Skip to content

tooling(pm): read pm:retriage as a question for triage, in H18 and the label description - #15795

Merged
os-steve merged 2 commits into
mainfrom
claude/issue-15744-retriage-is-a-question-h18-and-label
Sep 5, 2026
Merged

tooling(pm): read pm:retriage as a question for triage, in H18 and the label description#15795
os-steve merged 2 commits into
mainfrom
claude/issue-15744-retriage-is-a-question-h18-and-label

Conversation

@os-steve

@os-steve os-steve commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

Fixes #15744

pm:retriage is a question put to the triage seat — a re-grade, a lane for a cross-domain PR, a re-route, a split, a disposition fork a dev report left open — stated by the objection comment, answered every fire, and removed in the same write. That is the wording now on main in .claude/skills/pm-dispatch/SKILL.md (the label row, and the triage-duty line 「pm:retriage 每 fire 先答异议评论所求,答后同笔摘标;须维护者答的进收件箱,标照摘」) and in references/state-machine.md.

Two files still read the label as a re-grade request. This PR aligns them. Prose plus one description string — no predicate, no threshold, no logic.

What changed

scripts/pm/check-half-states.mjs — H18, four prose sites

Site Was Is
Threshold JSDoc cites 「pm:retriage 重判每 fire 高优先处理」, a SKILL.md line that no longer exists; "re-judges every card"; "survived at least one re-judgement pass" cites the landed triage-duty line verbatim; "ANSWERS the question on every card each fire"; "survived at least one answer pass"
Finding sentence "the objecting seat's grade is still undecided … resolve the grade (keep or change) and drop the label in the same write" "the question the objecting seat put to triage is still unanswered … answer what the comment asks and drop the label in the same write (an answer that needs the maintainer goes to the inbox with the label still removed)"
Header inventory "the triage Routine — which re-judges every pm:retriage card each fire, high priority" ; "every triage re-judgement (grade kept or changed) bumps updated_at" "which answers every pm:retriage card's question each fire" ; "every triage answer (whatever it decides) bumps updated_at"
PM_RESIDUE_LABELS docblock "pm:retriage a request for re-judgement" "pm:retriage a question put to the triage seat"

scripts/pm/ensure-pm-labels.sh — the label object

The description, and the comment block above it that named "the triage round's high-priority re-judgement pass" as a consumer.

What deliberately did NOT change

  • h18RetriageAged's predicate, RETRIAGE_STALE_HOURS, the updated_at proxy, the coexisting-label sentence and the row's report-only exit semantics — byte-for-byte. Same population, same threshold, same rows.
  • The ALONE-shape note, "the disputed grading is unidentifiable (异议对象不明)". It describes a card carrying pm:retriage with no coexisting standing pm:* label — a shape the state model does not define — and that is still true and still unidentifiable.
  • The two other mentions were read and left alone, because neither asserts the re-grade meaning: PM_RESIDUE_LABELS's census note (the label was measured absent from a live population) and PM_EXCLUSIVE_STATE_LABELS's "annotations ON a state".

The label description is capped at 100 characters

gh label create returns HTTP 422 above 100 characters and the script's || true swallows it, so an over-cap description means the label is silently never created on a repo that lacks it (pnpm check:pm-label-desc-cap exists for exactly this).

The card's candidate string, "Question for triage, answered each fire; coexists with the standing pm:* label; queued cards skip dispatch", measures 106 code points — over the cap. Landed instead, carrying the same three facts in the file's own house idiom (pm:blocked "do not dispatch", pm:on-hold "no dispatch, no nag"):

Question for triage, answered each fire; coexists with the standing pm:* label; no dispatch

91 code points, 91 bytes (a code-point count and LC_ALL=C wc -c agree; the string is ASCII). Nine characters of headroom. The dropped words are the population qualifier "queued cards" — the fact survives as "no dispatch", which is how the three sibling rows spell it.

Live labels are NOT re-seeded by this PR

ensure-pm-labels.sh needs gh, which is absent from this container, and three of its five repos are outside this session's scope — the script was not run and no live label was touched. The live pm:retriage description on all five repos still reads "Awaiting triage re-judgement — …". Re-seeding is a separate act after merge (a PATCH on the label object, or ensure-pm-labels.sh --reconcile from a shell that has gh).

Verification

Everything below ran on 76eab9dce6 — this branch's head, with origin/main merged in at 6a3cc134c4.

Self-test, red first. Five new H18 cases were written before the edit: three pin the new sentence (the question is unanswered; the remedy is answer + drop the label in the same write; an answer needing the maintainer still drops it), two assert the retired vocabulary is gone from both row shapes. All five failed against the old sentence, all five pass now.

before edit:  5 of 2267 case(s) failed
after edit:   2267 cases pass          (2262 on main -> 2267; no case dropped)

Ablation. The new sentence was replaced by the retired one on a throwaway copy of the script — the tracked file was never mutated, the copy was deleted, and the tracked blob's hash was compared against its HEAD blob afterwards (identical). The mutation was confirmed on disk by occurrence count, not by the editor's exit code. Result: exactly the five new cases went red, the other 2262 stayed green.

Gates. Derived on the final two-path file list with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack — 32 commands, all run, all exit 0, reconciled with --ran (32 derived, 32 run, 0 NOT-MEASURED, 0 UNRUN). Whole-repo pnpm lint (eslint . --no-inline-config) green through the shared verify lock. pnpm check:pm-half-states, pnpm check:pm-label-desc-cap (23 descriptions, all at or under 100 — it puts a fake gh on PATH and runs the real script, so the shell edit is exercised end to end), node scripts/pm/check-label-desc-cap.mjs --self-test, and the self-tests of the five other scripts/pm/ tools that name either edited file — all green. bash -n on the shell script parses.

node scripts/pm/check-governed-merges.mjs --test on both paths: 0 of 2 hit the register — not a governed surface, ordinary queue landing applies. skip-changeset because the diff publishes nothing from any released package.

pnpm check:published-readme-exports exits 3, NOT MEASURED — it needs 45 built packages and this tree is not built. It is a roster gate unrelated to these two paths; recorded here rather than read as a pass.

The row, rendered

`pm:retriage` carried alongside its standing `pm:queue`, ~3h without activity (threshold 2h) — the
question the objecting seat put to triage is still unanswered past one triage cycle. The triage
Routine answers every `pm:retriage` card's question each fire (SKILL.md); a card still here past the
threshold is an answer pass that did not run, not inventory: answer what the comment asks and drop
the label in the same write (an answer that needs the maintainer goes to the inbox with the label
still removed), oldest first.

Generated by Claude Code

…the label

`pm:retriage` is a question put to the triage seat — a re-grade, a lane for a
cross-domain PR, a re-route, a split, a disposition fork a dev report left open
— stated by the objection comment, answered every fire and removed in the same
write (SKILL.md). Three surfaces still spoke the retired re-grade vocabulary:
H18's threshold citation (which quoted a SKILL.md line that no longer exists),
its finding sentence ("the objecting seat's grade is still undecided … resolve
the grade (keep or change)"), and the `pm:retriage` description created by
`ensure-pm-labels.sh`.

Prose and one description string. `h18RetriageAged`'s predicate, threshold,
`updated_at` proxy, coexisting-label sentence and report-only exit semantics are
unchanged; the ALONE-shape note (异议对象不明) stays as written. The new label
description measures 91 code points / 91 bytes against GitHub's 100-character
cap; the live label objects are NOT re-seeded by this commit.

Self-test: 2262 -> 2267 cases, five new H18 pins — three on the new sentence,
two asserting the retired vocabulary is gone from both row shapes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox

os-steve commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator Author

ACCEPT — in-seat review of PR #15795, head 76eab9dce (skills seat, 2026-09-05T08:4xZ).

Implemented-by: claude/issue-15744-retriage-is-a-question-h18-and-label (os-dev subagent)
Reviewed-by: session_019RfFHiRCSs3JXLK4cwcfox (skills seat)

Verified in a detached compare worktree at the PR head, three-dot against origin/main, not from the report: two files, +54 / −38, prose and one description string, no logic. In scripts/pm/check-half-states.mjs the H18 threshold JSDoc now quotes the landed triage-duty line verbatim (「pm:retriage 每 fire 先答异议评论所求,答后同笔摘标;须维护者答的进收件箱,标照摘」) in place of the retired citation; the finding sentence reads the label as a question the objecting seat put to triage, still unanswered past one cycle, with the remedy "answer what the comment asks and drop the label in the same write (an answer that needs the maintainer goes to the inbox with the label still removed)"; the header inventory and the PM_RESIDUE_LABELS docblock follow; the predicate, RETRIAGE_STALE_HOURS, the updated_at proxy, the coexisting-label sentence and the ALONE-shape note are byte-identical; the two mentions that only say the label coexists with a state were read and left. In scripts/pm/ensure-pm-labels.sh the description reads "Question for triage, answered each fire; coexists with the standing pm:* label; no dispatch" — 91 bytes under the 100-character cap — and the comment block above it names the answer pass instead of the re-judgement pass. Self-test 2262 → 2267 on the head (seat run, exit 0); the five new cases pin the new words and the absence of the retired ones. No model names in the diff or the PR body; Fixes #15744 first line; skip-changeset with the size label intact. Not governed (check-governed-merges --test exit 0 on both paths).

The dev's evidence beyond the seat's runs: red first (5 of 2267 failed before the edit, exactly the five new cases), ablation on a throwaway copy with the mutation proven on disk and the restore proven by blob hash, 32 derived families all exit 0 and reconciled 32 of 32 after merging main, whole-repo lint through the lock, the label-cap gate end to end on the real script (23 descriptions at or under 100), and CI on 76eab9dce: 35 check runs completed, none non-success. Two NOT MEASURED readings recorded as such (an unbuilt-tree roster gate; the env-carried guard that exits 2 without PR context and 0 with it).

Open question ruled A: the landed 91-byte description stands — "standing" carries the maintainer-ruled half (the original grade stays authoritative until the question is answered), "no dispatch" is the file's own idiom for the fact, and only A leaves the cap real headroom.

Landing regime: pure code ⇒ ready + auto-merge in this same act (the queue's SQUASH governs whatever method the tool reports); Fixes #15744 closes the card on merge. The live label objects are not re-seeded by this PR; after it lands the seat patches the description on objectstack and objectui over REST with a read-back, and records cloud, objectos and hotcrm as pending the next five-repo reconcile run.


Generated by Claude Code

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

Labels

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

Projects

None yet

2 participants