+++ title = "Split archive/closed: archive=done, closed=cancelled" priority = 6 status = "todo" ticket_type = "bug" dependencies = [] +++ ## Problem Currently `nbd archive` sets a ticket's status to `closed`. This conflates two distinct intents: - A ticket that **was completed** and is being retired from the active list - A ticket that **will not be completed** (e.g. cancelled, superseded, won't-fix) ## Desired semantics | Status | Meaning | Resolved (unblocks deps)? | Visible in `nbd list` by default? | |---|---|---|---| | `archived` | Completed and soft-deleted from view | Yes | No | | `closed` | Won't be completed (cancelled/won't-fix) | Yes (avoids deadlock) | No | Both statuses resolve dependencies, so a ticket depending on an `archived` or `closed` ticket becomes unblocked. This matches current behaviour for `closed`. ## Changes required ### `src/ticket.rs` Add `Archived` variant to `Status`: ```rust pub enum Status { #[default] Todo, InProgress, Done, Closed, Archived, // new } ``` Serialises as `"archived"`. ### `src/main.rs` - `parse_status`: add `"archived" => Ok(Status::Archived)` arm and update error message - `cmd_archive`: change `ticket.status = Status::Closed` → `ticket.status = Status::Archived` - `cmd_list`: exclude `Status::Archived` alongside `Done` and `Closed` in the default filter path - `cmd_ready` / `cmd_next`: treat `Status::Archived` as resolved (count it in `done_ids`) - Update the `Archive` command docstring to say it sets status to `archived` not `closed` ### `src/display.rs` - `status_str`: add `Status::Archived => "archived"` arm ### `src/graph.rs` - `status_str` (internal helper): add `Status::Archived => "archived"` arm ### README.md - Update the Status table to show `archived` as a valid status - Update `nbd archive` description to say it sets status to `archived` - Update the note about `archived` vs `closed` semantics ### CLAUDE.md - Update CLI Interface block to include `archived` in valid status values - Update `nbd archive` description ### `src/tests.rs` / `tests/integration.rs` - Update any test that checks `status == "closed"` after `nbd archive` → expect `"archived"` instead - Add test: `nbd archive ` produces `"archived"` status - Add test: a ticket with `status=closed` (manually set) is also excluded from list by default and treated as resolved ## Migration concern Existing tickets on disk that have `status: "closed"` set by previous `nbd archive` calls will retain `closed` status. This is acceptable — `closed` remains a valid status. Users who want to distinguish can `nbd update --status archived` on historical tickets, or run `nbd migrate` once the schema is updated. ## Validation ```sh cargo fmt && cargo check && cargo clippy && cargo test cargo run -- create --title "Test archive" --json | jq -r '.id' | xargs -I{} cargo run -- archive {} --json # → status should be "archived" cargo run -- create --title "Cancelled ticket" --json | jq -r '.id' | xargs -I{} cargo run -- update {} --status closed --json # → status should be "closed" ```