Blocked-by: objectstack-ai/objectstack#9343
Filed by the domain:ui execution seat (PM session session_013hfmP9hoMd3dJwTh85J4yB) as the carrier for the half #5026 deliberately excluded, before #5026 closes rather than after.
Why this card exists as a card, and not as a sentence in a closing thread
#5026's dev raised this and I am adopting its reasoning verbatim, because it is the sharpest statement of the failure mode this seat has hit repeatedly:
This card is about to close on merge, and the exclusion's release condition currently lives only in a comment on it — the same shape that made this card's own expired hold invisible for 13 days. A blocked card in the backlog is cheap; a release condition that closes with its card is how work disappears.
⭐ #5026 was itself held from 2026-08-18 on a spec-pin condition whose stated reason had expired. Nobody noticed, because a hold whose reason has expired reads exactly like a live hold. Filing this now means the release condition is on the unlock scan's reverse index instead of in a thread on a closed issue.
The gap
The single-item publish door is now wired (#5026 / PR #6961): MetadataClient.publish and publishDraft report advisories through the same sink, event and renderer the save door uses.
"Publish whole app" is not, and cannot be from this side:
- The route is
POST /packages/:id/publish-drafts. - It still discards per-draft advisories server-side — objectstack#9343, open and
needs-user-decision. - It is reached by a bare
fetch in usePublishAllDrafts and by apiJson in PackagesPage. ⛔ Neither goes through MetadataClient, so the data-layer seam that covers every other write path does not cover this one.
⇒ Two independent things must change before an author publishing a whole app sees a finding: the server must stop discarding them, and the client must route that call through a seam that can report.
⛔ Do not "fix" the client half early
The absence is currently pinned: a test asserts that a batch-shaped body carrying findings under published[] reaching publishDraft renders nothing. That pin exists so a later well-meaning traversal cannot be added quietly — and it will go red if someone tries.
⛔ Do not traverse a batch response from the client to synthesise advisories the server did not send. That would be the client inventing a contract, and it would mask objectstack#9343 rather than surface it.
Release condition
objectstack#9343 lands with a ruling that the batch route reports per-draft advisories. Then this card is: route the batch call through MetadataClient (or an equivalent reporting seam), extend the door discriminator if the ruling makes the batch door a third one, and flip the absence pin into a presence pin in the same commit.
⚠️ The claiming seat re-verifies all of it against main first. This card's facts are 2026-08-31 readings and #6961 may not even be merged when you read this.
Related
Blocked-by: objectstack-ai/objectstack#9343
Filed by the
domain:uiexecution seat (PM sessionsession_013hfmP9hoMd3dJwTh85J4yB) as the carrier for the half #5026 deliberately excluded, before #5026 closes rather than after.Why this card exists as a card, and not as a sentence in a closing thread
#5026's dev raised this and I am adopting its reasoning verbatim, because it is the sharpest statement of the failure mode this seat has hit repeatedly:
⭐ #5026 was itself held from 2026-08-18 on a spec-pin condition whose stated reason had expired. Nobody noticed, because a hold whose reason has expired reads exactly like a live hold. Filing this now means the release condition is on the unlock scan's reverse index instead of in a thread on a closed issue.
The gap
The single-item publish door is now wired (#5026 / PR #6961):
MetadataClient.publishandpublishDraftreport advisories through the same sink, event and renderer the save door uses."Publish whole app" is not, and cannot be from this side:
POST /packages/:id/publish-drafts.needs-user-decision.fetchinusePublishAllDraftsand byapiJsoninPackagesPage. ⛔ Neither goes throughMetadataClient, so the data-layer seam that covers every other write path does not cover this one.⇒ Two independent things must change before an author publishing a whole app sees a finding: the server must stop discarding them, and the client must route that call through a seam that can report.
⛔ Do not "fix" the client half early
The absence is currently pinned: a test asserts that a batch-shaped body carrying findings under
published[]reachingpublishDraftrenders nothing. That pin exists so a later well-meaning traversal cannot be added quietly — and it will go red if someone tries.⛔ Do not traverse a batch response from the client to synthesise advisories the server did not send. That would be the client inventing a contract, and it would mask objectstack#9343 rather than surface it.
Release condition
objectstack#9343 lands with a ruling that the batch route reports per-draft advisories. Then this card is: route the batch call through
MetadataClient(or an equivalent reporting seam), extend thedoordiscriminator if the ruling makes the batch door a third one, and flip the absence pin into a presence pin in the same commit.mainfirst. This card's facts are 2026-08-31 readings and #6961 may not even be merged when you read this.Related
advisories— the key #4133 scoped out now exists onPublishMetaItemResponse#5026 — the single-item door, and where this exclusion was recordedneeds-user-decisionMetadataClient.publishandpublishDraftdisagree about the dispatcher envelope on the same publish route #6962 — filed alongside:publishandpublishDraftdisagree about the dispatcher{ success, data }envelope on the same route. Independent of this card, but it touches the same two methods