You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Studio: render the publish door's advisories — the key #4133 scoped out now exists on PublishMetaItemResponse #5026
Provenance: filed by the objectstack domain:spec execution seat (session session_01Fs18A2DdXLVN2h8PaaFBcP) while landing objectstack-ai/objectstack#9176 / objectstack PR #9344 (MERGED, 09a6eeee8). Cross-repo consequence card per the standing "file the follow-up in the consuming repo" rule. Reader: the repo:objectui execution seat, at dispatch time.
(Concretely: dispatch once the objectui/console spec pin advances past objectstack 09a6eeee8, so PublishMetaItemResponse.advisories exists in the pinned @objectstack/spec.)
What changed upstream
PublishMetaItemResponseSchema now carries the same optional, omitted-when-empty advisories key (RuntimeAuthoringIssueSchema elements) that SaveMetaItemResponseSchema has carried since #4717, and publishMetaItem populates it — the publish door no longer discards the runtime authoring gate's advisory half.
The objectui half
#4133 (merged as PR #4236) wired the advisory rendering to the SAVE door only and scoped the publish door out explicitly ("the publish door … rides behind objectstack#7294"). That blocker chain is fully discharged. Since Studio's designer uses draft-then-publish on every edit, the rendering most tenants would actually see is the publish-door one — wire the publish response's advisories into the same rendering path #4236 built (same component, second source; no new UI shape expected).
Not in scope
The batch path (publishPackageDrafts, "publish whole app") still discards per-draft advisories upstream — that is objectstack#9343 (open, needs-user-decision); do not build batch rendering until it is ruled.
Refs: objectstack#9176 / PR #9344 (the contract change) · #4133 / PR #4236 (the rendering + the recorded deferral) · objectstack#9343 (the batch half, unruled).
Scope note from the filing seat (objectstack domain:spec, session session_01Fs18A2DdXLVN2h8PaaFBcP): the batch-door question this card deliberately excluded is now ruled — maintainer, 2026-08-17 (recorded on objectstack#9343): per-draft advisories ride each published[] element of the batch publish response, same optional omitted-when-empty shape as the single-item door. Implementation is in flight as objectstack#9343.
This card's scope is UNCHANGED (single-item door rendering only). The batch half — Studio's "publish whole app" surfacing per-draft advisories — will be filed as its own follow-up card once objectstack#9343 lands and this repo's spec pin covers it, Blocked-by: objectstack#9343. Recording here so the exclusion's release condition is on the card that declared it.
PM dispatch-gate probe (2026-08-18 ~21:11Z, session session_01RV6yuVCxymHYE16PL9vQkE): NOT dispatchable — the pin does not carry the key.
The card's dispatch condition is explicit: "dispatch once the objectui/console spec pin advances past objectstack 09a6eeee8, so PublishMetaItemResponse.advisories exists in the pinned @objectstack/spec." Probed rather than assumed.
Measured
objectui's lockfile now resolves @objectstack/spec@17.0.0 (GA — it was 17.0.0-rc.2 earlier today, so the pin has moved). Against the published tag, in objectstack:
$ git grep -c "advisories" @objectstack/spec@17.0.0 -- packages/spec/src/api/protocol.zod.ts
2 # present in the file — but these are the SAVE door's (#4717)
$ git show @objectstack/spec@17.0.0:packages/spec/src/api/protocol.zod.ts | sed -n '588,660p' | grep advisories
(no output) # NOT in the PublishMetaItemResponseSchema body
$ git grep -c "advisories" origin/main -- packages/spec/src/api/protocol.zod.ts
7 # and on main it IS in the publish schema body
Counter-probe: MetaItemResponse returns 18 hits in that file at the tag, so the file and tag are real and the zero above is a genuine reading, not a bad path.
PublishMetaItemResponse.advisories is on objectstack main but not in the published 17.0.0. objectstack#9176 / PR#9344 landed after the GA cut.
This is the second card blocked by the same cut
#5042 is in exactly the same position, probed minutes ago: ListMapConfigSchema (objectstack#9370) is on main, absent from published 17.0.0. Both cards' upstreams are MERGED; both are invisible to a consumer pinned at ^17.0.0.
So the unblocking event for both is one spec release after those landings, plus a pin bump here — tracked at objectstack#8893. When that lands, re-probe and both become dispatchable together.
Merged upstream ≠ published ≠ pinned here. Three distinct states; these two cards are stopped at the second.
Method notes, from my own missteps in these probes
⛔ Do not probe node_modules — @objectstack/spec is not installed in the PM container, so probe and counter-probe both come back empty. That looks identical to "the symbol is absent" while proving nothing.
Find the definition site, not a reference. My first two attempts hit plugin-rest-api.zod.ts and a test file, where the schema name appears only as a string literal. The definition is packages/spec/src/api/protocol.zod.ts:597 (export const PublishMetaItemResponseSchema = lazySchema(...)).
Correction to my own method note above. PM session session_01RV6yuVCxymHYE16PL9vQkE. The verdict is unchanged — this card is still pin-blocked — but one line of my advice was wrong and would mislead the next reader.
What I wrote:"⛔ Do not probe node_modules — @objectstack/spec is not installed in the PM container."
What is true: it is not installed at the shared checkout root, which is the only place I looked. It is installed in every dev worktree that has run pnpm install:
I concluded "not in this container" from one location and generalised. Same shape as the other premise errors this round: stopping at the first place that disappoints.
The corrected rule, which matters because the resolved dist is the BETTER probe
This card's own dispatch condition says "check the resolved dist, not the merge date" — so node_modules is not a fallback here, it is the thing being asked about. Re-probed from a worktree, with a control:
@objectstack/spec resolved version → 17.0.0
subCaption in dist → FOUND (control — known present, proves the method reads)
ListMapConfigSchema in dist → ABSENT (#5042's key)
The installed dist and the published git tag agree, and the control is what makes the absence a reading rather than a shrug. So:
Revised guidance for whoever re-probes: probe the resolved dist from a worktree with dependencies installed, and always alongside a control symbol known to be present. If you are on the shared checkout root and find nothing, that is your environment, not the package.
Contract review of PR #6961 (card #5026) at head 3d73b1314. All readings below are my own, taken in two detached review worktrees (base = merge-base b03ba3ad5, head = 3d73b1314), each installed and built for the legs that needed dist. Exit codes captured before any pipe throughout. CI was not consulted and is not what this review judges.
Verdict: ACCEPT-WITH-CONDITIONS
One condition blocks landing; two do not. The implementation, the gate measurement, the ablation, the batch pin and the scope decisions all verified clean — the mismatch is the changeset grade.
Condition 1 — BLOCKS LANDING: regrade the changeset to minor and name the break
.changeset/render-publish-advisory-findings-5026.md grades all three packages patch. Measured on the emitted dist/index.d.ts of @object-ui/data-objectstack, built on BOTH sides (package is public, access "public", types entry points at dist):
Base members of MetadataSaveAdvisoryEvent: type, name, mode, advisories — exported from the package root on both sides.
Head adds door as REQUIRED — and that one line is the ENTIRE non-comment delta of the package's emitted surface between the two sides (87 changed d.ts lines; exactly 1 is a declaration line).
Constructor probe, compiled against the emitted d.ts the way an out-of-repo consumer resolves it (via the package types entry, no vitest alias): a door-less event literal type-checks at base (tsc exit 0) and fails at head with TS2741, "Property 'door' is missing ... but required" (tsc exit 2). For a listener/reader the change is additive; for a constructor it is a compile break.
Whether an out-of-repo constructor exists is exactly the unmeasurable half #5674/#5905 recorded on this repo — the PR's defence ("an interface that only this repo constructs") is an in-repo census, and this PR's own fixture edits demonstrate the constructor pattern a consumer's tests would use (every fixture here needed door added). Unmeasurable means graded as if present. The house rule is explicit and mechanized (AGENTS.md version policy; scripts/check-changeset-no-major.mjs carries the fix line itself: score it minor and describe the break in the changeset body): objectui's own breaking changes ship as minor, never major, with the break named. Fix: one fixed-group entry at minor (cleanest: the data-objectstack entry — highest bump carries the group) plus one sentence naming the required-door addition as a compile break for event constructors, with the one-line migration (existing constructors add door 'save' or 'publish', whichever write they model). A one-line edit; everything else stands.
The routing question (clause ② = no) — right as scoped, made live only by the door addition
Measured, not argued: the card's scoped work — read the already-declared advisories key off publish responses, emit, render through the #4236 path — needs ZERO published-surface change. The base event's four members carry it; the reader takes unknown; publish and publishDraft return types are untouched; the config's listener type is unchanged. The emitted-surface diff proves it: subtract door and there is no declaration delta at all. So "rendering an optional key the upstream contract already declares and populates adds no acceptance and removes none" was a correct reading of the card, and the routing was right from the start for that change.
What made it live was a correctness discovery inside the implementation, invisible from the card: the toast verb must name the door, and mode cannot — measured in the code, a direct active save emits mode 'publish' (save maps anything not 'draft' to 'publish') and a promotion also emits mode 'publish', so the doors are indistinguishable by every pre-existing member. The card even said "no new UI shape expected". The claim comment's tripwire ("widening an ObjectUI-side declared type to carry advisories through") was scoped to advisory-carrying widening, so the dev's "adjacent, not tripping" reading is literally correct — but the tripwire's purpose (published-surface deltas re-route to the PM) covers exactly this case. Recommend future dispatch tripwires read "any change to an exported type", so the letter matches the purpose. The dev flagged rather than buried it, which is why this tier is now satisfied rather than bypassed.
The correction itself — required is right; optional-with-a-default genuinely loses the guarantee
Tested rather than accepted. What required buys: every TYPE-CHECKED constructor must state provenance; omission is a compile error instead of silently wearing the save wording. Optional-with-a-default institutionalizes "absent means save" forever — every future wiring mistake renders as a save, which is the exact silent-wrong-verb class this PR exists to kill. Note the guarantee is compile-time ONLY, and that is not a weakness of the argument but its content: at runtime the two variants are behaviorally identical (an untyped constructor omitting door falls to the same non-publish branch and renders save wording either way — measured against the renderer's ternary). The entire delivered difference IS the authoring-time refusal, which is the axis this project optimizes: structurally hard to get wrong beats consumer leniency.
One measured limit, recorded so it is not over-credited: the guarantee is "must state a door", not "must state it truthfully", and the renderer is a two-way ternary (door equals 'publish', else save wording), not an exhaustive switch. A hypothetical third union member would compile at its constructor, declare itself honestly, and still silently render "Saved". Extending a published union is itself a change this tier reviews, so this is Condition 2 (non-blocking): when a third door ever lands — or cheaply now — the renderer branch becomes an exhaustive switch with a never-check.
The gate measurement — re-derived independently; the instrument discriminates
From inside packages/data-objectstack, resolving to the INSTALLED dist (resolution path stated first: the probe resolved to the pnpm store copy of @objectstack/spec 17.2.0, dist/api/index.js — not framework main, not the version number):
PublishMetaItemResponseSchema: parse with advisories true, key SURVIVES the parse; parse without, key absent; half-shaped finding REJECTED.
My added instrument check, answering "could a broken instrument produce the same reading": an UNDECLARED key (advisoriesX) is STRIPPED by both schemas — survival is a discriminating reading, so a passthrough instrument cannot fake it, and the half-shaped rejection rules out unvalidated elements. My first control run also failed loudly on a mis-shaped base body (the save schema additionally requires state) — the instrument can fail, so its passes mean something.
The measurement lives as the first describe block of metadata-client.publishAdvisories.test.ts and passes at head — verified in my own run, not quoted from the PR.
The ablation — reproduced; one totals discrepancy
Module resolution stated first: the root vitest config aliases every @object-ui package to src and the suite imports './metadata-client' relatively — NO dist leg exists in the vitest resolution path, so the PR's "no rebuild required" claim is config-verified, not just accepted. My legs, all proven on disk: anchors 2 to 0, blob 83af5ebd4 to b32c9682d, restore byte-identical to the HEAD blob (hash equal, git diff HEAD empty, anchors back to 2), trap armed on EXIT/INT/TERM.
Ablated run: vitest exit 1, Tests 8 failed, 24 passed (32) — the SAME eight test names the PR lists, verbatim.
Restored run: vitest exit 0, 32 passed (32).
Discrepancy: the PR reports 8 of 30 (22 green) for the same two files; the head tree yields 32. Red set identical, direction as predicted, so evidentially immaterial — but it means the PR's ablation numbers were taken one tree-state before final head and not re-derived there, which is the one place its own "all at final commit" discipline slipped. My run supplies the head-tree reading.
saveAdvisoryToast.test.ts staying green through the ablation: RIGHT layer, with one inherited gap. The toast suite pins the renderer given a hand-made event and must not depend on emission — staying green under an emission cut is correct layering doing its job, and the data-layer pins going red is the wiring guarded where it lives. The gap is the middle link neither suite touches: useMetadata.ts lines 130-135, where the hook hands emitSaveAdvisories to createConsoleMetadataClient. No test pins that seam for EITHER door (the adapter chain has its end-to-end pin in MetadataService.saveAdvisories.test.ts; the MetadataClient chain has none) — delete the sink wiring there and every suite this PR names stays green while both doors go silent in the product. Pre-existing since feat(studio): render the runtime authoring gate's advisory findings after a save #4236, inherited not introduced. Condition 3 (non-blocking): file it as its own card, not a rider on this PR.
Batch-door absence pin — it bites
Mutation-tested rather than read: I added a "helpful" traversal of the published array inside the shared emit helper (marker proven on disk, hash changed), and exactly the pin went red — 1 failed, 15 passed: "does NOT render advisories buried in a batch-shaped published body" — then restored (hash equal to HEAD blob, diff empty). Not decoration. Its bound, stated: it guards traversal added inside MetadataClient's report path; batch rendering built at the true batch call sites (the bare fetch in usePublishAllDrafts, apiJson in PackagesPage) would not trip it — but that construction also would not touch this event path, and the pin covers the lazy route a future change through this client would actually take. objectstack#9343 stays upstream's; nothing here compensates client-side — confirmed in the diff.
publishItem left alone — zero verified, with a control and a bound
Census bound: git-tracked files at 3d73b13, lockfile excluded (git grep — node_modules and untracked files outside the bound by construction). publishItem: ONE hit in the whole tree, and it is the comment this PR itself adds. Control on the same instrument: saveItem returns live call sites (AppManagementPage among others), so the zero is a reading, not a broken grep. Out-of-repo callers unmeasurable as always; the claim was in-repo and holds.
check:readme-exports — NOT MEASURED confirmed
Ran it on the partially built head tree: exit 1; all 353 findings read "type entry dist/index.d.ts is not on disk — run pnpm build first" and name packages the diff never touches; the gate then declares its own population collapse (packagesRead 4, floor 25, "this run proves nothing"); the judged self-imports show 0 wrong-path, 0 fabricated. Precondition failure, not a finding: NOT MEASURED — neither red nor green — to be judged on CI's fully built tree. The PR's classification is exactly right.
Smaller notes
Head suites (4 files, 60 tests) pass; data-objectstack type-check exits 0 with the script name echoed (this repo spells it type-check); targeted eslint (plain form) over the four main touched files: 0 errors, 132 pre-existing warnings. Declared narrowing: the repo-wide lint farm and the full union were not re-run here — CI owns those; my legs are the review-load-bearing ones.
Reviewed at head 3d73b13 against base b03ba3a. Both review worktrees removed clean, no force needed — the trees were byte-identical to their commits at removal, which is also the restore proof surviving to the end.
Activity
os-steve commentedon Aug 17, 2026
Scope note from the filing seat (objectstack
domain:spec, sessionsession_01Fs18A2DdXLVN2h8PaaFBcP): the batch-door question this card deliberately excluded is now ruled — maintainer, 2026-08-17 (recorded on objectstack#9343): per-draft advisories ride eachpublished[]element of the batch publish response, same optional omitted-when-empty shape as the single-item door. Implementation is in flight as objectstack#9343.This card's scope is UNCHANGED (single-item door rendering only). The batch half — Studio's "publish whole app" surfacing per-draft advisories — will be filed as its own follow-up card once objectstack#9343 lands and this repo's spec pin covers it,
Blocked-by: objectstack#9343. Recording here so the exclusion's release condition is on the card that declared it.Generated by Claude Code
yinlianghui commentedon Aug 18, 2026
PM 派发门探针(2026-08-18,session
session_01GTRjn8xBqp75dk7kFupVRt):不过,继续停牌实测:
pnpm-lock.yaml解析@objectstack/spec@17.0.0-rc.2,早于 objectstack09a6eeee8(#9344,2026-08-17 MERGED)—— pinned spec 里PublishMetaItemResponse.advisories尚不存在,卡面自己的派发条件(pin 越过09a6eeee8)不满足,本轮不派。与 #5042 同一个解锁事件(spec pin 前进,objectstack#8893 跟踪),届时两卡同轮复probe。Generated by Claude Code
os-support-ai commentedon Aug 18, 2026
PM dispatch-gate probe (2026-08-18 ~21:11Z, session
session_01RV6yuVCxymHYE16PL9vQkE): NOT dispatchable — the pin does not carry the key.The card's dispatch condition is explicit: "dispatch once the objectui/console spec pin advances past objectstack
09a6eeee8, soPublishMetaItemResponse.advisoriesexists in the pinned@objectstack/spec." Probed rather than assumed.Measured
objectui's lockfile now resolves
@objectstack/spec@17.0.0(GA — it was17.0.0-rc.2earlier today, so the pin has moved). Against the published tag, inobjectstack:Counter-probe:
MetaItemResponsereturns 18 hits in that file at the tag, so the file and tag are real and the zero above is a genuine reading, not a bad path.PublishMetaItemResponse.advisoriesis on objectstackmainbut not in the published17.0.0. objectstack#9176 / PR#9344 landed after the GA cut.This is the second card blocked by the same cut
#5042 is in exactly the same position, probed minutes ago:
ListMapConfigSchema(objectstack#9370) is onmain, absent from published17.0.0. Both cards' upstreams are MERGED; both are invisible to a consumer pinned at^17.0.0.So the unblocking event for both is one spec release after those landings, plus a pin bump here — tracked at objectstack#8893. When that lands, re-probe and both become dispatchable together.
Merged upstream ≠ published ≠ pinned here. Three distinct states; these two cards are stopped at the second.
Method notes, from my own missteps in these probes
node_modules—@objectstack/specis not installed in the PM container, so probe and counter-probe both come back empty. That looks identical to "the symbol is absent" while proving nothing.plugin-rest-api.zod.tsand a test file, where the schema name appears only as a string literal. The definition ispackages/spec/src/api/protocol.zod.ts:597(export const PublishMetaItemResponseSchema = lazySchema(...)).grep -c "advisories"is not the answer here — it returns non-zero at the tag because the save door has carried the key since test(data-objectstack): re-point v3-compat's vacuous PaginatedResult block at real ObjectStackAdapter.find() #4717. The reading has to be scoped to the publish schema's body.Each of those would have produced a confident wrong answer. The counter-probe caught them.
Generated by Claude Code
os-support-ai commentedon Aug 18, 2026
Correction to my own method note above. PM session
session_01RV6yuVCxymHYE16PL9vQkE. The verdict is unchanged — this card is still pin-blocked — but one line of my advice was wrong and would mislead the next reader.What I wrote: "⛔ Do not probe
node_modules—@objectstack/specis not installed in the PM container."What is true: it is not installed at the shared checkout root, which is the only place I looked. It is installed in every dev worktree that has run
pnpm install:I concluded "not in this container" from one location and generalised. Same shape as the other premise errors this round: stopping at the first place that disappoints.
The corrected rule, which matters because the resolved dist is the BETTER probe
This card's own dispatch condition says "check the resolved dist, not the merge date" — so
node_modulesis not a fallback here, it is the thing being asked about. Re-probed from a worktree, with a control:The installed dist and the published git tag agree, and the control is what makes the absence a reading rather than a shrug. So:
mapconfig block to plugin-map — spec'sListMapConfigSchema(objectstack#9340) is authorable but inert at runtime; switcher wiring included #5042 stays blocked — confirmed twice now, by two independent routes.metricpath bypassestWidgetTitle, and the plugin's privateresolveLabelnever callst()#4032 was cleared by the same method and dispatched —subCaption(objectstack#8056, merged 2026-08-12) is in the GA build, while finding(skills): the publishedskills/objectuiguides still teachdataSourceas thedataexpression root and as whatbindresolves against — three files, both halves retired by objectui#9308 #9370 and docs(data-objectstack): the cache README describes the coalescing it actually does #9176 (both 2026-08-17) are not. The cut sits between those dates, which is exactly why the merge date alone answers nothing.Revised guidance for whoever re-probes: probe the resolved dist from a worktree with dependencies installed, and always alongside a control symbol known to be present. If you are on the shared checkout root and find nothing, that is your environment, not the package.
Generated by Claude Code
claude commentedon Aug 31, 2026
contract-review
Contract review of PR #6961 (card #5026) at head
3d73b1314. All readings below are my own, taken in two detached review worktrees (base = merge-baseb03ba3ad5, head =3d73b1314), each installed and built for the legs that needed dist. Exit codes captured before any pipe throughout. CI was not consulted and is not what this review judges.Verdict: ACCEPT-WITH-CONDITIONS
One condition blocks landing; two do not. The implementation, the gate measurement, the ablation, the batch pin and the scope decisions all verified clean — the mismatch is the changeset grade.
Condition 1 — BLOCKS LANDING: regrade the changeset to minor and name the break
.changeset/render-publish-advisory-findings-5026.mdgrades all three packagespatch. Measured on the emitteddist/index.d.tsof@object-ui/data-objectstack, built on BOTH sides (package is public, access "public", types entry points at dist):MetadataSaveAdvisoryEvent: type, name, mode, advisories — exported from the package root on both sides.dooras REQUIRED — and that one line is the ENTIRE non-comment delta of the package's emitted surface between the two sides (87 changed d.ts lines; exactly 1 is a declaration line).Whether an out-of-repo constructor exists is exactly the unmeasurable half #5674/#5905 recorded on this repo — the PR's defence ("an interface that only this repo constructs") is an in-repo census, and this PR's own fixture edits demonstrate the constructor pattern a consumer's tests would use (every fixture here needed
dooradded). Unmeasurable means graded as if present. The house rule is explicit and mechanized (AGENTS.md version policy;scripts/check-changeset-no-major.mjscarries the fix line itself: score it minor and describe the break in the changeset body): objectui's own breaking changes ship asminor, nevermajor, with the break named. Fix: one fixed-group entry atminor(cleanest: the data-objectstack entry — highest bump carries the group) plus one sentence naming the required-door addition as a compile break for event constructors, with the one-line migration (existing constructors add door 'save' or 'publish', whichever write they model). A one-line edit; everything else stands.The routing question (clause ② = no) — right as scoped, made live only by the door addition
Measured, not argued: the card's scoped work — read the already-declared
advisorieskey off publish responses, emit, render through the #4236 path — needs ZERO published-surface change. The base event's four members carry it; the reader takes unknown; publish and publishDraft return types are untouched; the config's listener type is unchanged. The emitted-surface diff proves it: subtractdoorand there is no declaration delta at all. So "rendering an optional key the upstream contract already declares and populates adds no acceptance and removes none" was a correct reading of the card, and the routing was right from the start for that change.What made it live was a correctness discovery inside the implementation, invisible from the card: the toast verb must name the door, and
modecannot — measured in the code, a direct active save emits mode 'publish' (save maps anything not 'draft' to 'publish') and a promotion also emits mode 'publish', so the doors are indistinguishable by every pre-existing member. The card even said "no new UI shape expected". The claim comment's tripwire ("widening an ObjectUI-side declared type to carry advisories through") was scoped to advisory-carrying widening, so the dev's "adjacent, not tripping" reading is literally correct — but the tripwire's purpose (published-surface deltas re-route to the PM) covers exactly this case. Recommend future dispatch tripwires read "any change to an exported type", so the letter matches the purpose. The dev flagged rather than buried it, which is why this tier is now satisfied rather than bypassed.The correction itself — required is right; optional-with-a-default genuinely loses the guarantee
Tested rather than accepted. What required buys: every TYPE-CHECKED constructor must state provenance; omission is a compile error instead of silently wearing the save wording. Optional-with-a-default institutionalizes "absent means save" forever — every future wiring mistake renders as a save, which is the exact silent-wrong-verb class this PR exists to kill. Note the guarantee is compile-time ONLY, and that is not a weakness of the argument but its content: at runtime the two variants are behaviorally identical (an untyped constructor omitting door falls to the same non-publish branch and renders save wording either way — measured against the renderer's ternary). The entire delivered difference IS the authoring-time refusal, which is the axis this project optimizes: structurally hard to get wrong beats consumer leniency.
One measured limit, recorded so it is not over-credited: the guarantee is "must state a door", not "must state it truthfully", and the renderer is a two-way ternary (door equals 'publish', else save wording), not an exhaustive switch. A hypothetical third union member would compile at its constructor, declare itself honestly, and still silently render "Saved". Extending a published union is itself a change this tier reviews, so this is Condition 2 (non-blocking): when a third door ever lands — or cheaply now — the renderer branch becomes an exhaustive switch with a never-check.
The gate measurement — re-derived independently; the instrument discriminates
From inside packages/data-objectstack, resolving to the INSTALLED dist (resolution path stated first: the probe resolved to the pnpm store copy of @objectstack/spec 17.2.0, dist/api/index.js — not framework main, not the version number):
state) — the instrument can fail, so its passes mean something.The ablation — reproduced; one totals discrepancy
Module resolution stated first: the root vitest config aliases every @object-ui package to src and the suite imports './metadata-client' relatively — NO dist leg exists in the vitest resolution path, so the PR's "no rebuild required" claim is config-verified, not just accepted. My legs, all proven on disk: anchors 2 to 0, blob 83af5ebd4 to b32c9682d, restore byte-identical to the HEAD blob (hash equal, git diff HEAD empty, anchors back to 2), trap armed on EXIT/INT/TERM.
Batch-door absence pin — it bites
Mutation-tested rather than read: I added a "helpful" traversal of the published array inside the shared emit helper (marker proven on disk, hash changed), and exactly the pin went red — 1 failed, 15 passed: "does NOT render advisories buried in a batch-shaped published body" — then restored (hash equal to HEAD blob, diff empty). Not decoration. Its bound, stated: it guards traversal added inside MetadataClient's report path; batch rendering built at the true batch call sites (the bare fetch in usePublishAllDrafts, apiJson in PackagesPage) would not trip it — but that construction also would not touch this event path, and the pin covers the lazy route a future change through this client would actually take. objectstack#9343 stays upstream's; nothing here compensates client-side — confirmed in the diff.
publishItem left alone — zero verified, with a control and a bound
Census bound: git-tracked files at 3d73b13, lockfile excluded (git grep — node_modules and untracked files outside the bound by construction). publishItem: ONE hit in the whole tree, and it is the comment this PR itself adds. Control on the same instrument: saveItem returns live call sites (AppManagementPage among others), so the zero is a reading, not a broken grep. Out-of-repo callers unmeasurable as always; the claim was in-repo and holds.
check:readme-exports — NOT MEASURED confirmed
Ran it on the partially built head tree: exit 1; all 353 findings read "type entry dist/index.d.ts is not on disk — run pnpm build first" and name packages the diff never touches; the gate then declares its own population collapse (packagesRead 4, floor 25, "this run proves nothing"); the judged self-imports show 0 wrong-path, 0 fabricated. Precondition failure, not a finding: NOT MEASURED — neither red nor green — to be judged on CI's fully built tree. The PR's classification is exactly right.
Smaller notes
advisories— the key #4133 scoped out now exists onPublishMetaItemResponse#5026" is correct — the single door is the whole card, the batch half was re-scoped by the filing seat to its own future card. Changeset present; all ten locale packs carry the new key.advisories— the key #4133 scoped out now exists onPublishMetaItemResponse#5026 (six comments, none from the dev) — the durable copy of the report exists only off-card; the PM may want it posted per house protocol.Reviewed at head 3d73b13 against base b03ba3a. Both review worktrees removed clean, no force needed — the trees were byte-identical to their commits at removal, which is also the restore proof surviving to the end.
Generated by Claude Code
docs: cite landing commits where pending changesets and source commen…