Skip to content

[finding] H9's fireability test is a spelling test, so three unfireable Restart-when: shapes pass it green — and #7898 shows H17's trigger index carrying 0 of 11 #17377

Description

@os-project-manager

Filed by the domain:cli execution PM seat (#6024) from a full state audit of the lane's 10 open pm:on-hold cards, run at the maintainer's instruction. ⛔ Recording only — not graded here, no severity asserted, no remedy chosen.

⚠️ This card corrects an earlier claim of mine. In four audit comments posted minutes before this one (#7898, #3739, #13559, #12271) I wrote that Restart-when: has no unlock sweep at all, the way Blocked-by: does. That is false, and each of those four now carries a correction pointing here. The real shape is below; it is a narrower and sharper defect than the one I misdescribed, and the remedy it implies is different.

What the machinery actually is

Read off origin/main⚠️ read, not executed: scripts/pm/check-half-states.mjs needs a live gh and this seat's container has none, so every behaviour below is from source.

mechanism what it does working?
the unlock sweep fires Restart-when: closed <owner/repo>#N, same scan as Blocked-by:, over both channels since #10403 ✅ yes
H9 (:2047) flags pm:on-hold carrying no fireable Restart-when: line in EITHER channel ✅ the check exists
H17 (:3085) inventories, per open hold, the repo-relative trigger files its body/comments name — via prose anchors (H17_TRIGGER_ANCHOR_TERMS, :3171) plus the canonical Restart-touch: channel ✅ the index exists

⇒ ⛔ Nothing here is missing. The defect is in what H9 accepts and in whether H17's output is consumed.

Finding 1 — H9 tests the SPELLING of fireability, not fireability

The whole test (:2109):

export function hasFireableRestartWhen(text) {
  return directiveValues(text, 'Restart-when').some((v) => !/^manual\b/i.test(v));
}

any value that does not begin with manual passes. Three shapes clear H9 and can never fire anything. Two were found live in this lane today; the third is already documented in H9's own header:

shape live specimen why it cannot fire
a file trigger written under Restart-when: #7898 — "any PR touches packages/core/src/security/auth-gate.ts, packages/runtime/src/http-dispatcher.ts or adds an adapter under packages/adapters/**" file triggers are Restart-touch:'s key; the unlock sweep fires only closed #N
prose waiting on a seat to act #3739 — "the triage seat performs the contract-first split (parent + per-repo sub-issues)" not a condition on any event; nothing schedules the actor
an unreachable closed …#N Restart-when: closed objectstack-ai/objectstack#5499 — a tracking anchor that stays open by design H9 judges presence, never reachability — its header says so verbatim

⭐ The third row is the tell: H9's own documentation already names this class ("H9 judges the line's PRESENCE, never its target's REACHABILITY … ⇒ The class, not the instance"), and deliberately declines to act on it — "Teaching H9 to REFUSE an unreachable closed …#N target … is a behaviour change nobody has ruled on — deliberately NOT made here." ⇒ The gap is known and unruled, not unnoticed. What this audit adds is that the same gap admits two further shapes the header does not enumerate, both live in one lane on one day.

Finding 2 — #7898 is in H17's index, and the rider was carried 0 of 11

⭐ The sharper half, because H17 exists specifically to cure it.

H17 anchors a line if lower.includes(term) for any of ['trigger file', 'opportunistic', 'restart condition'] (:3171, :3284). #7898's Restart-when: line reads, in full:

Restart-when: any PR touches packages/core/src/security/auth-gate.ts, packages/runtime/src/http-dispatcher.ts or adds an adapter under packages/adapters/** (a second transport adapter is restart condition 1 by definition)

⇒ the substring restart condition is present, so the line anchors, and its two tracked paths extract. #7898 has been a row in the trigger-file index.

Measured on origin/main, git log --since=2026-08-12 over those two paths: 11 commits, the newest being cf791820b9fix(core): the auth-gate allow-list matches at a mount boundary (#17284), which edits auth-gate.ts itself. ⛔ The rider was carried zero times; the card sat in pm:on-hold until this audit moved it to needs-user-decision.

⚠️ That is #10034's finding recurring after its fix shipped. H17's own header records the original:

across six cards the named trigger files were touched NINETEEN times and the rider was carried ZERO times. The mechanism is real and maintainer-accepted (2026-08-11), but it existed only as a remembered protocol step … and a written step nobody executes is worse than none, because holds are PRICED assuming it runs.

0-for-19 was the disease; this is 0-for-11 on a single card, with the cure in the tree. ⛔ I cannot tell from here whether the patrol renders the index, whether it renders this row, or whether seats read it — H17 runs on an Actions runner and this container cannot execute the script. That is the open question this card exists to hand over, not a claim that H17 is broken.

Finding 3 — where H9 does work, its rows went unactioned

#13559 and #12271 carried pm:on-hold with no Restart-when: in either channel — the exact H9 predicate. ⇒ Live H9 rows, unactioned until today's audit (both now fixed: #13559's body gained the line transcribed from its own ruling; #12271 went back to pm:queue). ⛔ Whether they ever appeared in a rendered patrol output is the same open question as Finding 2.

Possible directions — ⛔ not prescriptive, no ruling implied

⛔ What this card is NOT

Refs

#7898 (Finding 2's specimen; now needs-user-decision) · #3739 (Finding 1, prose shape; now pm:queue) · #13559 · #12271 (Finding 3) · #10034 (H17's origin, the 0-for-19 measurement) · #10403 (H9's two-channel widening) · #10102 (the H4/H9 asymmetry it retired) · #17365 (the sibling class, Blocked-by:)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions