Observation-class finding from the domain:spec PM seat (session session_01Euoy6wyfzgiWtgCg4s6JK2), measured during PR #8399's patch round. Filed unassigned for triage. Dedup: #8409 covers cancelled-run artifacts, different mechanism; no open card names this derivation gap.
Measured
PR #8399's dev ran the full scripts/pm/dispatch-gates.mjs re-derivation against its actual diff (which included .changeset/engine-update-upsert-retired.md, a declared-breaking changeset). The derivation returned check-changeset-no-major.mjs for the .changeset/ path but left the pr-automation.yml family — including the Check Changeset step that enforces the adr-0087: disposition marker — in the 25-family "repo-wide/undetermined" bucket. Result: the dev's local gate loop was all green, and the missing marker surfaced only as a CI red (Check Changeset, run 31693913128), costing one patch round.
The dev's initial hypothesis (two gates disagreeing about valid markers) was checked and refuted: check:adr-0087-registration was simply never run locally — no conflict exists.
Suggested fix (mechanical)
Per the script's own design ("derived, never listed"), the fix is not to hardcode: the Check Changeset step's script source presumably names .changeset/ path literals — check why the watch-hint scan does not surface it (script inlined in workflow YAML rather than living in scripts/? the scanner only reads check:* package.json scripts?). If the enforcement lives inline in pr-automation.yml, either extract it to a script the scanner can see, or teach the scanner to scan workflow run: blocks for path literals. Either way, a breaking changeset should derive the family that will actually judge it.
Refs: PR #8399 (the measured miss), scripts/pm/dispatch-gates.mjs header (#7341 item 4, the no-lists design rationale), #6148 (the marker requirement's origin).
Observation-class finding from the
domain:specPM seat (sessionsession_01Euoy6wyfzgiWtgCg4s6JK2), measured during PR #8399's patch round. Filed unassigned for triage. Dedup: #8409 covers cancelled-run artifacts, different mechanism; no open card names this derivation gap.Measured
PR #8399's dev ran the full
scripts/pm/dispatch-gates.mjsre-derivation against its actual diff (which included.changeset/engine-update-upsert-retired.md, a declared-breaking changeset). The derivation returnedcheck-changeset-no-major.mjsfor the.changeset/path but left the pr-automation.yml family — including theCheck Changesetstep that enforces theadr-0087:disposition marker — in the 25-family "repo-wide/undetermined" bucket. Result: the dev's local gate loop was all green, and the missing marker surfaced only as a CI red (Check Changeset, run 31693913128), costing one patch round.The dev's initial hypothesis (two gates disagreeing about valid markers) was checked and refuted:
check:adr-0087-registrationwas simply never run locally — no conflict exists.Suggested fix (mechanical)
Per the script's own design ("derived, never listed"), the fix is not to hardcode: the
Check Changesetstep's script source presumably names.changeset/path literals — check why the watch-hint scan does not surface it (script inlined in workflow YAML rather than living inscripts/? the scanner only readscheck:*package.json scripts?). If the enforcement lives inline in pr-automation.yml, either extract it to a script the scanner can see, or teach the scanner to scan workflowrun:blocks for path literals. Either way, a breaking changeset should derive the family that will actually judge it.Refs: PR #8399 (the measured miss),
scripts/pm/dispatch-gates.mjsheader (#7341 item 4, the no-lists design rationale), #6148 (the marker requirement's origin).