Agent skill
work-backlog-item
Use when working, planning, or closing a backlog item. Bridges backlog items to SAM planning with GitHub Issue/Project/Milestone tracking. No args: interactive browser. '#N': load from GitHub Issue #N. Title substring: auto-grooming, RT-ICA gate, GitHub sync, SAM planning. '--auto {title}': autonomous mode — no AskUserQuestion, derives data from research files, logs decisions. 'close {title}': dismiss without completion — reason required (duplicate, out_of_scope, superseded, wontfix, blocked). ADR-9. 'resolve {title}': mark DONE with evidence trail — summary required. ADR-9. 'setup-github': init labels, project, milestone. '--language' and '--stack' select Layer 1/2 profile. STOPS if item has Plan field or RT-ICA returns BLOCKED.
Install this agent skill to your Project
npx add-skill https://github.com/Jamie-BitFlight/claude_skills/tree/main/plugins/development-harness/skills/work-backlog-item
SKILL.md
$0 <item_ref>$1</item_ref> <invocation_args>$ARGUMENTS</invocation_args>
Work Backlog Item
Bridge a backlog item into the SAM planning pipeline via /dh:add-new-feature (default). Optional --language and --stack select Layer 1/2 profiles — see sdlc-layers.
See the Backlog Lifecycle reference for the complete state machine, handoff protocol, and data architecture.
Phase separation: Grooming (Step 3.1) is autonomous research — the agent verifies facts, maps resources, estimates effort, and surfaces blockers. Planning (Step 4.2) is solution design — architecture, tasks, implementation. The human sets priorities and resolves blockers; the agent handles research and fact-checking autonomously.
SAM — Stateless Agent Methodology. See sam-definition.md for what SAM is and how to embody it. SAM lives in ../stateless-agent-methodology/ (or bitflight-devops/stateless-agent-methodology on GitHub).
Primary source of truth is GitHub Issues (labels + milestone = canonical status). Local per-item files are a read cache maintained by the MCP server.
When invoked with no arguments, shows an interactive browser. When invoked with #N or a title substring, proceeds directly to the planning workflow.
Arguments
<mode/> selects the operating mode; remaining positional args (<item_ref/>, $2, ...) form the title or parameter:
<mode/> value |
Remaining args meaning |
|---|---|
| (empty) | — |
#N / bare number / GitHub issue URL |
issue number |
--auto |
<item_ref/>+ = title (or empty → auto-select first open P0/P1 item) |
close / resolve |
<item_ref/>+ = title, #N, number, or URL |
setup-github |
— |
--quick |
<item_ref/>+ = title |
progress / resume |
<item_ref/>+ = title or #N (optional for resume) |
| (any other) | <invocation_args/> treated as title substring |
Optional flags (when <mode/> is title substring or --auto): --language <lang> selects language plugin (default: python); --stack <profile> selects stack profile (e.g., python-fastapi, python-cli). See sdlc-layers.
/work-backlog-item # interactive browser
/work-backlog-item #42 # issue-first → planning
/work-backlog-item 42 # issue-first (bare number) → planning
/work-backlog-item https://github.com/OWNER/REPO/issues/42 # URL → planning
/work-backlog-item Error Recovery # direct match → planning
/work-backlog-item --auto # autonomous → auto-select first open P0/P1
/work-backlog-item --auto vercel skills npm package # autonomous → planning
/work-backlog-item close Error Recovery # dismiss (reason required)
/work-backlog-item close #42 # dismiss by issue number
/work-backlog-item resolve Error Recovery # mark completed with evidence
/work-backlog-item resolve #42 # mark completed by issue number
/work-backlog-item --language python --stack python-fastapi Add auth # Layer 2 stack profile
--auto mode rules
All interactive AskUserQuestion calls are replaced with evidence-derived decisions. Full substitution table: auto-mode.md
Workflow
Routing (evaluated first, before any step)
Dispatch based on <mode/> (the first argument word) before executing any step:
flowchart TD
Start(["<mode/> value"]) --> Q1{Value?}
Q1 -->|"empty"| S0["Step 1.1 — interactive browser"]
Q1 -->|"#N / bare number / GitHub issue URL"| S1b["Step 1.2 — Issue-first path<br>title source: issue number from input"]
Q1 -->|"--auto"| Auto["AUTO_MODE=true → Step 1.3<br>title source: <item_ref/>+ joined<br>(empty → auto-select first open P0/P1)"]
Q1 -->|"--quick"| SQ["Step Q — quick mode<br>load ./references/step-procedures.md#step-q-quick-mode<br>title source: <item_ref/>+ joined"]
Q1 -->|"progress"| SP["Step P — progress report<br>load ./references/step-procedures.md#step-p-progress-report"]
Q1 -->|"resume"| SR["Step R — resume report<br>load ./references/step-procedures.md#step-r-resume-report<br>title source: <item_ref/>+ joined (optional)"]
Q1 -->|"close"| S9c["Step 5.1 — close path (dismiss without completion)<br>title source: <item_ref/>+ joined (title, #N, number, or URL)"]
Q1 -->|"resolve"| S9r["Step 5.1 — resolve path (mark completed with evidence)<br>title source: <item_ref/>+ joined (title, #N, number, or URL)"]
Q1 -->|"setup-github"| SGH["load ./references/github-integration.md#setup-github-command"]
Q1 -->|"any other string"| S1["Title substring → Step 1.3 (interactive mode)<br>title source: <invocation_args/>"]
AUTO_MODE — set when $0 is --auto. All AskUserQuestion calls are replaced with evidence-derived decisions. See auto-mode.md for the substitution table.
Phase 1: Locate
Step 1.1: Interactive Browser (no arguments only)
Trigger: <mode/> is empty (no arguments passed).
Full procedure (MCP error handling, display format, response handling): step-procedures.md
Step 1.2: Issue-First Path (#N, bare number, or GitHub URL)
Trigger: <mode/> matches #[0-9]+, is a bare number, or is a GitHub issue URL (https://github.com/.../issues/N).
<issue_first_procedure>
Fetch the issue using the mcp__plugin_dh_backlog__backlog_view tool (accepts URLs, #N, and bare numbers):
Call the mcp__plugin_dh_backlog__backlog_view tool with selector="{<mode/>}".
If the tool returns a dict with an error key, report and stop.
Parse the returned dict. If state is closed, run the Completed Issue Discovery procedure and stop. Full procedure (git commands, report template, AUTO_MODE behavior): step-procedures.md
From the JSON response build the working item:
| Field | Source |
|---|---|
title |
title |
description |
body (full text) |
source |
"GitHub Issue #N" |
priority |
priority field (extracted from priority:* label) |
status |
status field (extracted from status:* label — canonical) |
milestone |
milestone |
plan |
plan field, or search body for **Plan**: line |
The backlog_view MCP tool merges local cache with live GitHub issue data. All fields needed for subsequent steps are available in the response — do not read local files directly.
Proceed to Step 2.4 (Set In-Progress Label) with the assembled item, then continue to Step 3.1.
</issue_first_procedure>
Step 1.3: Find the Backlog Item
Bypass: If <mode/> is #N, a bare number, or a GitHub issue URL — skip this step entirely and go to Step 1.2. Issue-number and URL inputs resolve via backlog_view directly; no matching strategy is needed.
Title = <item_ref/>+ joined (args after the mode flag <mode/>). In interactive mode, title = full <invocation_args/>.
AUTO_MODE with no title (<item_ref/> is empty): apply the "No title given" substitution from the --auto mode rules table — scan P0 then P1 sections for the first open item, log and use its title. Skip items with status: done or status: resolved in their entry (these are filtered out by backlog_list already).
Before executing Step 1.3: load ./references/step-procedures.md.
Record the priority section (P0, P1, P2, Ideas) the item belongs to.
Step 1.4: Extract Item Fields
From the matched item's entry in the mcp__plugin_dh_backlog__backlog_list returned dict, extract title, plan, section (priority), issue, and groomed. For detailed fields not in the list response (description, source, added, research_first, suggested_location), call mcp__plugin_dh_backlog__backlog_view(selector="{title}", summary=false) to fetch the full item from the backend.
title— thetitlefield from list JSON (required)plan— theplanfield from list JSON (optional)description— frombacklog_viewresponsedescriptionfield (required)source— frombacklog_viewresponsesourcefield (optional)added— frombacklog_viewresponseaddedfield (optional)research_first— frombacklog_viewresponse body,**Research first**:line (optional)suggested_location— frombacklog_viewresponse body,**Suggested location**:line (optional)
If the item already has a **Plan**: field, extract the plan address from the YAML filename (e.g., plan/P1079-machine-readable-inter-item-dependencies.yaml → P1079). Report:
This item already has a plan (P{NNN}). Use /dh:implement-feature P{NNN} to execute it.
Then stop.
After extracting fields, proceed to Step 2.1 (Already Implemented Check) before continuing.
Phase 2: Validate
Step 2.1: Already Implemented Check
Before planning, verify the feature/fix hasn't already been implemented (stale open issue). Full procedure (git commands, resolve calls, AUTO_MODE behavior): step-procedures.md
Step 2.2: GitHub Issue Sync
After Step 1.4, check for **Issue**: #N in the matched item. Full procedure (MCP tool calls, yes/no branching, issue creation): github-integration.md
Note: On the Issue-first path (Step 1.2), the backlog_view response already contains issue state — carry it forward without re-fetching.
Step 2.3: Create GitHub Issue
Full procedure: github-integration.md
Step 2.4: Set In-Progress Label
Full procedure: github-integration.md
Two-part step: (a) Always run mcp__plugin_dh_backlog__backlog_update with status="in-progress" for the current item. (b) Run milestone start only on explicit user intent to start the whole milestone — it bulk-transitions all open milestone issues, not just the current one.
Step 2.5: Discovery Gate
Before grooming or planning, check whether a structured discovery artifact exists.
flowchart TD
InProgress([Step 2.4 complete — label set]) --> HasIssue{"Item has GitHub<br>Issue number?"}
HasIssue -->|"No"| SkipGate["Skip discovery gate<br>Proceed to Step 3.1"]
HasIssue -->|"Yes — issue #{N}"| TypeCheck{"Labels include<br>'type:fix' or 'type:bug'?"}
TypeCheck -->|"Yes — fix/bug type"| SkipGate
TypeCheck -->|"No — feature/refactor/other"| CheckArtifact["artifact_list(<br>issue_number={N},<br>artifact_type='feature-context')"]
CheckArtifact --> HasDiscovery{"count > 0?"}
HasDiscovery -->|"Yes"| Proceed["Discovery exists<br>Proceed to Step 3.1"]
HasDiscovery -->|"No"| InvokeDiscovery["Invoke: Skill(skill='dh:discovery')<br>Wait for user confirmation loop<br>Then proceed to Step 3.1"]
SkipGate --> Continue([Step 3.1 — Auto-Groom])
Proceed --> Continue
InvokeDiscovery --> Continue
The discovery skill runs its full interactive confirmation loop (WHO/WHAT/WHEN/WHY gathering)
and registers the result as a feature-context artifact. After completion, Step 3.1 (Auto-Groom)
will detect the artifact and pass it to the grooming swarm.
Phase 3: Prepare
Step 3.1: Auto-Groom (if needed)
<groom_check>
- Check if item is groomed: Check the
groomedfield in the JSON output. Iftrue, callmcp__plugin_dh_backlog__backlog_view(selector="{title}", summary=false)— the responsesectionsdict contains all groomed content (Reproducibility, Priority, Impact, Files, Dependencies, etc.). Use that content. - Search conversation context for a recent
groom-backlog-itemoutput matching this item.
If no groomed content exists:
Skill(skill: "groom-backlog-item", args: "{item title}")
The groom skill writes groomed content via the backlog MCP server. After grooming completes, call backlog_view again to retrieve the groomed sections.
</groom_check>
Step 3.2: RT-ICA Gate
RT-ICA Staleness Policy
RT-ICA Staleness Policy: An RT-ICA result is stale and must be re-run if either condition is true: (a) the
Date:header in the RT-ICA section is older than 7 calendar days, or (b) the item'smetadata.updated_atfield is newer than the RT-ICA section date. A stale RT-ICA result is treated as absent —dh:rt-icais re-run before proceeding to Step 3.4. The 7-day threshold applies regardless of whether the item description has changed, because codebase context may have changed even if the item text has not.
flowchart TD
RCheck(["Step 3.2: RT-ICA Freshness Check"]) --> Get["Read backlog_view(selector=title, summary=false).sections['RT-ICA']"]
Get --> Absent{"sections['RT-ICA'] key present and non-empty?"}
Absent -->|"No"| RunRTICA(["Run dh:rt-ica — section absent"])
Absent -->|"Yes"| ParseDate["Extract date using regex 'Date: YYYY-MM-DD' from section<br>If no match: try first ISO date in top 3 lines of section"]
ParseDate --> DateFound{"ISO date parseable?"}
DateFound -->|"No — date not found"| RunRTICA
DateFound -->|"Yes — date D extracted"| Check1{"D older than 7 calendar days?"}
Check1 -->|"Yes"| RunRTICA
Check1 -->|"No — within 7 days"| Check2{"backlog_view metadata.updated_at present<br>AND metadata.updated_at greater than D?"}
Check2 -->|"updated_at greater than D"| RunRTICA
Check2 -->|"updated_at less than or equal to D OR field absent"| UseCache(["RT-ICA is fresh — use cached result"])
When the flowchart routes to "Run dh:rt-ica":
Skill(skill: "dh:rt-ica")
- Present and fresh → use the APPROVED/BLOCKED decision from the cached result. Carry DERIVABLE items forward as "Assumptions to confirm" in the feature request.
- BLOCKED → stop. Do not proceed to Step 3.4 until all MISSING conditions are resolved.
Step 3.3: RT-ICA Date Stamp
After dh:rt-ica completes (or the existing result is confirmed fresh), write a parseable Date: header to the RT-ICA section before storing the result:
RT-ICA Final: {item title}
Date: {YYYY-MM-DD}
Goal: {same as snapshot}
The Date: header is required for the freshness check in Step 3.2. If the RT-ICA result was retrieved from cache and already contains a Date: header, skip this step.
Step 3.4: Feasibility Gate
Trigger: RT-ICA returned APPROVED (Step 3.2) and RT-ICA Date Stamp written (Step 3.3).
Load feasibility-gate.md and evaluate all 4 criteria (technical feasibility, effort proportionality, blast radius, prior attempt check).
BLOCKED at feasibility gate stops the workflow — do not proceed to Phase 4. Report the BLOCKED output contract from the reference file and stop.
PASS → proceed to Step 4.1 (Compose Feature Request) with the feasibility assessment appended to the feature request.
Phase 4: Plan
Step 4.1: Compose Feature Request
Build the feature request string for add-new-feature. If --stack was specified, append a "Stack profile" line. If --language is not python, invoke the corresponding language plugin (e.g., /typescript-development:add-new-feature).
Impact Radius requirement: Before composing, extract the Impact Radius from the backlog_view(selector=f"#{issue_number}", summary=false) response. The sections dict in the response contains an "Impact Radius" key (populated by groom-backlog-item Step 3.5). Include it in the feature request so the planner creates tasks for every affected component.
Ecosystem Completeness Constraint: The plan produced by add-new-feature MUST include tasks for every item listed in the Impact Radius, or explicitly document why an item is excluded. A feature is not complete when the core code works — it is complete when:
- Every upstream producer of the changed interface is updated or verified compatible
- Every downstream consumer is migrated to use the new interface
- Every document listed as "will become stale" is updated
- The old interface is deprecated or removed (if this item replaces something)
- CI/config files listed in Impact Radius are updated and validated
If the backlog_view response sections dict has no "Impact Radius" key, trigger groom-backlog-item for that item before continuing (Step 3.1 already handles this for ungroomed items — this handles the case where grooming ran before Step 3.5 existed). Do not skip to Step 4.2 with a missing impact radius — the planner will produce an incomplete plan.
Template: step-procedures.md
Step 4.2: Invoke SAM Planning
Skill(skill: "add-new-feature", args: "{composed feature request}")
This runs the full SAM workflow: discovery, codebase analysis, architecture spec, task decomposition, validation, context manifest.
Step 4.3: Update Backlog with Plan Reference
After add-new-feature completes, identify the task plan it created by calling mcp__plugin_dh_sam__sam_list(search="{slug}") where {slug} is the item title lowercased with spaces replaced by hyphens. The SAM MCP server manages plan storage — do not search the filesystem directly.
Call the mcp__plugin_dh_backlog__backlog_update tool to add the Plan:
| Parameter | Value |
|---|---|
selector |
"{title}" |
plan |
"plan/P{NNN}-{slug}.yaml" (state-relative path) |
If the item has **Issue**: #N, record it in the plan file header comment. Do NOT include Fixes #N, Closes #N, or Resolves #N in task-level commit messages — issue closure is handled exclusively by /complete-implementation in its final commit step.
Step 4.4: Simplify
Run the simplify skill only when source code was modified during this session. Planning-only sessions (plan artifacts, backlog items, documentation) do not need code review.
flowchart TD
Q{"Run: git diff --stat HEAD<br>Any .py .js .ts .cjs .mjs files<br>in the diff?"}
Q -->|"Yes — code was written"| Run["Skill(skill: 'simplify')"]
Q -->|"No — only .md .yaml .json<br>backlog items, plan artifacts"| Skip["Skip — no code to review"]
Step 4.5: Post-Planning Output
- Interactive mode: load
./references/step-procedures.md#step-4-5-post-planning-outputfor the report template. - AUTO_MODE: load
./references/step-procedures.md#step-4-5a-auto-mode-continuationfor the continuation procedure.
Phase 5: Close/Resolve
Step 5.1: Close or Resolve (ADR-9)
Trigger: <mode/> is close or resolve.
close= dismiss without completion. Requiresreason(duplicate, out_of_scope, superseded, wontfix, blocked). Optionalreferenceandcomment. Callsmcp__plugin_dh_backlog__backlog_close.resolve= mark DONE with evidence trail. Requiressummary. Optionalplan,method,notes,follow_ups,findings. Verifies checklist + acceptance criteria before resolving. For items with a**Plan**:field, also checks that thestatus:verifiedGitHub label is present (Step 5.4). Callsmcp__plugin_dh_backlog__backlog_resolve.resolve --force= bypass thestatus:verifiedgate (Step 5.4) and the open-PR gate (Step 5.7) with a warning. Use when label automation failed or when forcing a local-cache resolve while a PR is still open.
Full step-by-step procedure (5.2–5.7): close-resolve-procedure.md
Reference Index
GitHub Integration
GitHub Issues are the source of truth. The backlog MCP server manages local caching — skills interact via MCP tools only. See github-integration.md for step-by-step commands and example sessions. Note: Fixes #N trailers are restricted to the /complete-implementation final commit step only.
setup-github Command
Trigger: <mode/> is setup-github. Full setup procedure and expected output: github-integration.md
Error Handling
See error-handling.md for all error conditions and handling instructions.
Example Sessions
See example-sessions.md for complete examples. GitHub-specific sessions (issue creation, setup-github): github-integration.md
Validation Plan
See validation-plan.md for V1–V6 verification commands and the full integration test sequence.
Didn't find tool you were looking for?