Repository navigation
feat(spec): declare the publish-drafts request body, so the change note is part of the published API contract - #28447
Conversation
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
…ed schema; name it in the route ledger Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
… publish-drafts request schema Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
…blish-drafts-request
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
…untime suite by file in the client guard Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
…blish-drafts-request
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
|
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V 维护者速读(席位终稿 · head
|
📓 Docs Drift CheckThis PR changes 2 package(s): 11 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 5 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 173 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 780154abd6e8027c2ff8c38d5c8a5e04374b3df8 && git checkout 780154abd6e8027c2ff8c38d5c8a5e04374b3df8
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 776c1d875b2d140b4c2419103a7ad8681c1d2610 671e9f572f0db69bf31a123344304d511f809737 && git checkout -B drift-repro 776c1d875b2d140b4c2419103a7ad8681c1d2610 && git merge --no-ff 671e9f572f0db69bf31a123344304d511f809737
node scripts/docs-audit/affected-docs.mjs --json 776c1d875b2d140b4c2419103a7ad8681c1d2610
|
|
triage#1 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz Contract-review-claim: |
|
triage#1 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz Contract reviewServed-tier: ① Derived judgments
② Rulings cited
③ Narrowing / widening
④ Behaviour / flags
Implemented-by: |
|
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V Landing stroke · 2026-10-31T17:55Z · head
|
🤖 Generated with Claude Code
https://claude.ai/code/session_017ihL2fi9zfJhUTubyJYb6V
Fixes #28406
Clause-②: yes (widening)
Metadata-protocol: added
维护者速读
POST /packages/:id/publish-drafts(Studio「发布整个应用」)的请求体第一次写进了@objectstack/spec的公开契约:PublishPackageDraftsRequestSchema声明message(修改说明)和backfill;路由台账这一行也写明了它。actor被忽略、不会被拒。回滚即还原本 PR。packages/spec/src/api/protocol.zod.ts(新 schema 与说明),packages/runtime/src/domains/packages-publish-drafts-request-conformance.test.ts(每个字段在服务端实测的行为),packages/runtime/src/route-ledger.ts(台账新增的requestSchema字段)。pnpm --filter @objectstack/runtime exec vitest run src/domains/packages-publish-drafts-request-conformance.test.ts,预期 8 个测试全过。What changes
@objectstack/spec/api:PublishPackageDraftsRequestSchemaand its typePublishPackageDraftsRequest, besidePublishPackageDraftsResponseSchema. Two members, measured at the door (packages/runtime/src/domains/packages.ts, publish-drafts branch), not assumed:message: optional string. The door forwards it only when it is a string.backfill: optional array of{ object, field }, both non-empty strings, entries strict. No default: absent or[]asks for nothing. The door forwards it as sent; the protocol's shape judgement (readPublishBackfillRequest) refuses a malformed entry400 VALIDATION_ERRORbefore anything is published. The "named once" and "field is new and has a literal default" rules are described, not encoded: a refinement would be dropped from the published JSON Schema, and the second is judged against server state.actoris deliberately not declared (the door records the authenticated caller), and@objectstack/client'spackages.publishDraftsstill sends its deprecatedopts.actor, so a strict object would describe that call as invalid.packages/runtime/src/route-ledger.ts): the dispatcher ledger had norequestSchemafield (onlyresponseSchema). The field is added, runtime-internal like the rest of the ledger, with the same rules asresponseSchema(a name, resolved against the spec exports, never filled without conformance coverage). Its JSDoc says what a filled row claims and what it does not. The publish-drafts row namesPublishPackageDraftsRequestSchema.packages/client/src/route-ledger-response-schema.test.ts): ledgeredrequestSchemanames resolve against the live spec exports, using the existing resolver, with an anti-vacuity pin.api-surface,export-origins,declaration-map,authorable-surface,json-schema.manifest,content/docs/references/**, strictness-ledger counts. The SDK client is hand-written, not generated, andpackages/client/src/index.tsis not touched.gen:openapiemits a fixed list of nine contract schemas and its output is gitignored, so nothing there moves.@objectstack/specminor.Tests
packages/spec/src/api/protocol.test.ts: the schema accepts{},{ message },{ backfill }and both; strips the SDK'sactor; refuses a non-stringmessageand each malformedbackfillshape with the zod issue code and path; declares exactly the two members.packages/runtime/src/domains/packages-publish-drafts-request-conformance.test.tsdrives the real handler:publishPackageDraftsexactly as the schema parses it; an absent body reads as{};actorgets 200 and never reaches the publish (the session user is recorded);aiModel,contextandpackageIdin the body are not read;backfillis refused400 VALIDATION_ERRORnaming the entry, through the realObjectStackProtocolImplementation(its engine is a proxy that throws if touched, which shows the judgement runs before any read);packages/spec/src/type-alias-convention.pin.test.ts: the isomorphism pin for the new schema (805 → 806).Acceptance notes
messageis dropped and the publish goes ahead with no note: 200, not 400. The conformance suite pins this as a measured divergence, so a door that starts enforcing the schema flips one pin. Changing the door is outside this card's file surface (packages/runtime/src/domains/packages.ts, which runtime: the package doors record whateveractorthe request body names — publish, save, discard, revert, rollback, reassign and duplicate write a caller-chosen name into metadata history #28414 is editing now). It is reported to the seat.main: the ADR-0045 app re-save after the publish still passes a bodyactortosaveMetaItem. runtime: the package doors record whateveractorthe request body names — publish, save, discard, revert, rollback, reassign and duplicate write a caller-chosen name into metadata history #28414 removes that read. The conformance suite pins it today, and the pin's message says what to flip when runtime: the package doors record whateveractorthe request body names — publish, save, discard, revert, rollback, reassign and duplicate write a caller-chosen name into metadata history #28414 lands.actorthe request body names — publish, save, discard, revert, rollback, reassign and duplicate write a caller-chosen name into metadata history #28414 had no open PR when this was opened, and its branch touches nopackages/specfile, the route ledger or generated artefacts.Verification
Local gates and tests (head sha in the os-dev-report comment on the card)
Filled in the os-dev-report comment on #28406:
dispatch-gates --commandsfamilies with exit codes,--ranreconciliation, and the reverse verification of the non-strict choice.