deps: a CLI verb to remove a single dependency edge - #109
Merged
Conversation
`remove_dep` has been kind-aware since the deps-key change, but no verb reached it, so an edge authored by mistake — a `related` typed where `blocks` was meant, a `discovered-from` linking the wrong parent — was removable only with raw SQL against the database. `--blocked-by` could clear the blocker set wholesale, which left every other kind, and the ability to drop one edge of a pair carrying two, with no spelling at all. `voro set <id> --unlink <kind>:<other-id>` names one edge in the direction `show` prints it — the edge belongs to the task being edited — and drops exactly that one. The flag repeats for several. The echo reads the kind the way `show` does (`no longer blocked by #9`, never the kind backwards), and because dropping a blocker reconciles readiness in the store, the promotion that can follow is echoed beside it, symmetrically with `--blocks`' demotion echo; the trailing state is read back after the edit rather than reported from before it. No core logic changed: the store call and its refusal of an absent edge already existed. Covered at the CLI level — one kind of a pair surviving the other's removal, the refusal, the promotion, and the deliberate non-promotion when the last blocker goes (a parked task with no blockers is deferred by choice, DESIGN.md §5, so `unpark` stays the manual escape). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DxkK1vKA77ewc7vgnRTT9R
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
remove_dephas been kind-aware since the deps-key change (task 311), but noCLI verb reached it, so an edge authored by mistake — a
relatedtyped whereblockswas meant, adiscovered-fromlinking the wrong parent — wasremovable only with raw SQL against the database.
--blocked-bycould clearthe blocker set wholesale, which left every other kind, and the ability to
drop one edge of a pair carrying two, with no spelling at all.
What changed
voro set <id> --unlink <kind>:<other-id>drops exactly one dependency edge.The edge is named in the direction
voro showprints it — it belongs to thetask being edited — so
set 2 --unlink blocks:1removes whatshow 2listsas
dep: blocked by #1, andset 2 --unlink discovered-from:1removes theprovenance edge beside it without touching the blocker. The flag repeats for
several edges in one call.
The echo reads the kind the way
showdoes —task 2 no longer blocked by #1, never the kind backwards — and because dropping a blocker reconcilesreadiness in the store, the promotion that can follow is echoed beside it
(
— #3 promoted to ready), symmetrically with how--blocksechoes itsdemotion. The trailing
task N updated (state)is read back after the editrather than reported from before it, so a promotion is not printed as
(parked).Naming an edge that is not there fails with the store's own message
(
#2 has no related dependency on #1) rather than reporting a success it didnot perform; an unknown kind and a malformed
KIND:IDfail in the parser.No core logic changed — the store call and its refusal already existed. This
is CLI surface, its help text, and tests.
docs/DESIGN.md§5 gains a clausenaming the operator-facing spelling beside the store semantics it already
described; the
voro-cliskill and the changelog document the flag.A behaviour worth naming
Unlinking the last blocker leaves the task parked. That is DESIGN.md §5 as
written — a parked task with no blockers is deliberately deferred, and
auto-promotion applies only to parked tasks that have blockers — and it is
exactly what
--blocked-bywith an empty set already does, since both gothrough
reconcile_readiness.unparkremains the manual escape. Pinned withits own test so the asymmetry is deliberate rather than discovered later.
Verification
cargo test --workspacepasses (273 tests, 5 new),cargo clippy --workspace --all-targets -- -D warningsclean,cargo fmt --allapplied. Also smoke-runagainst a scratch database: authored a
discovered-from+blockspair withpropose --fromandset --blocked-by, unlinked the blocker, confirmedshowstill listsdep: discovered-from 1alone, and confirmed the absentrelated:1edge fails with the store's message and a non-zero exit.The new CLI tests cover each acceptance criterion: one kind of a pair
surviving the other's removal (both directions), the refusal on an absent
edge with the surviving edge intact, readiness reconciling on a
blocksremoval, the deliberate non-promotion above, and the repeated flag.