Skip to content

Store collections name project schemas; defaults and readOnlyProperties on the collection (#908) - #924

Merged
jimhoyd merged 2 commits into
mainfrom
claude/store-named-schemas
Sep 29, 2026
Merged

jimhoyd merged 2 commits into
mainfrom
claude/store-named-schemas

Conversation

@jimhoyd

@jimhoyd jimhoyd commented Sep 29, 2026

Copy link
Copy Markdown
Collaborator

Fixes #908. One named schema can now be the record shape of a store collection, the body of an HTTP route and the input of an MCP tool.

Design

  • Naming a schema: a collection's schema is either inline or the name of a top-level schemas: entry. A named schema must pass the same flat-record checks as an inline one, or activation refuses it with a pointed message. An unknown name and a bundled file with $defs each get their own message.
  • One place for store annotations (breaking): record schemas carry value shape only, whether inline or named.
    • Defaults move to defaults: {prop: value} on the collection, and read-only markers to readOnlyProperties: [prop]. (readOnly: true already means GET/HEAD only on a collection.)
    • default or readOnly on a property is refused, and the message names the collection key to use.
    • Why: the request-body profile refuses both keywords, so a shared schema can't carry them. This also removes the old strip-before-compile dialect.
    • Behavior is unchanged: defaults are validated, readOnly properties stay transition-only, required plus readOnly needs a default, and the key and increment rules are the same.
  • Core OpenAPI:
    • ExtensionDescribeRequest carries schemas.
    • Contributions may $ref a named schema or one of its root properties, and core writes that component once.
    • A name that collides with a project schema is refused.
  • Store OpenAPI: record, create and patch properties reference the named component. When the create body is exactly the named schema, Store<X>Create is a $ref to it, so POST, a route body and an MCP tool share one type.

Evidence (macOS, Node 26), rebased on main after #920 and #922

  • New packages/store/test/named-schema.test.ts:
    • One Ticket schema is shared by a collection, a POST route and an MCP tool. For 5 invalid inputs, the store's 422 issues deep-equal the route's at the same pointer, and the MCP error matches.
    • Defaults and readOnly work with a named schema.
    • The activation refusals.
    • OpenAPI writes Ticket once and the document is valid.
  • The store, OpenAPI and named-schema tests cover the new refusals and references.
  • Migrated: the scaffold, the store-crud recipe, both proofs, the bench and the store-schema artifact.
  • npm run verify passes: core 1219, store 144, proof 12, proof:authjs 13, ecosystem 12. npm run test:package passes.
  • Budgets: core 983 / 3864 KiB, store 104 / 394 KiB, with measured comments.

Limits

  • Filter query parameters still carry inline copies of property schemas.
  • The store's test suite now imports mcp source for the cross-package test.

🤖 Generated with Claude Code

…nd readOnlyProperties on the collection (#908)

A collection's `schema` may name a project named schema (top-level
`schemas:`), so one schema is a collection's record shape, a route's request
body and an MCP tool's arguments, refusing the same input at the same pointer.
A named schema must satisfy the flat-record restrictions or activation refuses
it, naming the collection, the schema and the pointer.

Breaking: a record schema (inline or named) is value shape only. `default` and
`readOnly` on a property are refused; the collection carries them as
`defaults: {prop: value}` and `readOnlyProperties: [prop]`, one model for both
forms. StoreRecords adds `defaults` and `readOnlyProperties`.

Core: ExtensionDescribeRequest carries the project's named schemas, and an
extension OpenAPI contribution may `$ref` a named schema or one of its root
properties; core writes the component once, as for a route body. The store's
description references the named component instead of copying it.

Migrates the store example, recipe, proofs, bench, tests and docs; re-measures
the core and store package budgets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jimhoyd
jimhoyd enabled auto-merge (squash) September 29, 2026 15:14
…dget

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jimhoyd
jimhoyd merged commit ef334c8 into main Sep 29, 2026
25 checks passed
@jimhoyd
jimhoyd deleted the claude/store-named-schemas branch September 29, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Let store collections reference named project schemas

1 participant