devague plan depend <tN> --on <tM> adds a dependency. Nothing removes one.
$ devague plan depend --help
usage: devague plan depend [-h] --on ON [--plan PLAN] [--json] id
--on ON The task id it depends on.
No --remove, no undepend, and the move list (task, accept, depend, cover, confirm, reject, risk, converge, export, waves, status, show, list) has no other escape hatch. Once tN depends on tM, that edge is permanent for the life of the task.
Why that's a problem
reject is the sanctioned way to drop a task — but the gate then refuses to converge because a surviving task still points at the rejected one, and there is no move to cut the edge:
$ devague plan reject t8 # t8's acceptance criteria were wrong
t8 -> rejected
$ devague plan task "..." --dep t4 --dep t6 --dep t7 # t10 = corrected replacement
added t10 (proposed)
$ devague plan depend t9 --on t10 # point t9 at the replacement
t9 depends on t10
$ devague plan converge
not converged:
- task t9 depends on rejected task t8 # <-- the old edge is unremovable
t9 now depends on both t8 (rejected, unremovable) and t10. The only way out is to reject t9 too and recreate it as t11 — re-typing its summary, every acceptance criterion, every --covers target and its instruction, purely to shed one stale edge. Any task depending on t9 would cascade the same way.
Why it bites harder than it looks
Revising a task is the normal case, not an edge case. Mine came from a real correction: the user changed the intent of a task (a role that must stay served-but-known-incorrect rather than be declared unavailable), which changed its acceptance criteria. accept only adds criteria — it can't replace a wrong one — so reject-and-recreate is already the prescribed path for that. But reject-and-recreate is precisely what the frozen dependency edge punishes.
The two gaps compose into a cascade: you can't edit a task's criteria, so you must recreate it; you can't drop a dependency, so recreating it forces you to recreate its dependents too. In a deep graph that's an unbounded rewrite for a one-word correction.
Suggested fix
Any one of these breaks the cascade; the first is the smallest:
devague plan depend <tN> --remove <tM> (or --on <tM> --remove) — cut a single edge.
reject prunes edges pointing at the rejected task, so a rejected task can't strand a live one. (Arguably the right default: a rejected task is not a real dependency.)
- An
amend/edit move for a task's summary + acceptance criteria, so correcting a task doesn't require reject-and-recreate in the first place. This one also fixes the other half of the cascade.
Relatedly, accept <tN> "<crit>" can only append — there's no way to remove or replace an acceptance criterion, which is what makes reject-and-recreate the only route for a corrected task. (3) would cover both.
Found while running /spec-to-plan on agentculture/lobes-cli (per-machine hardware profiles plan). Companion to #67.
devague plan depend <tN> --on <tM>adds a dependency. Nothing removes one.No
--remove, noundepend, and the move list (task,accept,depend,cover,confirm,reject,risk,converge,export,waves,status,show,list) has no other escape hatch. OncetNdepends ontM, that edge is permanent for the life of the task.Why that's a problem
rejectis the sanctioned way to drop a task — but the gate then refuses to converge because a surviving task still points at the rejected one, and there is no move to cut the edge:t9now depends on botht8(rejected, unremovable) andt10. The only way out is to rejectt9too and recreate it ast11— re-typing its summary, every acceptance criterion, every--coverstarget and its instruction, purely to shed one stale edge. Any task depending ont9would cascade the same way.Why it bites harder than it looks
Revising a task is the normal case, not an edge case. Mine came from a real correction: the user changed the intent of a task (a role that must stay served-but-known-incorrect rather than be declared unavailable), which changed its acceptance criteria.
acceptonly adds criteria — it can't replace a wrong one — so reject-and-recreate is already the prescribed path for that. But reject-and-recreate is precisely what the frozen dependency edge punishes.The two gaps compose into a cascade: you can't edit a task's criteria, so you must recreate it; you can't drop a dependency, so recreating it forces you to recreate its dependents too. In a deep graph that's an unbounded rewrite for a one-word correction.
Suggested fix
Any one of these breaks the cascade; the first is the smallest:
devague plan depend <tN> --remove <tM>(or--on <tM> --remove) — cut a single edge.rejectprunes edges pointing at the rejected task, so a rejected task can't strand a live one. (Arguably the right default: a rejected task is not a real dependency.)amend/editmove for a task's summary + acceptance criteria, so correcting a task doesn't require reject-and-recreate in the first place. This one also fixes the other half of the cascade.Relatedly,
accept <tN> "<crit>"can only append — there's no way to remove or replace an acceptance criterion, which is what makes reject-and-recreate the only route for a corrected task. (3) would cover both.Found while running
/spec-to-planonagentculture/lobes-cli(per-machine hardware profiles plan). Companion to #67.