tickets(nbd): triage TODO.md → 818598 scope next/ready by subtree
- 818598: Scope nbd next and nbd ready by dependency subtree Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>quotesdb
parent
7e0ba78240
commit
3c0665314a
@ -0,0 +1,102 @@
|
||||
+++
|
||||
title = "Scope nbd next and nbd ready by dependency subtree"
|
||||
priority = 5
|
||||
status = "todo"
|
||||
ticket_type = "feature"
|
||||
dependencies = []
|
||||
+++
|
||||
## Summary
|
||||
|
||||
Add an optional positional `<id>` argument to `nbd next` and `nbd ready` that scopes
|
||||
the results to the dependency subtree of the given ticket.
|
||||
|
||||
## Motivation
|
||||
|
||||
When a project has many tickets, you often want to focus on tickets that directly
|
||||
unblock a specific goal ticket. Currently `nbd next` and `nbd ready` operate over
|
||||
the entire ticket store, with no way to narrow by project/feature scope except
|
||||
through `--filter` expressions that don't understand the dependency graph.
|
||||
|
||||
## Desired behaviour
|
||||
|
||||
```sh
|
||||
# Highest-priority ready ticket that is a dependency of abc123 (directly or transitively)
|
||||
nbd next abc123
|
||||
nbd next abc123 --json
|
||||
|
||||
# All ready tickets that are dependencies of abc123 (directly or transitively)
|
||||
nbd ready abc123
|
||||
nbd ready abc123 --json
|
||||
|
||||
# Both commands still accept --filter alongside the scoping ID
|
||||
nbd next abc123 --filter type=bug
|
||||
nbd ready abc123 --filter priority=8
|
||||
```
|
||||
|
||||
The root ticket itself (abc123) is *not* included in the results — only its
|
||||
dependencies (the tickets it is waiting on).
|
||||
|
||||
## Implementation plan
|
||||
|
||||
### 1. CLI changes (`src/main.rs`)
|
||||
|
||||
In `Commands::Next` and `Commands::Ready`, add an optional positional argument:
|
||||
|
||||
```rust
|
||||
id: Option<String>, // Optional ticket ID or prefix to scope results
|
||||
```
|
||||
|
||||
Update `dispatch` to pass the new argument to `cmd_next` and `cmd_ready`.
|
||||
|
||||
Update the CLI doc-comments for both subcommands to mention the scoping
|
||||
behaviour.
|
||||
|
||||
### 2. Logic changes (`src/main.rs`)
|
||||
|
||||
In `cmd_next` and `cmd_ready`, after loading all tickets, if `scope_id` is
|
||||
`Some`:
|
||||
|
||||
1. Resolve the prefix to a full ID using `resolve_id`.
|
||||
2. Build a `TicketGraph` from all tickets (the full list, not filtered).
|
||||
3. Call `graph.subtree(&resolved_id)` to get the set of all dependency IDs
|
||||
reachable from the root (this already excludes the root itself when it is
|
||||
not in its own dependency list).
|
||||
4. Convert the subtree IDs into a `HashSet`.
|
||||
5. Restrict the ready/next candidate pool to tickets whose ID is in that set
|
||||
*and* whose ID is not the scoping ticket itself (the root should never be
|
||||
returned as a "what to do next" result when it is the scope target).
|
||||
|
||||
`TicketGraph::subtree` is already implemented in `src/graph.rs` and handles
|
||||
cycles correctly via a visited set.
|
||||
|
||||
### 3. Test coverage (`tests/integration.rs`)
|
||||
|
||||
Add integration tests (using `tempdir`):
|
||||
|
||||
- **`test_next_scoped_by_id`**: create a project ticket P with deps [A, B],
|
||||
where A has dep [C]. Mark C as done. Verify `nbd next P` returns A (the
|
||||
highest-priority ready dep of P), not P itself or any unrelated ticket.
|
||||
- **`test_ready_scoped_by_id`**: same setup; verify `nbd ready P` returns
|
||||
[A] (B is blocked because... actually B has no deps so it's also ready).
|
||||
Adjust setup so exactly the expected set is returned.
|
||||
- **`test_next_scoped_no_ready`**: all deps of P are done; verify `nbd next P`
|
||||
returns no ticket (`{"next": null}` in JSON mode).
|
||||
- **`test_ready_scoped_with_filter`**: verify `--filter` still narrows within
|
||||
the scoped set.
|
||||
|
||||
### 4. Relevant files
|
||||
|
||||
| File | Change |
|
||||
|---|---|
|
||||
| `src/main.rs:135-156` | `Commands::Ready` and `Commands::Next` — add `id: Option<String>` |
|
||||
| `src/main.rs:308-310` | `dispatch` arms for `Next` and `Ready` — pass new arg |
|
||||
| `src/main.rs:473-511` | `cmd_ready` — add subtree scoping logic |
|
||||
| `src/main.rs:522-566` | `cmd_next` — add subtree scoping logic |
|
||||
| `src/graph.rs:165-172` | `TicketGraph::subtree` — already correct, no change needed |
|
||||
| `tests/integration.rs` | Add 4 new scoped-by-id tests |
|
||||
|
||||
### 5. Validation
|
||||
|
||||
```sh
|
||||
cargo fmt && cargo check && cargo clippy && cargo test
|
||||
```
|
||||
Loading…
Reference in New Issue