4.6 KiB
title, category, date, tags, related_components, problem_type
| title | category | date | tags | related_components | problem_type | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Status-gated todo resolution: making pending/ready distinction load-bearing | workflow | 2026-03-24 |
|
|
correctness-gap |
Status-Gated Todo Resolution
Problem
The todo system defines a three-state lifecycle (pending -> ready -> complete) across three skills (todo-create, todo-triage, todo-resolve). Different sources create todos with different status assumptions:
| Source | Status created | Reasoning |
|---|---|---|
ce:review (autofix mode) |
ready |
Built-in triage: confidence gating (>0.60), merge/dedup across 8 personas, owner routing. Only creates todos for downstream-resolver findings |
todo-create (manual) |
pending (default) |
Template default |
test-browser, test-xcode |
via todo-create |
Inherit default |
todo-resolve was resolving ALL todos regardless of status. This meant untriaged, potentially ambiguous findings could be auto-implemented without human review. The pending/ready distinction was purely cosmetic -- dead metadata that nothing branched on.
Root Cause
The status field was defined in the schema but never enforced at the resolve boundary. todo-resolve loaded every non-complete todo and attempted to fix it, collapsing the intended pending -> triage -> ready -> resolve pipeline into a flat "resolve everything" approach.
Solution
Updated todo-resolve to partition todos by status in its Analyze step:
ready(status field or-ready-in filename): resolve thesepending: skip entirely, report at end with hint to run/todo-triagecomplete: ignore
This is a single-file change scoped to todo-resolve/SKILL.md. No schema changes, no new fields, no changes to todo-create or todo-triage -- just enforcement of the existing contract at the resolve boundary.
Key Insight: No Automated Source Creates pending Todos
No automated source creates pending todos. The pending status is exclusively a human-authored state for manually created work items that need triage before action.
The safety model becomes:
ready= autofix-eligible. Triage already happened upstream (either built into the review pipeline or via explicit/todo-triage).pending= needs human judgment. Either manually created or from a legacy review path.
This makes auto-resolve safe by design: the quality gate is upstream (in the review), not at the resolve boundary.
Prevention Strategies
Make State Transitions Load-Bearing, Not Advisory
If a state field exists, at least one downstream consumer must branch on it. If nothing branches on the value, the field is dead metadata.
- Gate on state at consumption boundaries. Any skill that reads todos must partition by status before processing.
- Require explicit skip-and-report. Silent skipping is indistinguishable from silent acceptance. When a skill filters by state, it reports what it filtered out.
- Default-deny for new statuses. If a new status value is added, existing consumers should skip unknown statuses rather than process everything.
Dead-Metadata Detection
When reviewing a skill that defines a state field, ask: "What would change if this field were always the same value?" If the answer is "nothing," the field is dead metadata and either needs enforcement or removal. This is the exact scenario that produced the original issue.
Producer Declares Consumer Expectations
When a skill creates artifacts for downstream consumption, it should state which downstream skill processes them and what state precondition that skill requires. The inverse should also hold: consuming skills should state what upstream flows produce items in the expected state.
Cross-References
- beta-promotion-orchestration-contract.md -- promotion hazard: if mode flags are dropped during promotion, the wrong artifacts are produced upstream
- compound-refresh-skill-improvements.md -- "conservative confidence in autonomous mode" principle that motivates status enforcement
- claude-permissions-optimizer-classification-fix.md -- "pipeline ordering is an architectural invariant" pattern; the same concept applies to the review -> triage -> resolve pipeline