Fact-Check
Date: 2026-02-27 Claims checked: 4
| # | Claim | Verdict | Evidence |
|---|---|---|---|
| 1 | Per-item files have plan: N/A set on completed items | VERIFIED | 22 backlog files have plan: N/A in frontmatter, all with status: done |
| 2 | Step 2 treats N/A as a valid plan path and stops | VERIFIED | work-backlog-item/SKILL.md:199-205 checks plan field truthiness; "N/A" is truthy |
| 3 | All items with plan: N/A are status: done | VERIFIED | All 22 files confirmed status: done, priority: completed |
| 4 | Description says 22 items | VERIFIED | Count is 22 (23rd grep match is bug report description text, not frontmatter) |
Summary: VERIFIED: 4 | REFUTED: 0 | INCONCLUSIVE: 0
RT-ICA
Goal: Prevent work-backlog-item Step 2 from treating "N/A" plan values as valid plan paths.
| # | Condition | Status | Info |
|---|---|---|---|
| 1 | Bug location identified | AVAILABLE | backlog.py:260 builds plan field; work-backlog-item/SKILL.md:199-205 checks it |
| 2 | Root cause understood | AVAILABLE | str("N/A") is truthy, treated as valid path |
| 3 | Fix strategy clear | AVAILABLE | Strip N/A during parsing OR add guard in Step 2; both viable |
| 4 | Files affected by fix identified | DERIVABLE | backlog.py (parsing), work-backlog-item/SKILL.md (Step 2 logic), or both |
| 5 | Regression scope known | AVAILABLE | 22 items with plan: N/A, all status:done |
| 6 | Test approach defined | DERIVABLE | Verify backlog list JSON output for plan field handling |
| 7 | Interaction with close/update/sync | DERIVABLE | Check if close also sets plan: N/A |
Decision: APPROVED Missing: None — all conditions AVAILABLE or DERIVABLE
Groomed (2026-02-27)
Reproducibility
- Run
uv run .claude/skills/backlog/scripts/backlog.py list --format json - Filter results for items with
status: doneorstatus: resolved - Note items with
plan: "N/A"in JSON output - Invoke
/work-backlog-itemwith title of one of these items - Observe Step 2 checks
if plan field is truthy(SKILL.md line 199-205) - Confirm false-positive: "This item already has a plan at N/A"
Output / Evidence
backlog.pyline 260:item["**Plan**"] = str(meta.get("plan") or fm.get("plan") or "")- Converts
plan: N/Ato string"N/A", which is truthy in Python
- Converts
backlog.pyline 1003:_update_item_metadata(..., {"metadata": {"status": "done", ... "plan": plan}})- Explicitly sets
plan: N/Awhen closing items
- Explicitly sets
work-backlog-item/SKILL.mdlines 199-205: checksif plan field is truthywithout filtering out"N/A"- Current barrier: 22 items with
plan: N/Aall havestatus: done, so they're filtered at JSON stage; latent bug surfaces if a completed item gets reopened or a non-completed item receivesplan: N/A
Priority
7/10 — Prevents work-backlog-item from processing items marked done (current safety by accident), but exposes code smell: N/A should normalize to empty, not stringify to truthy value. Low immediate risk (all affected items filtered), moderate debt (confuses workflow state).
Impact
- Blocks: Items with
plan: N/Acannot be reopened and re-planned without manual frontmatter edit - Bottleneck: Design confusion between "completed" (status: done) and "no plan needed" (plan: N/A); both conflate in Step 2 logic
Scope
Two viable fixes (both produce same outcome):
Option A: Normalize in backlog.py parsing (recommended)
- Line 260: Change
str(meta.get("plan") or fm.get("plan") or "")to filterN/Ato empty - Applies globally; all downstream code sees clean data
- Single source of truth
Option B: Guard in work-backlog-item Step 2
- Lines 199-205: Add condition
if plan and plan != "N/A"before stopping - Localized; other skills/agents using backlog.py still receive N/A strings
Output / Evidence
Expected Behavior: When work-backlog-item Step 2 extracts plan field, it should treat "N/A" as "no plan available" (equivalent to empty string), not as a valid plan path.
Acceptance Criteria:
backlog.py list --format jsonon items withplan: N/Areturnsplan: ""(empty string)/work-backlog-itemwith a reopened item does NOT report "plan at N/A"- Existing 22 files with
plan: N/Aare unaffected (status: done) - New items closing without a plan serialize to
plan: ""in JSON
Dependencies
- Depends on: None
- Blocks: None (safe to do independently)
Research
No external research needed. Bug is fully characterized from codebase analysis.
Skills
/work-backlog-item— consumer of the plan field/backlog— manages per-item files and JSON serialization
Agents
None required for fix implementation.
Prior Work
backlog.pylines 260, 1003 — plan field serialization and close logicwork-backlog-item/SKILL.mdlines 199-205 — Step 2 plan guard
Files
.claude/skills/backlog/scripts/backlog.py(lines 260, 1003).claude/skills/work-backlog-item/SKILL.md(lines 199-205)
Decision
APPROVED — Small fix, no blockers. Recommend Option A (normalize at parse time).
Effort
Small — 1-line string filter or 1-line guard condition. ~15 minutes implementation + validation.