Uh oh!
There was an error while loading. Please reload this page.
feat(metadata-protocol): batch publish door returns per-draft advisories on each published[] element - #9405
Conversation
…ies on each published[] element
publishPackageDrafts (Studio's "publish whole app") destructured only
{ singularType, result } from promoteDraftForPublish, which since #9176
RETURNS the #4463 gate's advisory findings — so they were computed and
discarded, per draft, for every draft in the batch.
Per the maintainer's ruling on #9343: advisories ride EACH published[]
element, same optional omitted-when-empty shape as
PublishMetaItemResponseSchema.advisories on the single-item door; no
parallel top-level map; failed[] elements unaffected (an error finding
still aborts the batch, ADR-0067 D2).
The objectql doubles of the promoteDraftForPublish seam gain the
advisories key the real helper has returned since #9176.
Part of #9343
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fs18A2DdXLVN2h8PaaFBcP📓 Docs Drift CheckThis PR changes 1 package(s): 4 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 seeCoarse fallback — 5 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop):
|
Uh oh!
There was an error while loading. Please reload this page.
Fixes#9343
Ruling (recorded on the card 2026-08-17 22:35Z, batch acceptance 「同意」)
What landed
packages/metadata-protocol/src/protocol.ts—publishPackageDraftsnow destructures theadvisoriesthe Phase-1 seam (promoteDraftForPublish) has returned since The publish door discards the runtime authoring gate's advisory findings — and Studio's designer only ever uses that door #9176, captures them per draft onPromotedDraft, and attaches them to the matchingpublished[]element in Phase 2, omitted-when-empty (neveradvisories: []). The declared return type'spublished[]element gains the optionaladvisorieskey (RuntimeAuthoringIssue[], the The publish door discards the runtime authoring gate's advisory findings — and Studio's designer only ever uses that door #9176 element shape).failed[]untouched. The two stale "the batch caller deliberately does not read it" notes are updated.packages/metadata-protocol/src/protocol-publish-drafts-advisories.test.ts— four cases through the REALpublishPackageDrafts(nothing on the gate path stubbed; the [P2/P3] 运行时授权门的 advisory findings 要进响应并被 Studio 渲染 + docs「the gate」补第四列(#4463 收尾) #4717/The publish door discards the runtime authoring gate's advisory findings — and Studio's designer only ever uses that door #9176flow-multi-write-unfilteredwarning fixture): (1) a one-draft batch reports the finding on its element with rule id, severity and the full element key set; (2) a mixed batch attaches the key to exactly the raising element — the clean sibling's raw key set is pinned as[name, type, version]; (3) an advisory-free batch is byte-identical (JSON.stringifycarries no trace of the key); (4) the gating half is unchanged — anerrorfinding aborts the batch (INVALID_METADATAcausal +BATCH_ABORTEDsiblings) and noadvisorieskey appears anywhere onfailed[].packages/objectql/src/{protocol-publish-package-drafts,build-probes,protocol-commit-history}.test.ts— the four doubles of thepromoteDraftForPublishseam gainadvisories: [], the key the real helper has returned since The publish door discards the runtime authoring gate's advisory findings — and Studio's designer only ever uses that door #9176 (drifted seam doubles, surfaced by the new read).@objectstack/metadata-protocolminor (additive optional key).Deviations from the dispatch card (measured, not chosen)
packages/specchange. The card namedprotocol.zod.tsas gaining the key, but measured againstorigin/mainthe batch publish response has no declared Zod schema anywhere in spec — the batch response face lives solely aspublishPackageDrafts' TS return type (grep publishedCount packages/spec/src= zero hits). The ruled shape is fully implementable on that face, so it landed there; declaring the whole batch response schema in spec is a separate [finding]POST /meta/:type/:name/publishis a served REST route with NO spec declaration — the #5745 "declared = returned" discipline covers only the save door #7294-class card, filed as follow-up finding The batch publish response (POST /packages/:id/publish-drafts) has no declared spec schema — the #5745 "declared = returned" discipline covers only the single-item publish door #9406. Consequently no generated spec artifacts move (check:generated: all 13 up to date at292239ca6), no reference docs exist for this response to sync, and the [#5563 附带裁决] SaveMetaItemResponseSchema 补齐实现实际返回的字段(version / seq / state / projectionApplied) #5745 "declared = returned" conformance gate cannot cover this door until that declaration exists.feat(metadata-protocol), not the card'sfeat(spec), for the same reason.pnpm --filter @objectstack/spec testwas not run: spec is byte-identical toorigin/mainin this branch, so the run would measure main, not this change.Verification (all at
292239ca6)@objectstack/metadata-protocolfull suite: 121 files / 1655 tests green (new file 4/4). DTS build green (measured DEBT-ledger package, no typecheck script);check:type-check-debt --re-measure: 33 entries re-measured, none above recorded (surplus: none).@objectstack/objectql(downstream consumer of@objectstack/metadata-protocol) full suite: 215 files / 3811 tests green;tsc --noEmitgreen.node scripts/pm/dispatch-gates.mjsover the changed paths), all green locally: cross-package-test-inputs, durability-log-level, filter-alias-parity, changeset-gate-self-tests, objectui-changeset, query-options-erasure, engine-double-contract, where-matcher, nul-bytes, type-check-coverage, type-check-debt (re-measure), adr-0087-registration, changeset-no-major, empty-changeset, docs-audit affected-docs, spec check:generated.Reverse verification (from the committed state)
Predicted before the run: the two directional cases go red, the byte-stability and gating-half pins stay green (green-either-way by design). Restored
origin/main'sprotocol.tsinto the tree (git restore --source=origin/main), re-ran the new file: 2 failed / 2 passed — exactly the predicted split (both reds are the element-leveladvisoriesread returning undefined, i.e. the discard this card is about). Restored from HEAD, re-ran: 4/4 green.Conditional-field byte-stability proof
Case (3) pins the raw element key set (
Object.keys(el).sort()=['name','type','version']) and assertsJSON.stringify(res)contains noadvisoriessubstring — the route hands this object tores.json()verbatim, so this is the wire. An advisory-free batch's response bytes are unchanged.Generated by Claude Code