Skip to content

feat(pm): add H18 — pm:retriage aged past the triage cycle - #10184

Merged
qq9340100 merged 1 commit into
mainfrom
claude/issue-10082-retriage-age-row
Aug 20, 2026
Merged

feat(pm): add H18 — pm:retriage aged past the triage cycle#10184
qq9340100 merged 1 commit into
mainfrom
claude/issue-10082-retriage-age-row

Conversation

@qq9340100

Copy link
Copy Markdown
Collaborator

Fixes#10082

What

Adds H18 to scripts/pm/check-half-states.mjs: a report-only row for an
open card carrying pm:retriage past a 2h threshold (RETRIAGE_STALE_HOURS,
aligned to the triage Routine's hourly re-judgement cadence — same reasoning
as DOMAIN_HALF_STATE_STALE_HOURS/H13). Maintainer ruling 2026-08-19/20,
verbatim: 「同意 并存」— pm:retriage coexists with the card's standing pm:*
label rather than replacing it, and the triage Routine is the sole remover.
Without an age check that label becomes the next half-state nobody watches.

  • The row names the card and its coexisting standing pm:* label(s).
  • pm:retriage present with no coexisting pm:* label gets its own note
    instead — the coexistence the state model requires is itself missing, so
    the disputed grading is unidentifiable (异议对象不明).
  • Age is read from updated_at (the same timeline-fetch-free proxy H13
    uses) — every triage re-judgement bumps it, so a stale reading means
    nothing touched the card since any triage pass.
  • Wired into the existing unscoped pass (H13-H15) — pm:retriage can
    coexist with a label this sweep's label pages never fetch (e.g.
    pm:blocking) or with none at all, so only the unscoped listing is
    guaranteed to see every carrier. No new fetch.
  • Report-only, ordinary row in both renderers (plain + markdown), never loud
    — same property H14-H16 hold.

Tests

pnpm check:pm-half-states (== node scripts/pm/check-half-states.mjs --self-test) at e47badf: 489 cases pass (469 baseline before this PR,
re-measured on origin/main at dispatch time, matching the #10082 handoff
comment's 414→469 note; +20 new H18 cases here).

New cases cover: over-threshold hit (single and multiple coexisting pm:*
labels), under-threshold no-hit, exactly-at-threshold (clean), no
pm:retriage label (out of scope), the disputed-target variant
(pm:retriage alone — asserts the 异议对象不明 note and that no coexisting
label is falsely claimed), a domain:* label not counted as a coexisting
pm:* label, unreadable/absent updated_at (#4690: must not read as
fresh), not-loud, and the plain/markdown ordinary-row rendering shapes
(mirroring the H14/H15/H16 pins).

✓ check-half-states self-test: 489 cases pass.

Also green at the same head:

  • node scripts/check-cross-package-test-inputs.mjsOK: 12 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.
  • pnpm check:nul-bytesOK (scanned 6066 text file(s) ... no raw ASCII control bytes)

node scripts/check-partof-closing-keyword.mjs requires PR_BODY/PR_NUMBER
(a PR-body linter with no local dry-run target) — validated locally against
this exact body via PR_BODY="$(cat pr-body.md)" node scripts/check-partof-closing-keyword.mjs: ✓ this PR carries no Part-of/ closing-keyword contradiction. It also runs in CI on
.github/workflows/partof-closing-keyword-guard.yml.

Scope

Non-governed surface (internal tooling): skip-changeset.


Generated by Claude Code

Report-only invariant in check-half-states.mjs: an open card carrying
pm:retriage past a 2h threshold (RETRIAGE_STALE_HOURS, aligned to the
triage Routine's hourly re-judgement cadence, same reasoning as
DOMAIN_HALF_STATE_STALE_HOURS/H13) is triage debt — the objecting
seat's grade is still undecided past a cycle the Routine should have
re-judged it in.
The row names the card and its coexisting standing pm:* label;
pm:retriage present with no coexisting pm:* label gets its own note
(disputed grading is unidentifiable, 异议对象不明). Age is read from
updated_at, the same timeline-fetch-free proxy H13 uses. Wired into
the existing unscoped pass (H13-H15) so it needs no new fetch. Ordinary
report-only row in both renderers, not loud — same as H14-H16.
20 new self-test cases (positive/negative/threshold-edge/unreadable/
disputed-target/render shapes); self-test count 469 -> 489.
Fixes#10082
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

patrol: H-next — pm:retriage aged past threshold is a triage debt row

2 participants

@qq9340100@claude