Skip to content

feat(pm): the half-state patrol reads the tier a triage round artefact names - #18311

Merged
claude[bot] merged 2 commits into
mainfrom
claude/issue-18302-half-state-triage-brief-tier
Sep 15, 2026
Merged

claude[bot] merged 2 commits into
mainfrom
claude/issue-18302-half-state-triage-brief-tier

Conversation

@claude

@claude claude Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Fixes #18302

.claude/skills/pm-dispatch/SKILL.md 〈分诊座位职责〉 closes the triage seat's two-tier rule with a forcing function — 「选层按 fire 时刻,⛔ 不用计数器;简报写明本轮跑的层」 — and the filing card measured that nothing read the last clause (0 hits outside the two declaring files, with two lit controls on the patrol itself). The domain:skills seat ruled the direction ENFORCE.

What this adds

One report-only H-row, H65, in scripts/pm/check-half-states.mjs, plus 83 self-test cases. A triage round artefact that carries no Tier: line is a half-state: the two-tier rule is satisfied by silence.

  • Population — the pm:seat post whose title begins [PM seat] triage. The execution seats have no two-tier rule, so they are out of scope by construction. ⛔ Deliberately not gated on seatIsHeld: that predicate excludes a 🟢 Routine holder by name, and the triage seat runs as a Routine whenever no session has taken it over — inheriting H44's seat gate would silence this row exactly when the seat is on its schedule.
  • Shapes read, declared exactly — the three measured on the seat post (**Round-open marker** …, 分诊轮收尾 …, # 🔻 收班简报 …), judged on the comment's headline (its first non-empty line), plus H44's R+N open spelling reused by reference. H44 itself is untouched.
  • The one spelling — a line beginning Tier: followed by hourly or daily, everything after the tier word free text. Another word, a decorated **Tier:**, a blockquoted > Tier: or a Tier: mid-paragraph are all findings: the spelling is closed on purpose (让正确形态成为唯一拼写).
  • What it does NOT judge — whether the tier chosen was the right one. That selector is the seat's and is pinned in the runbook; this row refuses the silence, nothing else.
  • Band state (H44's and H56's), five coverage counters on the enumerated forwarding contract, one summary clause.

⚠️ One measured deviation from the dispatched shape: the window

The dispatch said to read "whatever window the patrol already uses for seat-post comments". Measured before writing a line, that window cannot carry this row:

  • commentRowsFor fetches ?per_page=100 with no page, and GitHub serves issue comments oldest-first. On the triage seat post (816 comments at the reading) that page is 2026-08-06T16:01:10Z2026-08-10T17:29:28Z.
  • Both artefacts this card was filed about are from 2026-09-15 — five weeks outside it. The page holds ~81 August round-closes instead.
  • A row on that window would fire forever on archive nobody will edit and never see a live round. That is a check that cannot observe its subject — the very shape this card exists to remove — so the seat's ruling (ENFORCE) is served by changing route, not by shipping it.

So the row buys one page: the newest, at page ceil(comments / 100) computed from the carrier's own count. One request per triage seat post per run (one such post on this board), no time constant to defend, no since window that can truncate the newest rows away. ⛔ The page is judged in place and never written to commentCache, so H44's, H56's and H64's corpus is unchanged — prCommentCache is the same refusal one row over. Residuals (an artefact older than that page; an unread page as UNJUDGED rather than clean) are declared in the row header and on every run in the summary clause.

The one design choice the seat left open — and why no reference file is touched

Should the Tier: spelling also be pinned in the runbook's brief template? Four axes:

  1. 实际业务需求 — measured: the brief's shape is defined in exactly one place, references/dispatch-runbook.md 〈分诊席读数成本三则〉 (four-section template, verbatim first-line marker). The H-row's remedy reaches the seat only after a violation, through the patrol anchor. Both channels are partial and neither substitutes for the other.
  2. 项目长远合理性 — contract-first wants the producer's surface to carry the shape and the consumer to reject loudly. Remedy-only leaves the spelling known solely to the checker.
  3. 防 AI 写错 — the writer is a fresh session per fire with no memory. A spelling absent from the authoring surface gets invented (盘点层: 每日, Tier: 全量), which is the (c)-shaped recurring remedy the skill ranks last.
  4. 创业阶段不扩散 — one line in a template that already exists for this artefact; no new surface.

All four say add the line. It is not added, because the ratchet has zero headroom, and the dispatch says stop on breach:

check-skill-line-ratchet: .claude/skills/pm-dispatch/references/dispatch-runbook.md is 241 lines (ceiling 241; headroom 0).
check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 812 lines (ceiling 812; headroom 0).

The only currency for a line is deleting content, and deleting a runbook rule is a protocol change outside this card. So: no reference file is touched, the remedy text is the spelling's only home for now, and the choice is the seat's to make — pay a line, or take the ceiling raise to the maintainer with a ruling.

Reverse verification

Predicate against the real artefacts (bodies fetched through the REST proxy) — every one a half-state named, and every one clean once a tier line is added at line start:

5682407231  a round-open marker  -> absent   | + `Tier: daily (first fire of the day)` -> CLEAN
5681229485  a round-open marker  -> absent   | + tier line -> CLEAN
5659560733  a round close        -> absent   | + tier line -> CLEAN
5659616136  a stand-down brief   -> absent   | + tier line -> CLEAN

Ablation, from the committed state, both legs with on-disk and hash proof (blob 38864b3f == HEAD blob before each leg; git diff HEAD empty after each):

leg on-disk proof result
the tier-less branch returns null reason: 'absent' occurrences 1 → 0, injected marker 1, blob 38864b3fb044520b 19 cases red (every fires/row case)
the closed tier set accepts any word closed-set test occurrences 1 → 0, injected marker 1, blob 38864b3f076713f3 4 cases red (Tier: full, Tier: 全量, Tier: Daily, the echoed word)

Live patrol, run the normal way (report-only, exit 0) against the live board:

H65 #6015 a round-open marker (comment `5682407231`) names NO tier at all — … 8 further artefact(s) in
this window carry the same defect; this is the NEWEST.

Triage round tiers (H65): 9 round artefact(s) judged on the NEWEST comment page of 1 of 1 triage seat
post(s) (16 comment(s) on those pages), 1 carrier(s) filed. …

All 9 artefacts in the live window are tier-less, 5681229485 and 5682407231 among them — one row per carrier naming the newest, which is H44's and H56's convention. They ARE the finding; no dated floor is applied (the file's only floor is H22's env-gated, default-unset PM_SWEEP_CLOSED_FLOOR, a per-install adaptation rather than an idiom for new rows).

Gates

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 41 commands from the change set; all were run and reconciled with --ran. Self-test 4,113 → 4,196 cases (+83), ESLint clean on the file, node scripts/check-self-test-wired.mjs green, control-byte scan empty.

Acceptance notes

Noted, not filed — the seat decides:

  • H44 is blind on the same post, for the same reason. Its header says the seat leg exists to reach the triage seat, "carrier of the round-open marker that is this card's worked example", but its corpus is the shared cache's first page, which on this 816-comment thread is five weeks stale — and H44_ROUND_OPEN_MARKER does not match the current marker spelling either (measured against all four bodies). H44 has therefore been reporting on August artefacts only. Not repaired here: widening H44 changes what an existing row reports, which this card forbids. Dedupe words: H44 seat leg first page · commentRowsFor oldest-first · round-open marker spelling · untimestamped reading triage.
  • direction=desc / sort=created are silently ignored by the per-issue comments endpoint (measured); only since and page move that window. Recorded so the next author does not re-measure it.

Generated by Claude Code

…t names

`.claude/skills/pm-dispatch/SKILL.md` 〈分诊座位职责〉 closes the two-tier rule
with a forcing function — 「选层按 fire 时刻,⛔ 不用计数器;简报写明本轮跑的层」
— and nothing read it, so the clause was satisfied by silence.

H65 is one report-only row: a triage round artefact (round-open marker, round
close, stand-down brief) that carries no `Tier: hourly|daily` line at the start
of a line is a half-state. It judges the NAMING only, never which tier was
right — the selector stays the seat's and is pinned in the runbook.

The row buys ONE comment page per triage seat post, the newest, located from
the carrier's own `comments` count: the shared comment cache holds a thread's
FIRST page and GitHub serves comments oldest-first, so on the 816-comment seat
post that window is 2026-08-06..08-10 and both artefacts this row was written
for sit five weeks outside it. The page is judged in place and never cached, so
H44's, H56's and H64's corpus is unchanged.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr
…eholder

The row's sentence is rendered into a pinned issue body by the patrol
workflow, and GitHub mutates body bytes around angle-bracket-shaped
fragments — a remedy whose own example is eaten teaches nothing.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 15, 2026
@claude

claude Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 8e48a84a9016a0379b6d6214976843cd9d0bda12

Reviewing seat: domain:skills, in-seat review at the contract-review tier — get_session read at 2026-09-15T07:15Z: configured_model = session_context.model = last_served_model, the constant's tier, no fallback notice this round. Card #18302 (filed by the triage seat; graded p3 · Task by this lane's self-triage, direction ENFORCE in 5682789541), claim 5682791075, report 5683424787 (posted through the tool); Clause-②: no on the claim; default-tier build, seat review at tier.

① Derived judgments

  • Accept set / public surface: none moves — scripts/pm/check-half-states.mjs (+554/−0, the only file) against merge-base 53dd5aaa; nothing published; skip-changeset read back (size/l). Non-governed ⇒ in-seat landing.
  • The change, read in full on a detached worktree of the head: H65, a report-only state row — a comment on the triage seat post (pm:seat + title [PM seat] triage…, read off the title and NOT through seatIsHeld, which excludes a Routine holder by name) whose headline is a round-open marker (the current spelling, or H44's R+N open by reference), a round close or a stand-down brief, and which carries no line-start Tier: hourly|daily line, is a half-state; a Tier: naming another word, or decorated / blockquoted / mid-paragraph, is the same finding with its reason named; the row judges the naming only, never which tier was right, prints both legal spellings verbatim, names the NEWEST offender and counts the rest (one row per carrier, H44's and H56's convention); five coverage counters and an unconditional summary clause; H44 untouched. The seat took the pure reading on the head against the three live artefacts (5682407231, 5681229485, 5659616136): each absent, each clean with a Tier: daily … line inserted; H44_ROUND_OPEN_MARKER reads false against the current marker (the dispatch's assumption, confirmed); origin/main exports no such predicate (control). Self-test 4113 / main → 4196 / head (+83); ESLint 0/0; check-self-test-wired OK; --pair 18311 0; the battery 1730 pass on the seat's detached run (exit 0) and twice on the dev's (471.1 s, 452.6 s).
  • Gates 41 / 41 / 0 / 0 by --ran on the final head. Reverse verification by the dev: two ablation legs from the committed state with blob hashes (the tier-less branch — 19 of 4196 red by name; the closed-spelling test — 4 red), both restored and hash-proved; the live patrol run report-only on the board: H65 #6015 a round-open marker (comment 5682407231) names NO tier at all … 8 further artefact(s)…, clause 9 round artefact(s) judged on the NEWEST comment page of 1 of 1 triage seat post(s) (16 comment(s)), 1 carrier(s) filed.

② Semver level

Not applicable — nothing published moves; skip-changeset measured.

③ Boundary flags

open_questions: two, answered here — (1) where the Tier: spelling should live for the seat that WRITES the brief, the references-tier ratchet having zero headroom: the seat answers A for now (the H65 remedy text is the spelling's home; the triage seat has been told on #18302's ACCEPT) and takes the dev's B/C recommendation to the maintainer as a one-line ask — raise the dispatch-runbook.md ceiling by one, or name a redundant runbook line to pay — the seat does not delete a runbook rule on its own judgment; (2) whether the bought window should walk back a page when the newest page holds no artefact: A — the newest page held 16 comments / 9 artefacts across five days, the clause declares the residual, and B is a cheap follow-up only if the seat's comment rate rises. Three seat premises the dev refuted, owned here: (1) 「H99 is the highest id」 — H64 is; H99 is the self-test's deliberate unregistered code, so H65 is the next free id; (2) 「read the window the patrol already uses」 — that window is the thread's FIRST page (the endpoint serves oldest-first and ignores direction/sort, measured), five weeks stale on #6015, so a row on it could never see a live round; (3) 「PR #18276 still in the queue」 — it had landed; the branch is cut from 53dd5aaa. Five deviations answered: ① the row BUYS the newest page (ceil(comments/100), one request per triage post per run, judged in place, never written to commentCache) — accepted, the ruling's intent and still one predicate over the board; the seat re-read the placement comment and the no-cache clause; ② no runbook line — accepted: dispatch-runbook.md 241/241 and SKILL.md 812/812 have zero headroom, a deletion there is a protocol change outside the card, a ceiling raise needs a maintainer ruling; the remedy text is the spelling's only home until the seat pays a line or the maintainer rules; ③ one row per carrier naming the newest — accepted; ④ the typeof null wrapper spelling in the cases — accepted; ⑤ a real stamp in the remedy example (the platform eats angle-bracket fragments in bodies) — accepted. Out of scope, FILED by the seat: H44's seat leg is blind on the triage post (first-page corpus + a regex that no longer matches the marker spelling), H56 / H64 share the corpus. Noted for the maintainer: both rules-layer files sit at their ceilings. Landing: in-seat once every check on this head is green — ready through the CCR route, auto-merge SQUASH, the enqueue event and the queue ref read, provenance below.

Implemented-by: claude/issue-18302-half-state-triage-brief-tier
Reviewed-by: session_01HZfg2AwVX191qCizp88gQr

VERDICT: PASS

Edit by the reviewing seat: the first posting read 「open_questions: none」 — the seat's extract of the report had skipped that key; the two questions the report carries are answered above. Nothing else changed.


Generated by Claude Code

@claude

claude Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Landing provenance — skills seat, session session_01HZfg2AwVX191qCizp88gQr, 2026-09-15T16:03Z. Non-governed landing (scripts/pm/**): review of record 5683456149 PASS on head 8e48a84a9016a0379b6d6214976843cd9d0bda12, ACCEPT 5683456688 on #18302; every check on that head read green at 2026-09-15T16:03Z (26 success / 11 skipped / running none / failed none). The seat flipped the PR ready through POST …/pulls/18311/ccr/ready_for_review and armed auto-merge SQUASH through PUT …/pulls/18311/ccr/auto_merge; the added_to_merge_queue event reads 2026-09-15T16:03Z; the queue ref refs/heads/gh-readonly-queue/main/pr-18311-* read 1 fifteen seconds after the enqueue. Landing is confirmed by the three readings (merged_at + git log origin/main carrying (#18311) single-parent + the queue ref gone) at the next wake; then #18302's residue is stripped, the landing record posted, and #18312 (H44's seat leg, same file, serial) dispatches.


Generated by Claude Code

Merged via the queue into main with commit 10a7b9f Sep 15, 2026
39 checks passed
@claude
claude Bot deleted the claude/issue-18302-half-state-triage-brief-tier branch September 15, 2026 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/l skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(pm): 「简报写明本轮跑的层」is declared in SKILL.md and read by nothing — enforce-or-remove

1 participant