Skip to content

fix(work-items): clear raw-intake marker on every triage side-exit (#562)#728

Merged
kyle-sexton merged 1 commit into
mainfrom
fix/562-triage-side-exit-label-clear
Jul 20, 2026
Merged

fix(work-items): clear raw-intake marker on every triage side-exit (#562)#728
kyle-sexton merged 1 commit into
mainfrom
fix/562-triage-side-exit-label-clear

Conversation

@kyle-sexton

Copy link
Copy Markdown
Contributor

Summary

The /work-items:triage skill's closing invariant did not reliably clear the raw-intake needs-triage marker when routing an item to a status side-exit. Its enumeration only named status:ready and the two role labels as contradictory with the raw marker, omitting status:needs-decision and status:needs-info, and it pinned the marker to a hardcoded status:needs-triage string. As a result an already-decided item could keep the raw marker and resurface in the next cycle's needs-triage queue as if it were unrouted intake — wasting a read-and-confirm pass every cycle.

Fix

Doc-only change to plugins/work-items/skills/triage/SKILL.md:

  • Made the closing invariant exhaustive across the routing space: every open-keeping outcome — status:ready (briefed/ready and decision-defaulted), the autonomous-eligible role label, the human-gated role label (needs-human), status:needs-decision, and status:needs-info — removes the raw marker in the same edit that applies the outcome's labels; never leave both present.
  • Reframed the "Apply outcome" preamble and the invariant around the abstract raw-intake marker resolved from the live label set rather than a hardcoded prefix, so the instruction is correct regardless of which axis a repo files needs-triage under (this repo deploys it as priority: needs-triage; the plugin's own taxonomy grammar mandates reading members from the live set).

Extends the #478 routing rules already absorbed into the triage SKILL.md (that issue is closed; the skill is now the invariant's natural home).

Follow-up findings (non-blocking, out of this PR's charter)

  • This repo's live raw marker is priority: needs-triage, but SKILL.md (state table, attention view), evals.json, and the two reference docs snapshot it as status:needs-triage. The abstract framing here makes the fix correct regardless; reconciling the axis mismatch is a maintainer taxonomy decision spanning shared docs.
  • status:needs-decision is a live routing outcome (#505 carries it) that the triage state machine does not model (its briefed exits are delegable / decision-defaulted / human-gated / needs-info). Worth a follow-up to align the state machine with the deployed label set.

Verification

Branch fast-forwarded to current origin/main before verifying (it was 3 commits behind, which produced a false skill-quality parity flag until updated).

  • scripts/validate-plugins.sh — all plugin manifests + catalog: Validation passed
  • scripts/check-changelog-parity.sh --check-bump origin/mainEvery plugin whose version changed vs origin/main has a '## [<version>]' CHANGELOG.md entry.
  • scripts/check-skill-portability.sh origin/mainNo unexcused coupling tokens in 1 skill file(s).
  • scripts/check-changed-skills.sh origin/mainCHECK-SKILL triage: PASS — 0 errors, 1 warning(s) (pre-existing no-Gotchas warning)
  • scripts/check-skill-leaf-names.sh --checkAll 8 cross-plugin skill leaf-name collisions are registered.
  • markdownlint-cli2 on both changed markdown files — Summary: 0 error(s)
  • plugin.json — valid JSON; version bumped 0.16.0 -> 0.16.1

Closes #562

Related

)

The triage skill's closing invariant only named `status:ready` and the two
role labels as contradictory with the raw-intake marker, and pinned the marker
to a hardcoded `status:needs-triage` string. A status side-exit —
`status:needs-decision`, `status:needs-info`, human-gated, or the terminal
`status:ready` — could leave the raw marker attached, so an already-decided
item (e.g. #505) resurfaced in the next cycle's needs-triage queue as unrouted
intake, wasting a read-and-confirm pass every cycle.

Make the invariant exhaustive across the routing space — every open-keeping
outcome removes the raw marker in the same edit — and frame it around the
abstract raw-intake marker resolved from the live label set rather than a
hardcoded prefix, so it holds regardless of which axis a repo files
`needs-triage` under. Doc-only; extends the #478 routing rules already absorbed
into the triage SKILL.md.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kyle-sexton kyle-sexton added the automated Opened by automation. label Jul 20, 2026
@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 43s —— View job


PR Review

  • Gather context and understand the PR
  • Read the changed files
  • Review for correctness, security, and CLAUDE.md alignment
  • Post final review feedback

Summary: Doc-only patch to plugins/work-items/skills/triage/SKILL.md. The core fix is correct and well-scoped — the closing invariant is now exhaustive across the full routing space, and the abstract framing of the raw-intake marker is an improvement over the hardcoded status:needs-triage string. Version bump and changelog entry are properly structured. No security concerns (no executable code changed; REVIEW.md blocking checks are all N/A for a doc-only diff).

One structural observation and two minor inconsistencies worth flagging:


status:needs-decision appears in the invariant but is absent from the state machine and outcome table

The updated invariant at SKILL.md line 144 now explicitly names status:needs-decision as an outcome that must clear the raw marker — which is the right rule. But an agent reading this skill has no path to apply status:needs-decision: the state machine diagram (lines 59–66) doesn't model it, and the outcome table (lines 122–133) has no corresponding row.

The invariant tells agents "if you applied this label, also clear the raw marker", which is correct. But without a table row, an agent has no signal for when this label is appropriate versus the existing human-gated or status:needs-info exits. Putting status:needs-decision in the invariant without modeling it in the machine creates a forward reference to a state the skill doesn't yet teach. The PR description acknowledges this gap and flags it as a follow-up — that's the right call for scope reasons. Just worth tracking: the follow-up should add the state-machine entry alongside the outcome row, or the invariant's mention of this label will remain context-free for agents reading the skill cold. 🟡 Nit


Attention view and state table still hardcode status:needs-triage

The "Apply outcome" preamble now correctly abstracts the raw marker to "resolved from the live set (whichever axis the repo files it under)". But two other locations still reference it by name:

  • Line 46 — state table: status:needs-triage as the tracker marker for raw
  • Line 76 — attention view: bucket 2 labeled status:needs-triage

This is consistent with the PR description's acknowledgment that reconciling the axis mismatch (priority:needs-triage vs status:needs-triage) is a maintainer taxonomy decision out of this PR's charter — the abstract preamble framing keeps the fix semantically correct regardless. Still worth a follow-up pass to make these two display sites consistent with the preamble language. 🟡 Nit


Everything else looks good. The invariant rewrite at line 144 is substantially more correct than what it replaces: the previous version only named status:ready and the two role labels, silently omitting status:needs-decision and status:needs-info, and pinned the marker string. The new version covers all five open-keeping routing outcomes and the wording is clear. The CHANGELOG entry under [0.16.1] accurately describes both the bug and the fix. The 0.16.0 → 0.16.1 semver bump is appropriate for a patch.

@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Post-green review pass complete (rule 8). Bot review classification:

Finding Verdict Action
status:needs-decision in the invariant but unmodeled in the state machine/outcome table VALID, non-blocking follow-up (already flagged in the PR body by the worker) Deferred — appended to #657 sweep
Attention view + state table still hardcode status:needs-triage string display-wise VALID, non-blocking follow-up (already flagged in the PR body) Deferred — appended to #657 sweep

Both are cosmetic-doc-consistency, not DEFER-FORBIDDEN classes (no data-loss/fail-open-gate/security-posture/silent-wrong-output). No inline threads, CI fully green (18/18).

Flipping to ready for review; handing off to the babysit lane for merge.

@claude

claude Bot commented Jul 20, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 1s —— View job


Babysit / Merge-Readiness Pass

  • Gather context and understand the PR
  • Read changed files
  • Check CI status
  • Verify previous review findings were classified / deferred
  • Post merge-readiness verdict

Verdict: Ready to Merge ✅

CI: All prerequisite checks green — ci, pr-title, pr-issue-linkage, do-not-merge all success.

Diff review (3 files):

File Assessment
plugin.json Version bump 0.16.0 → 0.16.1 — correct semver (patch, doc-only fix) ✅
CHANGELOG.md [0.16.1] section — accurate bug description, correct Keep-a-Changelog format ✅
SKILL.md L117 Preamble now abstracts raw-intake marker from hardcoded status:needs-triage to "resolved from the live set (whichever axis the repo files it under)" — correct and future-proof ✅
SKILL.md L144 Closing invariant is now exhaustive — all five open-keeping outcomes (status:ready, autonomous-eligible role, needs-human, status:needs-decision, status:needs-info) are named and each removes the raw marker ✅

Previous review findings: Both nits (#status:needs-decision unmodeled in state machine; display sites still hardcode status:needs-triage) were correctly classified non-blocking by @kyle-sexton and deferred to #657. Neither is a DEFER-FORBIDDEN class issue, and the abstract preamble framing makes the core fix semantically correct regardless of the label-axis mismatch. Classification stands.

No new findings from this pass. The change is doc-only with no security surface, and the fix is substantively correct.

@kyle-sexton
kyle-sexton merged commit ce7f8c2 into main Jul 20, 2026
21 of 22 checks passed
@kyle-sexton
kyle-sexton deleted the fix/562-triage-side-exit-label-clear branch July 20, 2026 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automated Opened by automation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

work-items(triage): status side-exit routing does not reliably clear priority: needs-triage, letting already-decided items re-enter the queue

1 participant