diff --git a/plugins/work-items/.claude-plugin/plugin.json b/plugins/work-items/.claude-plugin/plugin.json index 52559472f..fbeb91867 100644 --- a/plugins/work-items/.claude-plugin/plugin.json +++ b/plugins/work-items/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "work-items", - "version": "0.16.0", + "version": "0.16.1", "description": "Manages development work items through a provider-neutral tracker seam that ships with the plugin (bundled dispatcher plus github and local-markdown adapters; seam plugin-dir canonical, adapters consumer-local-first): dashboard, taxonomy-labeled creation, a race-safe assignee-plus-lease claim protocol, recurring-schedule checks, TODO scanning, stale-lease auditing, plan decomposition into vertical-slice items, and raw-intake triage (issues and unsolicited PRs through raw, verified, briefed, autonomous-eligible states). The re-runnable setup skill binds the provider (.work-item-tracker.json), seeds the recurring-schedule seam (.github/recurring-schedule.json), and remaps canonical role labels.", "author": { "name": "Melodic Software", diff --git a/plugins/work-items/CHANGELOG.md b/plugins/work-items/CHANGELOG.md index 55d083ba3..45044ab9f 100644 --- a/plugins/work-items/CHANGELOG.md +++ b/plugins/work-items/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to the `work-items` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.16.1] + +### Fixed + +- **Triage side-exit routing now clears the raw-intake marker on every outcome (`#562`).** The + closing invariant in the triage skill only named `status:ready` and the two role labels as + contradictory with the raw marker, and pinned the marker to a single hardcoded label string. A + status side-exit — `status:needs-decision`, `status:needs-info`, human-gated (`needs-human`), or + the terminal `status:ready` — could leave `needs-triage` attached, so an already-decided item + (e.g. `#505`, routed to `status:needs-decision`) resurfaced in the next cycle's needs-triage queue + as if it were unrouted intake, wasting a read-and-confirm pass every cycle. The invariant is now + exhaustive across the routing space — **every** open-keeping outcome removes the raw marker in the + same edit — and framed 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; absorbed into the triage `SKILL.md` alongside the `#478` routing rules. + ## [0.16.0] Close the work-item-tracker seam's container read-verb gap (`#498`): the seam reserves `work-map` diff --git a/plugins/work-items/skills/triage/SKILL.md b/plugins/work-items/skills/triage/SKILL.md index 62ff1cb38..77a5a517a 100644 --- a/plugins/work-items/skills/triage/SKILL.md +++ b/plugins/work-items/skills/triage/SKILL.md @@ -117,7 +117,7 @@ Only after verification (or for enhancements, where the open question is scope, ### 5. Apply outcome -Every outcome is a **transition off raw**, not a layer on top of it. Applying an outcome **clears the raw-intake marker**: remove `status:needs-triage` (and the item leaves the unlabeled raw state) in the same edit that applies the labels below. The label sets in the table are the item's **resulting** state, not deltas stacked over `status:needs-triage` — normalization replaces the raw marker, it never adds to it. +Every outcome is a **transition off raw**, not a layer on top of it. Applying an outcome **clears the raw-intake marker** — the default `needs-triage` label a fresh item carries before triage, resolved from the live set (whichever axis the repo files it under) — in the same edit that applies the labels below, and the item leaves the unlabeled raw state. The label sets in the table are the item's **resulting** state, not deltas stacked over the raw marker — normalization replaces the raw marker, it never adds to it. | Outcome | Action | |---------|--------| @@ -141,7 +141,7 @@ Label edits, comments, and closes route through the adapter's write mechanics (a **Closing invariant — no outcome leaves a re-selectable raw item.** The attention view lists *open* items and re-selects anything still carrying the raw marker, so every outcome must leave the item unre-selectable: -- Outcomes that keep the item **open** (briefed/ready, a role label, or `status:needs-info`) **clear `status:needs-triage`**. A raw marker alongside `status:ready`, the autonomous-eligible role label, or the human-gated role label is a contradiction — the attention view reads it as still-raw and re-triages it every cycle. If an item shows both, the briefed state is the truth; clear the stale raw marker. +- **Every routing outcome that keeps the item open clears the raw-intake marker in the same edit that applies the outcome's labels — no exceptions across the routing space.** `status:ready` (briefed/ready and decision-defaulted), the autonomous-eligible role label, the human-gated role label (default `needs-human`), `status:needs-decision`, and `status:needs-info` each **remove the raw marker**; never leave both the raw marker and a routing label present. A raw marker alongside any routing label is a contradiction — the open-only attention view reads it as still-raw and re-triages it every cycle, so an already-decided item re-enters the needs-triage queue as if it were unrouted intake and wastes a read-and-confirm pass. If an item shows both, the routed state is the truth; clear the stale raw marker. - **Close** (already implemented / wontfix / duplicate) drops the item from the open-only attention frontier, so the raw marker is moot — a closed item never re-triages. ## Needs-info template