Bind published response contracts for the 17 unbound client-SDK methods; retire the false PackageRollbackResponseSchema (#12038, ruling 1C·2C·3A·4A·5A) - #12848
Conversation
…ntract binding (#12038 3A) The schema declared a VERSION rollback ({ success, restoredVersion?, message? }) while PackageApiContracts.rollbackPackage bound it to the live POST /api/v1/packages/:packageId/rollback path, which the dispatcher serves with rollbackToPackageCommit — the ADR-0067 COMMIT rollback, a different operation with a different result. Retired through the ADR-0087 discipline: RETIRED_DEFS_BY_MAJOR entry api/PackageRollbackResponse, D3 semantic entry package-rollback-response-retired, manifest key and authorable-surface baseline lines released with their registered proof (#4725 / #4650), runtime namespace-probe pins in package-api.test.ts. PackageRollbackRequestSchema stays published as ruled; the true commit-rollback contract follows in the next commit, after this retirement per the ruling's sequencing. Co-authored-by: Claude <noreply@anthropic.com>
…e contracts (#12038) The twelve describe-only transcriptions from the recorded ruling (1C/2C/3A/4A/5A), each transcribed from the return type its producer already declares inline: six meta.* payloads in api/protocol.zod.ts (listDrafts, getMetaDiagnostics, findReferencesToMeta, rollbackMetaItem, diffMetaItem, plus the ruling-1C opaque GetPublishedMetaItemResponseSchema), the package lifecycle family in the new api/package-lifecycle.zod.ts (discardDrafts, listCommits with the handler-minted commits wrapper, revertCommit, the true commit-rollback RollbackToPackageCommitResponseSchema, the ruling-4A fixed-keys-plus-catchall PackageExportManifestSchema, adoptOrphans, duplicate), and the resolved book tree as Zod beside its interfaces in system/book.zod.ts. Ruling 5A re-exports (PackagePublishResultSchema, ResolvedBookSchema family) land in the /api namespace the ledger resolver searches — never a second copy. meta.migrateStored stays unbound, documented (ruling 2C). Generated artifacts regenerated by the spec build. Co-authored-by: Claude <noreply@anthropic.com>
…s and bind the SDK
Fill responseSchema on the 18 boundable ledger rows across both ledgers,
each row stating which surface's envelope it describes (the dispatcher wraps
{ success, data }; the REST server answers the payload bare — the three
dual-mounted meta routes carry one note per surface). meta.migrateStored's
two rows document the ruling-2C deliberate unbinding instead. Conformance
suites land with the rows (spec api/protocol.test.ts, the new
api/package-lifecycle.test.ts, system/book.test.ts — the #3877
no-row-without-conformance rule, house capture pattern).
The client SDK binds 16 of the 17 methods to the published payload types
(migrateStored stays any, documented per 2C; getPublished binds to unknown
per 1C), replaces the four invented test mocks (getDiagnostics, getBookTree,
rollbackItem, diffItem) with producer-true shapes, flips the #11925 rollback
negative guard to guard the new commit-rollback truth, adds the
returnTypePrecisionPins12038 type-level pins, and pins the unwrapResponse
mis-unwrap hazard (survey §8.2) so no bound payload can ever declare both a
boolean success and a data key.
Co-authored-by: Claude <noreply@anthropic.com>
…changeset api-surface, export-origins, reference docs and the strictness ledger regenerated by check:generated --fix (only the artifacts it proved stale); the ResolvedBook type family re-exported on /api so the generated page's import line resolves. The changeset carries the breaking FROM-to-TO mapping and the ADR-0087 disposition (registered package-rollback-response-retired). Co-authored-by: Claude <noreply@anthropic.com>
… pins The file docblock opened at heading level 1 (the #12249 demotion pin counts exactly the 38 files that predate it) and split a code span across lines, leaving a same-directory source path as plain text for the #6484 rule. Open at level 2 and keep the span on one line; reference docs regenerated. Co-authored-by: Claude <noreply@anthropic.com>
…k-response-contracts
…nce total for the new contracts The 13 new response types gain their Parsed aliases (check:spec-parsed-alias; all are isomorphic — no defaults or transforms — but the paired-alias route keeps the family uniform with its package-api siblings), the API Protocol quick-reference heading's M rises to the 31 pages the reference tree now publishes, and the spec artifacts are regenerated for the new type exports. Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 4 package(s): 2 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 134 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 53f76d0eb3e7317a815aff29ba1798469e3d1ee1 && git checkout 53f76d0eb3e7317a815aff29ba1798469e3d1ee1
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 277948f7aea27a6f246bc73d95d8359086cca250 e539b0848961c7ec8173201c45eec84d7af5f36c && git checkout -B drift-repro 277948f7aea27a6f246bc73d95d8359086cca250 && git merge --no-ff e539b0848961c7ec8173201c45eec84d7af5f36c
node scripts/docs-audit/affected-docs.mjs --json 277948f7aea27a6f246bc73d95d8359086cca250
|
check:llms-txt (the last step of the source-gates job) went red on the new api/package-lifecycle.zod.ts: the hand-kept inventory declared 207 schemas total and 29 under api. Re-read per the gate's own rule — number AND prose: 208 / 30, with Package Lifecycle added to the api row's key-schema sampler. Gate re-derived green locally: 97 claims, 14 domains, 208 schemas. Co-authored-by: Claude <noreply@anthropic.com>
… closed check:exported-any-returns (Type Check - consumer gates) is exact in both directions: the #11925 entries for the newly bound meta.* and packages.* methods no longer resolve to any, so their ledger rows must be deleted. meta.migrateStored's entry stays - it remains any by the 2C ruling. Verified against the rebuilt dist: 'no NEW exported callable resolves to any: 317 callables reached, 47 ledgered site(s) still open'. Co-authored-by: Claude <noreply@anthropic.com>
…eclares it check:error-code-casing (Lint & Repo Gates) flagged the handwritten conformance capture's code: 'item_locked' — an invented lowercase spelling. The producer propagates deleteMetaItem's refusal code verbatim, and the protection path sets 'ITEM_LOCKED' (ledger-declared, error-code-ledger.zod.ts ADR-0010 §3.3), so the capture now carries the code the route really answers. Gate and the conformance suite re-run green. Co-authored-by: Claude <noreply@anthropic.com>
…k-response-contracts
…12849) os-regen-merge.sh step 4: gen:migration-registry rebuilds registry.ts with BOTH step-18 populations (#12849's ui-form-view-predicate-features-root-refused semantic entry beside this PR's retirement + semantic entries), the retirement's manifest and authorable-surface deletions are re-applied over main's side (the merge takes main's copy of os-regen artifacts by design; the #4725/#4650 proofs re-verify against the new base), and the full chain regenerates green: check:generated 14/14, check:llms-txt 208 schemas, the five touched spec suites, client typecheck and the resolver + unwrap pin suites all pass on the merged tree. Co-authored-by: Claude <noreply@anthropic.com>
Fixes #12038
Implements the recorded five-part maintainer ruling (2026-08-27, comment 5434804846: 1C · 2C · 3A · 4A · 5A, verbatim 「其他接受」) for the 17 client-SDK methods that had no published response contract, on the factual basis of the accepted survey (comment 5431841395, 12 sections).
What landed, in the ruling's order
PackageRollbackResponseSchema+ thePackageApiContracts.rollbackPackageentry that bound the wrong-operation (VERSION-rollback) schema to the live COMMIT-rollback path are retired through the ADR-0087 discipline —RETIRED_DEFS_BY_MAJOR[18]entryapi/PackageRollbackResponse, D3 semantic entrypackage-rollback-response-retired, manifest key and authorable-surface baseline lines released with their registered proof (the json-schema.manifest.json 的「deliberate removal」删行仍是纪律而非门禁 —— #4650 的同类洞,上移一层(整 schema 级) #4725 / authorable-surface 的 tombstone 门禁可被手编基线绕过 —— 删掉基线行就删掉了证据(#4638 / #4643 已两次这样过绿) #4650 gates verified this on every build), runtime namespace-probe pins inpackage-api.test.ts.PackageRollbackRequestSchemastays published as ruled (it now binds to no route — recorded in the file comment).@objectstack/spec/api, each from the return type its producer already declares inline — no wire byte changes anywhere (the only handler-owned shape,listCommits'{ commits }wrapper, is declared as the handler's, not moved).GetPublishedMetaItemResponseSchemais deliberately opaque (z.unknown()) — no discriminated union over the type registry.meta.migrateStoredstays UNBOUND, documented at both of its ledger rows and in the SDK annotation (plus a pinnedtoBeAny()so a future sweep cannot "fix" it against the ruling).PackageExportManifestSchema= four fixed keys (id,name,version,label?) + open catch-all; freezes nothing.PackagePublishResultSchema(from/system) and theResolvedBookfamily (authored beside its interfaces insystem/book.zod.ts, type-identity-pinned) are re-exported into the/apinamespace the ledger resolver searches — never a second copy.unwrapResponse< …any… >#11925 rollback negative guard flipped to guard the new truth; the survey-§8.2unwrapResponsemis-unwrap hazard pinned (no bound payload may declare booleansuccessbesidedata; the export manifest's open half is covered via the plural vocabulary).resolveBookTree()producer).Per-method table
@objectstack/spec/api)meta.getPublishedGetPublishedMetaItemResponseSchema(opaque, 1C)dataof the dispatcher envelope on runtime, the whole bare body on RESTmeta.listDraftsListDraftsResponseSchemameta.migrateStoredmeta.getDiagnosticsGetMetaDiagnosticsResponseSchemameta.getReferencesFindReferencesToMetaResponseSchemameta.getBookTreeResolvedBookSchema(declared insystem/book.zod.ts, 5A re-export)meta.getAuditAuditMetaItemResponseSchema(existing, #11678 — bucket c)meta.rollbackItemRollbackMetaItemResponseSchemameta.diffItemDiffMetaItemResponseSchemapackages.publishPackagePublishResultSchema(from/system, 5A re-export)datapackages.discardDraftsDiscardPackageDraftsResponseSchemapackages.listCommitsListPackageCommitsResponseSchema(wrapper declared as the handler's)packages.revertCommitRevertPackageCommitResponseSchemapackages.rollbackRollbackToPackageCommitResponseSchema(3A — after the retirement)packages.exportPackageExportManifestSchema(4A)packages.adoptOrphansReassignOrphanedMetadataResponseSchemapackages.duplicateDuplicatePackageResponseSchema(payloadsuccessis the operation's verdict — the objectui#6593 confusion now has a declared answer)Row counts: 20 rows total for the 17 methods (three meta routes are dual-mounted); 18 rows name a schema,
migrateStored's 2 rows document the ruled unbinding.Verification record
All commands ran through
scripts/pm/os-verify-lock.sh; verdicts quoted from each gate's own output. Final head at verification:a4c926c(post-merge of origin/main at f907fbe).2f1bf89; only type-alias/doc-count edits and regenerated artifacts followed): specTest Files 436 passed+ the initially-failingscripts/file-description.test.tsre-run green after the header fix (its two corpus pins were tripped by the new file's docblock shape, not by behaviour); runtimeTest Files 197 passed (197); restTest Files 153 passed (153); clientTest Files 26 passed (26). Typechecks: spec / runtime / rest / client all green (check:test-typecheck: OK … 0 error(s)for client; spec's own test layer compiles with its pre-existing shrink-only debt ledger untouched).a4c926c:check:generated→✓ All 14 generated artifacts are up to date.; the five touched spec test files →Test Files 5 passed (5); client typecheck → OK; the resolver + unwrap pin suites →Test Files 2 passed (2).node scripts/pm/dispatch-gates.mjs(no paths passed — change set derived from the merge base, 36 paths): 28 families derived; all run green. Two reds surfaced and were fixed in-PR:check:quick-reference-counts(the API reference tree grew to 31 pages) andcheck:spec-parsed-alias(13 new types now carry their ADR-0122Parsedaliases).check:type-check-debtran with the wholepackages/*closure built, as its remedy requires.check:nul-bytesrun additionally (any-edit rule).check-adr-0087-registration→1 declared-breaking changeset(s), each carrying an ADR-0087 disposition … registered package-rollback-response-retired;check-changeset-no-major→ no major introduced (launch-window convention: the breaking removal ships asminorwith the FROM → TO mapping in the changeset body);check-empty-changeset→ green.restoredFromVersionkey ofRollbackMetaItemResponseSchemainprotocol.zod.ts(injection grep count 1, original line count 0), ran the schema's conformance block →Tests 2 failed | 147 skipped, exit 1 — the predicted red. Restore proven bygit hash-objectequality with the HEAD blob (6ed7351…) and an emptygit diff HEAD. A first attempt at this leg was VOID and is declared as such: the restore trap fired at that shell's exit before the test ran, so its green measured an unmutated tree; the leg was redone in one shell.route-ledger-response-schema.test.ts) exercises every filled row against the live@objectstack/spec/apinamespace — green on the final head.Landing note (for the PM)
This PR is serialized LAST in the landing relay behind PR #12718 and PR #12737 — both touch
packages/spec/src/migrations/registry.ts, which this PR's 3A retirement also regenerates. origin/main was merged before opening (f907fbe; neither sibling had landed). Expect a regen-merge sync (scripts/pm/os-regen-merge.sh) at enqueue time; not attempting ready/enqueue from this seat.Out of scope, recorded:
PackageRollbackRequestSchema(the version-rollback REQUEST half) stays published per the ruling's exact scope; it binds to no route since the contracts entry left. objectui#6593 remains open in objectui and is not addressed here.Generated by Claude Code