Replace stub with full prose covering the stationary equation,
long-run frequency interpretation, irreducibility and aperiodicity,
a worked 2×2 analytical solution for the weather chain, and a power
iteration pseudocode + Rust sketch.
Replaces the stub with full lesson content:
- Defines the transition matrix P[i][j] and stochastic matrix constraints
- Derives multi-step probabilities via π_k = π₀ · P^k
- Works through the 2-state weather chain by hand (1- and 2-step calculations)
- Bridges to §9 stationary distributions
- Words as states paragraph
- Bigrams and transition tables explanation
- Worked bigram example with two-sentence corpus and transition table
- Why generated text sounds locally plausible but globally incoherent
- Order-n chains and the coherence/novelty tradeoff
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Migrate async runtime from async-std to tokio (required by libsql),
then add a mtime-based libsql cache at .nbd/cache.db that accelerates
nbd list, nbd ready, and nbd next by avoiding redundant file reads.
- Cargo.toml: replace async-std with tokio + libsql = "0.6"
- src/store.rs: async_std → tokio fs API; add open_cache() and
list_tickets_cached() with fallback to list_tickets on error
- src/main.rs: tokio::main, tokio::fs::remove_file; wire cmd_list,
cmd_ready, cmd_next to list_tickets_cached
- src/tests.rs: async_std::test → tokio::test, async_std::fs → tokio::fs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The [cycle] label was misleading — a node marked this way is not
necessarily in a true cycle, it is simply a shared dependency appearing
in multiple branches of the tree. The `*` marker is more neutral and
concise.
Changes: render_node in display.rs, test in tests.rs, README.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ensures every command in the embedded snippet uses --json for structured
output, consistent with the guideline at the bottom of the snippet.
Also adds --json to nbd ready and nbd next, and --ftype md to the create
workflow step.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
build.rs captures the short git SHA at compile time via
`git rev-parse --short HEAD` and emits it as GIT_SHORT_SHA. Falls back
to "unknown" when git is unavailable (e.g. Nix sandboxed builds).
main.rs adds a VERSION const (`env!("CARGO_PKG_VERSION") + "+" + SHA`)
and passes it to clap's `version =` attribute, enabling both -V and
--version flags.
Example output: `nbd 0.1.0+8f4d25b`
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the key-value table format with TOML frontmatter + body when
printing tickets to stdout (nbd read, nbd create, nbd archive, nbd next
— all non-JSON paths). The --json output is unchanged.
New format:
+++
id = "a3f9c2"
title = "Fix login bug"
priority = 8
status = "in_progress"
ticket_type = "bug"
dependencies = ["b7d41e"]
+++
Body text here.
Changes:
- display.rs: add DisplayFrontmatter struct, rewrite format_ticket using
toml::to_string with id prepended as first frontmatter key
- tests.rs: update format_ticket_joins_dependencies and
format_ticket_empty_dependencies for the new format
- integration.rs: update TestEnv::create to use --json for reliable
ID extraction instead of parsing the key-value text format
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`nbd archive` now sets status to `archived` (completed, soft-deleted)
instead of `closed`. The `closed` status is reserved for tickets that
will not be completed (cancelled, superseded, won't-fix).
Both statuses count as resolved for dependency purposes and are excluded
from `nbd list`, `nbd ready`, and `nbd next` by default.
Changes:
- Add `Status::Archived` variant (serialises as "archived")
- `cmd_archive`: sets `Status::Archived` instead of `Status::Closed`
- `parse_status`: add "archived" arm
- `cmd_list`, `cmd_ready`, `cmd_next`: exclude/resolve `Archived`
- `display`, `graph`, `filter`: add `Archived` arm to `status_str`
- Tests: rename/update archive tests, add archived/closed test variants
- Docs: update README.md and CLAUDE.md status tables and descriptions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a new `backlog` Status variant for tickets that are created but
intentionally deferred. Backlog tickets are excluded from `nbd list`,
`nbd ready`, and `nbd next` by default, but unlike `done` and `closed`
they do not count as resolved for dependency purposes — a ticket whose
dependency is `backlog` remains blocked.
Visible via `--all` or `--filter status=backlog`.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add flake.nix so nbd can be consumed as a reproducible Nix package.
Exposes packages.default, apps.default (nix run), and a devShell with
stable Rust toolchain and the nbd binary. Uses cargoLock for
dependency hashing without a pre-computed cargoHash.
Also adds an Installation section to README.md covering nix run and
nix build usage.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When `nbd update` is run without `--json`, print a git-diff-style
+/- summary of changed fields instead of the full ticket.
- Add `format_diff` and `print_diff` to display.rs
- Capture `old` ticket snapshot in `cmd_update` before mutations
- Use `print_diff` for the non-JSON branch of `cmd_update`
- Add unit tests (4) and integration tests (3) covering diff output,
JSON fallback, and the no-changes case
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wires up the graph command in main.rs with cmd_graph(). Supports
full dependency forest (nbd graph), subtree by ID/prefix (nbd graph
<id>), --filter narrowing, and --json machine-readable output. Fixes
tree-rendering indentation bug (child_base vs prefix separation).
Updates README.md and CLAUDE.md with graph command documentation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements TicketGraph<'a> with build(), roots(), subtree(),
to_json_value(), and to_subtree_json_value(). Tracks both forward
(dependencies) and reverse (dependents) edges. Cycle-safe DFS via
visited set. No new crate dependencies. 14 unit tests covering empty
graph, chains, branching, cycles, dangling refs, and JSON output.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update CLAUDE.md workflow guidance and the claude_md_snippet to always
use --ftype md on nbd create, so ticket bodies are stored as
human-readable markdown files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tickets can now be stored in four formats, selected with --ftype:
json (.json) — pretty-printed JSON, default, unchanged
md (.md) — Markdown body with TOML frontmatter
toml (.toml) — full TOML
jsonb (.jsonb) — CBOR binary via ciborium
Changes:
- store.rs: FileFormat enum, detect_format(), find_ticket_path(),
per-format serialize/deserialize helpers; read_ticket/list_tickets/
resolve_id/migrate_tickets all scan all known extensions
- main.rs: --ftype on create (default "json") and update (optional,
converts format and removes old file); archive/update preserve
existing format when --ftype is absent
- tests.rs: update write_ticket/ticket_path call sites; add TOML,
Markdown, and CBOR roundtrip unit tests
- integration.rs: 8 new format tests covering create, list, update
conversion, format preservation, body roundtrip, unknown-ftype error
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds `nbd claude-md` subcommand that prints a ready-to-paste CLAUDE.md
snippet for adopting nbd in any project. The snippet is embedded at
compile time via `include_str!` from `src/claude_md_snippet.md`, so it
stays in sync with the installed binary automatically.
- `nbd claude-md` prints raw markdown (suitable for `>> CLAUDE.md`)
- `nbd claude-md --json` outputs `{"snippet": "..."}` for programmatic use
- Works without a `.nbd/` store present (no find_nbd_root call)
- 4 new integration tests covering all specified behaviours
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Status::Closed variant serialised as "closed", providing a
soft-delete for tickets that should be hidden from normal listings.
- nbd archive <id>: sets status to closed (sugar for update --status closed)
- nbd list: excludes closed tickets by default (same as done)
- nbd list --all: bypasses default status exclusion, shows everything
- nbd list --filter status=closed: shows only closed tickets
- Closed tickets count as resolved for dependency purposes (unblock dependents)
- nbd ready / nbd next: closed tickets excluded from actionable set
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds `nbd next` which selects the single highest-priority ready ticket.
Supports `--filter` narrowing, `--json` output as `{"next": ...}` or
`{"next": null}` when nothing is ready. Makes `ticket_to_json_value`
pub(crate) for reuse. Adds 7 integration tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nbd list now hides done tickets unless the caller explicitly provides a
status filter. Pass --filter status=* to see all tickets or
--filter status=done to see only completed ones.
- Add matches_status and matches_except_status to TicketFilter
- Update cmd_list to apply implicit done-exclusion when no status filter given
- Update List command help text
- Add unit tests for new filter methods
- Add integration tests for the new default behaviour
- Update README usage section
Add repeatable --filter KEY=VALUE option to nbd list, nbd ready, and
nbd migrate. Filters are parsed into a TicketFilter and applied in each
command handler. Different keys are ANDed; same key with multiple values
is ORed; values support glob wildcards.
- store: add skipped field to MigrateReport; migrate_tickets accepts
a &TicketFilter and skips non-matching tickets
- display: format_migrate_report shows optional Skipped line;
format_migrate_report_json includes skipped key
- filter: suppress dead_code on is_empty/has_status_filter (public API
reserved for future done-exclusion feature)
- tests: update MigrateReport literals and migrate_tickets call sites;
add unit tests for skipped formatting; add 14 integration tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add src/filter.rs with TicketFilter struct, parse_filters(), and a
hand-rolled glob_matches() function supporting * wildcards. Different
keys are ANDed; same key, multiple values are ORed. Status and type
matching is case-insensitive; priority and title are case-sensitive.
Adds 21 unit tests covering glob edge cases, AND/OR semantics,
is_empty(), and has_status_filter().
- Add nbd init and nbd ready to the CLI Interface reference
- Replace mkdir workaround with `cargo run -- init` in Task Tracking
- Restore the --json guideline to its original wording
- Add `nbd ready` as the preferred "what to work on next" command
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- `nbd init` creates `.nbd/tickets/` in cwd (idempotent, no find_nbd_root)
- `nbd ready` lists actionable tickets: not done with all deps completed
- Both commands support `--json` for machine-readable output
- 6 new integration tests covering init and ready behaviour
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add `resolve_id` to `store.rs` that resolves a full ticket ID from an
exact match or a unique prefix (like git short-SHA resolution). Use it
in `cmd_read`, `cmd_update`, and `validate_deps` so all three accept
short prefixes. Ambiguous prefixes produce an error listing all matches.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds `nbd migrate` to bring ticket files on disk into conformance with
the current serde schema. Re-serialises every *.json file through the
current Ticket model — removing stale fields (e.g. old \"id\" key),
adding new fields with their defaults, and normalising formatting.
- store: MigrateReport struct and migrate_tickets() function
- display: format/print_migrate_report and _json variants
- main: Migrate command with --dry-run flag and cmd_migrate handler
- 6 unit tests (rewrites old format, already-current, dry-run, invalid JSON, empty store, no tickets dir)
- 4 integration tests (rewrite, dry-run, parse error tolerance, --json output)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The ticket id is now stored only in the filename stem (.nbd/tickets/{id}.json).
`id` is annotated with `#[serde(skip)]` so it is never written to disk,
eliminating the consistency hazard of id-in-body vs. filename disagreement.
- ticket.rs: add `#[serde(skip)]` to `Ticket::id`
- store.rs: `read_ticket` and `list_tickets` inject id from filename stem
- display.rs: `ticket_to_json_value` re-inserts id for CLI `--json` output
- tests.rs: new unit tests for omission, injection, and old-format compat
- integration.rs: assert written files lack "id"; assert read --json has id
Backwards-compatible: old files with "id" in JSON body still parse correctly
(serde ignores the unknown field), so existing stores work without migration.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Write the three required documentation files for the nbd crate:
- README.md: usage guide, field reference, dev workflow, dual-license
footer, and Claude Code disclaimer
- docs/PLANNING.md: development phase log and post-MVP roadmap
- docs/ARCHITECTURE.md: module responsibilities, data flow diagram,
storage layout, and testing strategy
Run and verify cargo fmt, check, clippy, and test (34 tests pass).
Mark all Phase 6 items as complete in PLAN.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wire up clap subcommands to storage and display layers:
- Cli struct with global --json flag and Create/Read/List/Update subcommands
- cmd_create: generates ID, validates priority and deps, writes and prints ticket
- cmd_read: looks up ticket by ID and prints it
- cmd_list: lists all tickets sorted by priority
- cmd_update: reads existing ticket, merges only provided flags, writes and prints
- parse_status, parse_ticket_type, parse_deps, validate_deps helpers
- 8 integration tests using process::Command against a tempdir
- Fix clippy: map_or(false, …) → is_some_and(…) in store.rs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add async-std file I/O and directory traversal in store.rs:
- find_nbd_root / find_nbd_root_from: walk up from cwd to locate .nbd/
- tickets_dir, ticket_path: pure path helpers
- ensure_tickets_dir: create .nbd/tickets/ on first use
- write_ticket / read_ticket: JSON serialisation round-trip
- list_tickets: read all *.json files, sort by priority descending
Add 8 unit tests covering write/read round-trip, missing-ticket
error, priority-sorted list, empty directory, grandparent traversal,
traversal failure, and path helpers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Define Status and TicketType enums with serde snake_case/lowercase
serialization, Ticket struct with all fields, Ticket::new constructor,
validate_priority, and generate_id using RandomState entropy. Add 9
unit tests covering roundtrips, enum serialization, priority validation,
and ID format/uniqueness.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>