What happened
Ran /pm:sync in a repo with 18 files in docs/superpowers/plans/. All 18 were registered as new untriaged epics:
conductor: synced (18 new epic(s) added as untriaged)
Every one of them is completed, shipped work — some from March. Verified by checking that the code each plan describes exists in the repo today (src/brokers/ for the broker-abstraction plan, src/tasks/reminder_*.py for the reminder-system plan, src/operations/repair_agent.py, src/operations/scheduler.py, check_alternative_criteria_sets for the multi-criteria-gate plan, etc.).
Root cause
The engine has no signal for "this plan is done." OpenSpec has changes/archive/ as the done-marker; Superpowers plans have no equivalent convention — plan files just sit in plans/ forever. So sync re-registers every plan on disk, every time.
Contributing factor: the plans' task checkboxes were never ticked on completion (17 of 18 read 0/N complete), so even a checkbox heuristic wouldn't have saved it here. But the checkbox state is user discipline; the engine treating presence of a file as pending work is the actual defect.
Why it matters
This is the same class as the archive-scan bug fixed in 0.19.0 (sync scanning openspec/changes/archive/ and re-registering completed changes), just on the Superpowers-plan path instead of the OpenSpec-archive path. The 0.19.0 fix filtered the archive dir; the plans path has no dir to filter.
Impact is worse than noise: it buried 5 genuinely-queued P0/P1 epics under 18 phantom untriaged ones, and the briefing's "NEXT UP" became unusable. If a user triages rather than investigates, they'd schedule work that shipped months ago.
Suggested fixes (in rough preference order)
- A done-marker convention for plans, mirroring OpenSpec's archive:
docs/superpowers/plans/archive/ (or a Status: COMPLETE frontmatter key), filtered by sync the same way 0.19.0 filters changes/archive/.
- Checkbox heuristic as a secondary signal — if a plan is 100% checked, don't register. Weak alone (see above) but a cheap safety net.
- At minimum, don't silently bulk-add. When
sync would add more than a handful at once, list them and ask before writing. synced (18 new epic(s) added as untriaged) gives no chance to catch this before state.json is rewritten.
Workaround
remove-epic each one. remove-epic exists as of 0.19.0, so cleanup is at least scriptable now — it just shouldn't be necessary.
Environment
- pm engine 0.23.1
- Repo has both
openspec/ and docs/superpowers/plans/
What happened
Ran
/pm:syncin a repo with 18 files indocs/superpowers/plans/. All 18 were registered as new untriaged epics:Every one of them is completed, shipped work — some from March. Verified by checking that the code each plan describes exists in the repo today (
src/brokers/for the broker-abstraction plan,src/tasks/reminder_*.pyfor the reminder-system plan,src/operations/repair_agent.py,src/operations/scheduler.py,check_alternative_criteria_setsfor the multi-criteria-gate plan, etc.).Root cause
The engine has no signal for "this plan is done." OpenSpec has
changes/archive/as the done-marker; Superpowers plans have no equivalent convention — plan files just sit inplans/forever. Sosyncre-registers every plan on disk, every time.Contributing factor: the plans' task checkboxes were never ticked on completion (17 of 18 read
0/Ncomplete), so even a checkbox heuristic wouldn't have saved it here. But the checkbox state is user discipline; the engine treating presence of a file as pending work is the actual defect.Why it matters
This is the same class as the archive-scan bug fixed in 0.19.0 (
syncscanningopenspec/changes/archive/and re-registering completed changes), just on the Superpowers-plan path instead of the OpenSpec-archive path. The 0.19.0 fix filtered the archive dir; the plans path has no dir to filter.Impact is worse than noise: it buried 5 genuinely-queued P0/P1 epics under 18 phantom untriaged ones, and the briefing's "NEXT UP" became unusable. If a user triages rather than investigates, they'd schedule work that shipped months ago.
Suggested fixes (in rough preference order)
docs/superpowers/plans/archive/(or aStatus: COMPLETEfrontmatter key), filtered bysyncthe same way 0.19.0 filterschanges/archive/.syncwould add more than a handful at once, list them and ask before writing.synced (18 new epic(s) added as untriaged)gives no chance to catch this before state.json is rewritten.Workaround
remove-epiceach one.remove-epicexists as of 0.19.0, so cleanup is at least scriptable now — it just shouldn't be necessary.Environment
openspec/anddocs/superpowers/plans/