Repository navigation
fix(pm): node is a fireable Restart-when: command head - #19712
Conversation
`classifyRestartWhen` decides fireability from the first word alone, and `node` was not on `RESTART_WHEN_COMMAND_HEADS`, so a runnable `node -e` predicate classified `prose` — the class H9 calls "a `manual` in disguise, waiting on an actor nothing schedules" — while the same predicate re-headed `pnpm exec node -e …` classified `command`. The head is the head every tool in this repo is invoked with, so the row reported a schedulable exit as unschedulable and its remedy sentence pointed at the wrong defect. Adds `node` to the measured head list with its corpus provenance, states in the docblock what the head-word test can and cannot tell, and records that the `pnpm exec` prefix is a workaround for this hole rather than a sanctioned spelling. Pins land in a new floored self-test battery carrying the card's four controls plus the closed-list and whole-word controls. Claude-Session: https://claude.ai/code/session_01Wnstp2kTth7sGXfr8fXypc Co-authored-by: Claude <noreply@anthropic.com>
…lf-states-h9-node-command-head
Contract reviewServed-tier: ① Derived judgmentsRendered in-seat by the skills seat 1 session at the served tier the maintainer named on this date (the fable tier word at
② Semver levelNone — no release. ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
Part of #19129
classifyRestartWheninscripts/pm/check-half-states.mjsdecides whether aRestart-when:value is fireable from its FIRST WORD alone, againstRESTART_WHEN_COMMAND_HEADS.nodewas not on that list, so a runnablenode -epredicate classifiedprose— the class the H9 row calls "amanualin disguise, waiting on an actor nothing schedules" — while the same predicate re-headedpnpm exec node -e …classifiedcommand.nodeis the head every tool in this repo is invoked with, so the row reported a schedulable exit as unschedulable and its remedy sentence pointed at the wrong defect.What changed
nodejoinsRESTART_WHEN_COMMAND_HEADS, with its corpus provenance in the docblock: the live objectui#9868 hold, whoseRestart-when:is an installed-surface probe a seat re-headed at 2026-09-18T22:00Z to clear a row this list should never have fired.node -e "process.exit(0)"fires on the spot and answers nothing. It records thepnpm execprefix as a workaround for this hole and ⛔ never as a sanctioned spelling.nodeis in because this repo's own tools are invoked with it and a live hold spells a predicate that way.bash,shandgradleare NOT added — nobody measured them on a hold — and all three are pinned asprosecontrols so the list cannot drift into a guess at command-shaped words.H9 node command head(10 cases registered, pin 9) carries the card's four controls plus the closed-list and whole-word controls.SELF_TEST_BATTERY_FLOORrises 8 to 9 and the five sibling pins that assert the roster size move with it, per this file's own floor discipline (a battery deleted from the roster must take its floor with it).Evidence
Red first, on the dispatch base
7e1b048a1d, the card's four controls in one command:Green, on this branch — the subject moves and the three controls are byte-identical:
Ablation, through
scripts/ablation-replace.mjsin wrap mode, run from the COMMITTED fix so the restore has a real restore point. Predicted direction: RED.The five reds are the two starred subject pins, the two heads-list pins and the gathering-policy pin. Every control in the battery stayed GREEN under the mutation — the
prosespecimens, the closed-list controls and thepnpm exectwin — which is what keeps the battery from being a widening nobody can fail. Restore was independently re-read afterwards: worktree blob equals the HEAD blob andgit status --porcelainis empty.No
dist/preflight applies: the subject is a standalone.mjsthatnoderuns directly, with no build step between the edit and the run.Gates, all on the merged head
d953fabbd:node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commandsderived 42 families on this tree; all 42 were run and all 42 exited 0.--ranreconciles: "42 derived famil(ies) accounted for — 42 run, 0 NOT-MEASURED (a DERIVED zero — all 42 recorded an exit code and none of them is 3)." The family set was re-derived after mergingorigin/mainand is identical to the pre-merge one.pnpm check:pm-half-statesexit 0 — 5170 cases pass (5160 at base; the 10 new ones are this battery), batteries line endsH9 node command head 10/9.pnpm check:nul-bytesexit 0, plus a manual control-byte scan of the edited file with zero hits.pnpm lint(the repo-wideeslint . --no-inline-config) exit 0 — the full scan, so no narrowing is being declared.check-published-list-mirrorsand its self-test,check-dts-references --self-test,check:pm-label-desc-cap,check:console-injection,check:i18n-stale-fill— all exit 0.pnpm check:published-readme-exportsexits 3, its own PREREQUISITE NOT MET code: this worktree has nodist/because this card builds nothing. Recorded as NOT MEASURED — ⛔ not a pass and ⛔ not a finding.Exit codes throughout were captured into a file and read back before any pipe.
Changeset:
skip-changeset, measured rather than assumed — the root manifest isprivate: true, and of the 75 package manifests in the workspace none carries afiles[]entry namingscripts.scripts/pm/**is a repo-root tool directory that ships in nothing.Line budget: +54 / -8, net +46 over one file, against the dispatch's suggested net +30. The overrun is the battery discipline the dispatch itself requires: the roster entry with its rationale, ten pinned cases, and the docblock stating why each candidate head is in or out.
Acceptance notes
h9OnHoldNoRestartWhenreceivescommentBodiesas an array of STRINGS, and the ids never reach it: the shared comment cache that H4, H9 and H17 all ride stores whatcommentsForreturns, which is bodies. Naming an id means changing the shape of that cache and the signature every one of roughly thirty pinned call sites uses — a ripple through three rows, not a sentence in one function. This PR's dispatch scopes the file surface to the command-head defect, and the card itself offers the split ("split it if the lane prefers"). Recommendation: file it as its own card against the same file. Dedupe words:H9 row channel,commentsFor bodies,Restart-when comment id,h9OnHoldNoRestartWhen signature.Generated by Claude Code
Generated by Claude Code