Triage
Drive issues through the triage state machine - route incoming issues to needs-info, ready-for-agent, ready-for-human, or wontfix, and keep states legal on both backends (sphinx-needs status edits or GitHub labels). Use when the user wants to triage issues, review the backlog, prepare issues for an agent, or says "triage" / "go through the open issues".From its SKILL.md
npx -y skills add patdhlk/skills --skill triageAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.7 KB, ~2.2k tokens by cl100k_base, as published. Nobody here has run it
Triage
One state machine, schema-enforced on the local backend (ADR_0005):
needs-triage ──► needs-info | ready-for-agent | ready-for-human | wontfix
needs-info ──► (answered) ──► needs-triage
ready-for-* ──► in-progress ──► done | wontfix
/triage owns the routing decisions; in-progress/done belong to whoever
does the work. Never jump states (e.g. needs-triage → done) — the enum
won't catch it, you must.
Workflow
1. Resolve configuration and load the queue
Read [tool.patdhlk-skills] from ubproject.toml (missing → point to
/setup-patdhlk-skills).
- sphinx-needs:
pds statusfirst — it rebuilds needs.json (ADR_0006) and emits the per-status counts, the "what needs attention" buckets, in one query. Then the queue = issues withstatus == "needs-triage"(jq over the fresh needs.json), plusneeds-infoones whose question got answered since. - github:
gh issue list --label needs-triageplus open issues with no state label at all (treat unlabeled as needs-triage; offer to label them). Ensure the five state labels exist (gh label create, idempotent).
Empty queue → say so and stop.
2. Route each issue
Before routing, gather search evidence for each issue (sphinx-needs backend
only). If pds is not on PATH, print a loud warning pointing to
/setup-patdhlk-skills and skip this enrichment step.
pds search "<issue title> <issue body>" --config ubproject.toml
# exit 0 → hits JSON; exit 2 → stop and escalate
Use the full title + body as the query (ADR_0021 saturation). The top hit
is the issue under triage itself — skip it; judge the remaining
hits. A high-scoring hit on a done issue or an
arch-decision means the report is already shipped; a high-scoring hit on
another open issue means it may be a duplicate. Feed both signals into
rule 1 below. The github backend keeps its existing gh issue list
judgment; pds search is not available there.
Apply in order — first match wins:
- Duplicate / invalid / out of scope →
wontfix, with a one-line reason (and the duplicate's ID if any). Use the search hits above as evidence — cite the twin's ID when recommending duplicate. - Cannot be acted on as written — missing repro, ambiguous scope, no
way to verify →
needs-info, writing the concrete question. - An agent can finish it unattended — clear acceptance criteria, no
unresolved design decisions, no credentials or human taste required →
ready-for-agent. - Otherwise →
ready-for-human(say what the human must decide).
Propose the routing for the whole queue in one table (ID, title, verdict, reason) and get the user's go-ahead — they may override any verdict — before applying. An override into an in-scope status still authors a fail-closed verdict (§3a).
3. Apply transitions
- sphinx-needs: edit each
:status:in place in the issue's RST — git history is the audit trail, no changelog field. Forneeds-info, append the question to the directive body under a**Needs info.**lead-in. Forwontfix, append the one-line reason the same way. - github: swap the state label (remove old, add new). For
needs-infoandwontfix, post the question/reason as a comment; closewontfixissues as not-planned (gh issue close --reason "not planned").
3a. Author or update the triage verdict (sphinx-needs backend only)
Fire only when routing into ready-for-agent, ready-for-human, or
in-progress. Routing to needs-info, wontfix, or needs-triage
authors nothing.
Ordering:
- Apply the
:status:edit and any title/body tightening this pass makes (step 3 above). - Run
pds fingerprint <id>last — after every title/body edit:
Only title+body enter the hash (ADR_0015), so thepds fingerprint ISSUE_0042 --config ubproject.toml # prints {"schema":1,"verb":"fingerprint","id":"ISSUE_0042","fingerprint":"sha256:..."}:status:edit's position does not matter — but a fingerprint taken before a body edit is born stale, which the gate then flags. Compute it after the issue is in its final shape. - Write or edit
VERDICT_<id>inspec/verdicts/index.rst. The derived ID is one slot — edit in place if it already exists (re-triage after aneeds-inforound-trip); git history is the audit trail (ADR_0005). The directive must carry::rubric: triage, the computed:fingerprint:,:axes_failed:per the fail-closed rule, and per-axis reasoning as body prose. - Run
make strict(step 4).
The four triage axes (each is an affirmative claim; ADR_0016):
- category — exactly one correct
:kind:for the content (e.g.bug,improvement,feature). - state — the routing target is justified. For
ready-for-agentthis means: clear acceptance criteria, no unresolved design decision, no credentials or human-taste required (route rule 3 — an agent finishes unattended). - actionability — the body is self-contained to the AGENT-BRIEF.md bar: a fresh agent can execute without conversation history.
- duplicate-check —
pds search/dedupwas run and the top non-self hits were judged not duplicate and not already-shipped.
Fail-closed rule: any axis the triager cannot affirmatively confirm
goes into :axes_failed: with a finding sentence in the body explaining
why — never omitted, never optimistically passed. A passing (empty
:axes_failed:) verdict asserts all four were positively cleared.
Worked RST example (mirror the spec/verdicts/index.rst tracer shape):
.. verdict:: Triage verdict for ISSUE_0042
:id: VERDICT_ISSUE_0042
:links: ISSUE_0042
:rubric: triage
:fingerprint: sha256:abcd1234ef567890
*This was generated by AI during triage.*
Judged on <date>. **category**: improvement, clear-cut — a bounded
prose change with no ambiguous type. **state**: ready-for-agent —
acceptance criteria are independently verifiable, no open design
decisions, no credentials required. **actionability**: body is
self-contained; a fresh agent executes without conversation history.
**duplicate-check**: ``pds search`` top non-self hits judged not
duplicate and not already-shipped.
Quick-override path ("move #42 to ready-for-agent", skip-grill): still
authors a verdict, but fail-closed — all unevaluated axes go in
:axes_failed: with the finding "routed by maintainer override, not
triage-judged", so the gate flags it for a real triage pass rather than
rubber-stamping. A failing verdict lists the failed axes in
:axes_failed: (comma-separated):
.. verdict:: Triage verdict for ISSUE_0042
:id: VERDICT_ISSUE_0042
:links: ISSUE_0042
:rubric: triage
:fingerprint: sha256:abcd1234ef567890
:axes_failed: category, state, actionability, duplicate-check
*This was generated by AI during triage.*
Routed to ready-for-agent by maintainer override, not triage-judged:
no axis was affirmatively checked. Needs a real triage pass.
4. Validate and report
Local mutations end with the strict gate (ADR_0007, ADR_0017):
pds check
# no pds: uv run sphinx-build -W -b html <spec_dir> <spec_dir>/_build/html
Exit 0 means proceed; exit 1 means fix the corpus and re-run; exit 2 means
stop and escalate.
Report counts per verdict (pds status after the gate shows the new
buckets) and the ready-for-agent list — that's the pickup queue for the
next work session; pds next returns its lowest-ID member as JSON.
For each issue in ready-for-agent or ready-for-human, name its verdict
in the report: ID + pass (empty :axes_failed:) or fail (list the failing
axes). Example: "ISSUE_0042 → VERDICT_ISSUE_0042 (pass)". A green
make strict guarantees a passing, fresh verdict on every in-scope issue —
that is the pickup contract.
Hard rules
- Only the transitions drawn above;
/triagenever setsin-progressordone. - Every
needs-infocarries a concrete, answerable question; everywontfixcarries a reason. No silent state changes. - The user confirms the routing table before anything is applied.
- A failed strict gate is YOUR bug to fix before reporting success.
- Never author a passing verdict for an axis you did not affirmatively check — uncertain is a failing axis with a finding, never a silent pass.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.