Symptom
Working through M001 of an llm-wiki project: I picked 5 backlog items from .ytstack/backlog/, scoped them into M001-CONTEXT.md, planned 3 slices, executed all of them, and finished the milestone. The implementations shipped, but the original 5 backlog files (clippings-sweep.md, engine-layout-cleanup.md, install-symlink-skills.md, wiki-config.md, plus partial cleanup-followups.md) stayed in `.ytstack/backlog/` until I noticed and swept them manually.
A fresh `ytstack:resume-session` after that point would still surface those items as candidates, even though they're done. The roadmap looks heavier than it is.
Where the workflow currently has the gap
summarize-task updates STATE.md and M###-S##-PLAN.md checkboxes — but doesn't know which backlog files seeded the slice.
reassess-roadmap reviews whether the milestone roadmap still fits reality — but operates at slice boundaries and doesn't sweep backlog/.
plan-milestone references which backlog items the milestone covers (in M###-CONTEXT.md "Scope") — that's where the linkage exists, but it's prose, not a tracked relationship.
So the only authoritative record of "which backlog items did this milestone consume" is buried in M###-CONTEXT.md prose. Nothing automatic checks it on milestone close.
What I'd want
When a milestone hits "done" (last slice closes), one of:
reassess-roadmap post-final-slice asks: "Backlog items folded into this milestone (per M###-CONTEXT scope): [list]. Move to a done/ archive, delete, or keep with a status: done marker?"
plan-milestone writes a structured front-matter field (e.g. consumes_backlog: [clippings-sweep, engine-layout-cleanup, ...]) so milestone-completion has a machine-readable source-of-truth, then a milestone-close skill (or the existing summarize-task for the last task) sweeps based on that field.
- A new tiny skill
sweep-backlog the operator runs at will, that re-reads M###-CONTEXT.md, parses the scope items, and prompts per-item.
Option 2 is probably the most disciplined; option 1 is the smallest change.
Either way, the prompt at sweep time should distinguish:
- Fully shipped → delete the backlog file (the milestone artifacts are the audit trail)
- Partially shipped, deferred → trim the file to only the deferred parts (this is what I had to do for
cleanup-followups.md after M001)
- Re-scoped / dropped → delete with a note in DECISIONS.md
Where this surfaced
llm-wiki, M001 close on 2026-05-02. The cleanup is in lx-0/llm-wiki@2ad825e — manual, repeatable, but the kind of step a workflow tool should remind the operator about so it isn't forgotten.
Related to (but distinct from) M010's "brownfield-detect-analyze-migrate" thread — this is the closing end of the same workflow loop, where ytstack is the source of truth and needs to keep its own backlog tidy.
Severity
Low/UX. Doesn't break anything; just lets the backlog stay louder than it should. Easy to fix opportunistically next time the planning skills get a touch.
Symptom
Working through M001 of an llm-wiki project: I picked 5 backlog items from
.ytstack/backlog/, scoped them into M001-CONTEXT.md, planned 3 slices, executed all of them, and finished the milestone. The implementations shipped, but the original 5 backlog files (clippings-sweep.md,engine-layout-cleanup.md,install-symlink-skills.md,wiki-config.md, plus partialcleanup-followups.md) stayed in `.ytstack/backlog/` until I noticed and swept them manually.A fresh `ytstack:resume-session` after that point would still surface those items as candidates, even though they're done. The roadmap looks heavier than it is.
Where the workflow currently has the gap
summarize-taskupdatesSTATE.mdandM###-S##-PLAN.mdcheckboxes — but doesn't know which backlog files seeded the slice.reassess-roadmapreviews whether the milestone roadmap still fits reality — but operates at slice boundaries and doesn't sweep backlog/.plan-milestonereferences which backlog items the milestone covers (inM###-CONTEXT.md "Scope") — that's where the linkage exists, but it's prose, not a tracked relationship.So the only authoritative record of "which backlog items did this milestone consume" is buried in
M###-CONTEXT.mdprose. Nothing automatic checks it on milestone close.What I'd want
When a milestone hits "done" (last slice closes), one of:
reassess-roadmappost-final-slice asks: "Backlog items folded into this milestone (per M###-CONTEXT scope): [list]. Move to adone/archive, delete, or keep with astatus: donemarker?"plan-milestonewrites a structured front-matter field (e.g.consumes_backlog: [clippings-sweep, engine-layout-cleanup, ...]) so milestone-completion has a machine-readable source-of-truth, then a milestone-close skill (or the existingsummarize-taskfor the last task) sweeps based on that field.sweep-backlogthe operator runs at will, that re-readsM###-CONTEXT.md, parses the scope items, and prompts per-item.Option 2 is probably the most disciplined; option 1 is the smallest change.
Either way, the prompt at sweep time should distinguish:
cleanup-followups.mdafter M001)Where this surfaced
llm-wiki, M001 close on 2026-05-02. The cleanup is in lx-0/llm-wiki@2ad825e — manual, repeatable, but the kind of step a workflow tool should remind the operator about so it isn't forgotten.
Related to (but distinct from) M010's "brownfield-detect-analyze-migrate" thread — this is the closing end of the same workflow loop, where ytstack is the source of truth and needs to keep its own backlog tidy.
Severity
Low/UX. Doesn't break anything; just lets the backlog stay louder than it should. Easy to fix opportunistically next time the planning skills get a touch.