Class (b) candidate — violates an already-declared contract. ⛔ Awaiting first triage; this seat does not grade or route it.
What was measured
When a stack carries an app payload but no manifest.id / manifest.name, AppPlugin's constructor identity guard throws a bare Error — no ADR-0112 code, no status:
packages/runtime/src/app-plugin.ts:255-300 — the guard; APP_CATEGORY_KEYS includes 'objects', so a stack with an objects payload and no identity reaches the throw new Error(...) with no envelope fields.
packages/plugins/plugin-dev/src/dev-plugin.ts:572 — where dev boot catches it and degrades.
This is the one ADR-0112 divergence that PR #19602 measured and could not fix inside its own scope (that PR is comment-only, zero production behaviour change).
Provenance, and one thing this card deliberately does NOT cite
Measured by the isolated at-tier contract reviewer of PR #19602, head e895dda8b9747b052a54ea2a7fa1155599e45a43; the record is comment 5765220585 on card #15292, CHARGE 9.
⛔ #11896 is not prior art for this and is not cited as such. An earlier draft of PR #19602's body said no card was filed "since #11896 owns the door question and closed it". That was a non-sequitur and is corrected on that PR. #11896 owns exactly one question — whether os build --json computes the four structural advisories — decided B by the maintainer on 2026-08-25, and its ruling says nothing about the boot-time refusal's envelope shape. Its own reopening condition is about out-of-tree os build --json consumers. Nothing in it reaches this.
Why it is worth recording rather than absorbing
The surrounding posture work established that no door refuses this malformation: os validate advises and exits 0 without --strict, os build is silent on it, os package publish substitutes a filename-derived permanent id and proceeds, and dev boot tolerates and reports. The boot-time throw is therefore the one place the system says anything categorical about missing identity — and it says it in a shape no programmatic consumer can branch on.
Radius of this reading
Static, at head e895dda8b9 and origin/main. ⛔ The reviewer's checkout had no node_modules and no dist/, so no gate, test or runtime probe was executed for this item; the claim rests on source read plus the constructor's own control flow. ⛔ Whether ADR-0112 requires an envelope on this throw path specifically has not been adjudicated here — that is exactly the triage question.
Not in this card, on purpose
The sibling observation — that reportOptionalLoadFailure (dev-plugin.ts:585) is still the vehicle reporting it, while PR #19602's own docblock at :438-441 says ⛔ it is not the vehicle for a metadata-shape defect ("precisely the mis-attribution #7926 removed from this file") — belongs to the domain:cli seat's sibling PR already editing this plugin's operator-facing text, per Ruling C's State line. ⛔ Not a second card.
Dedupe terms
ADR-0112 · manifest.id · AppPlugin constructor guard · bare Error envelope · reportOptionalLoadFailure
⛔ Filed without a duplicate search, per the standing rule that the filer attaches terms and the triage seat runs the check.
Filed by domain:spec execution seat 2, session session_01UDXER3sdqfeVYpEWZs5mZx, 2026-09-21T18:2xZ.
Generated by Claude Code
Class (b) candidate — violates an already-declared contract. ⛔ Awaiting first triage; this seat does not grade or route it.
What was measured
When a stack carries an app payload but no
manifest.id/manifest.name,AppPlugin's constructor identity guard throws a bareError— no ADR-0112code, nostatus:packages/runtime/src/app-plugin.ts:255-300— the guard;APP_CATEGORY_KEYSincludes'objects', so a stack with anobjectspayload and no identity reaches thethrow new Error(...)with no envelope fields.packages/plugins/plugin-dev/src/dev-plugin.ts:572— where dev boot catches it and degrades.This is the one ADR-0112 divergence that PR #19602 measured and could not fix inside its own scope (that PR is comment-only, zero production behaviour change).
Provenance, and one thing this card deliberately does NOT cite
Measured by the isolated at-tier contract reviewer of PR #19602, head
e895dda8b9747b052a54ea2a7fa1155599e45a43; the record is comment5765220585on card #15292, CHARGE 9.⛔ #11896 is not prior art for this and is not cited as such. An earlier draft of PR #19602's body said no card was filed "since #11896 owns the door question and closed it". That was a non-sequitur and is corrected on that PR. #11896 owns exactly one question — whether
os build --jsoncomputes the four structural advisories — decided B by the maintainer on 2026-08-25, and its ruling says nothing about the boot-time refusal's envelope shape. Its own reopening condition is about out-of-treeos build --jsonconsumers. Nothing in it reaches this.Why it is worth recording rather than absorbing
The surrounding posture work established that no door refuses this malformation:
os validateadvises and exits 0 without--strict,os buildis silent on it,os package publishsubstitutes a filename-derived permanent id and proceeds, and dev boot tolerates and reports. The boot-time throw is therefore the one place the system says anything categorical about missing identity — and it says it in a shape no programmatic consumer can branch on.Radius of this reading
Static, at head
e895dda8b9andorigin/main. ⛔ The reviewer's checkout had nonode_modulesand nodist/, so no gate, test or runtime probe was executed for this item; the claim rests on source read plus the constructor's own control flow. ⛔ Whether ADR-0112 requires an envelope on this throw path specifically has not been adjudicated here — that is exactly the triage question.Not in this card, on purpose
The sibling observation — that
reportOptionalLoadFailure(dev-plugin.ts:585) is still the vehicle reporting it, while PR #19602's own docblock at:438-441says ⛔ it is not the vehicle for a metadata-shape defect ("precisely the mis-attribution #7926 removed from this file") — belongs to thedomain:cliseat's sibling PR already editing this plugin's operator-facing text, per Ruling C's State line. ⛔ Not a second card.Dedupe terms
ADR-0112·manifest.id·AppPluginconstructor guard · bareErrorenvelope ·reportOptionalLoadFailure⛔ Filed without a duplicate search, per the standing rule that the filer attaches terms and the triage seat runs the check.
Filed by
domain:specexecution seat 2, sessionsession_01UDXER3sdqfeVYpEWZs5mZx, 2026-09-21T18:2xZ.Generated by Claude Code