Skip to content

v0.8.0

Latest

Choose a tag to compare

@hexsecs hexsecs released this 30 May 00:00
· 57 commits to main since this release
1cb5898

Changed

  • Audited MCP coverage against the full CLI surface (#323): Refreshed the authoritative CLI-to-MCP coverage matrix in docs/design/mcp-server.md so every implemented command is classified as exposed, intentionally excluded (with rationale), or deferred (not yet implemented). The audit confirms the active surface is complete: all 63 exposable commands have MCP mirrors (64 tools, since datasets replay splits into datasets_replay_plan / datasets_replay_files), with shell, tui, mcp serve, mcp install, completion, and datasets stream intentionally excluded, and plugins list/info (#317) and re anomalies (#321) deferred until those commands land. Corrected stale docs that still listed fuzzing as "deferred"/"not exposed" (the fuzz_* tools shipped in #312/#346#348) and added the newer dbc_signals, doctor, sequence_replay, and fuzz_signal / fuzz_spn tools to the naming table. Added two guard tests in tests/test_mcp.pytest_every_cli_command_is_exposed_or_documented and test_no_orphan_mcp_tools — that fail the build if a new command drifts out of coverage or a tool loses its CLI counterpart (REQ-MCP-16). docs/agents.md and AGENTS.md updated to reflect the final surface and point at the matrix.

Added

  • canarchy mcp install — write the MCP server block into a client config: Added an mcp install --client {claude-desktop,claude-code} helper that merges the mcpServers.canarchy block into a client configuration so operators no longer hand-edit JSON. It detects the per-platform Claude Desktop path (macOS / Windows / Linux) and writes a project-scoped .mcp.json for Claude Code; --config-path overrides the location and --command sets the server command (e.g. a venv binary path). The merge preserves any other mcpServers entries, treats an identical existing entry as a no-op (unchanged), and refuses to clobber a different existing canarchy entry — returning structured errors MCP_INSTALL_CONFLICT, MCP_INSTALL_INVALID_CONFIG, MCP_INSTALL_DIR_MISSING, MCP_INSTALL_READ_FAILED, and MCP_INSTALL_WRITE_FAILED. --dry-run previews the would-write config without touching disk; a YES confirmation prompt guards live writes unless --ack is supplied. The pure path-resolution and merge logic lives in src/canarchy/mcp_install.py. The command is intentionally CLI-only (writing a client config is a user action, like plugins enable/disable), and docs/mcp_install.md documents it as the quick path ahead of the hand-edit fallback. 10 tests in tests/test_cli.py cover dry-run, fresh install, the confirmation prompt (accept / decline), merge preservation, unchanged, conflict, invalid JSON, missing directory, and the --command override. Closes #322.
  • atheris coverage-guided self-fuzz of CANarchy's parsers: Added tests/fuzz/ with four atheris harnesses that fuzz CANarchy's own input parsers — fuzz_candump_parser.py (the candump line parser), fuzz_dbc_parser.py (the cantools-backed DBC parse path), fuzz_isotp_reassembly.py (the ISO-TP reassembler behind uds scan / uds trace), and fuzz_j1939_tp.py (the J1939 TP CM/DT reassembler). atheris is an opt-in dev dependency under [project.optional-dependencies] fuzz, so the default install footprint is unchanged. Seed corpora ship under tests/fuzz/corpora/<harness>/; crashing inputs are preserved under tests/fuzz/regressions/ with paired regression tests. A new bounded fuzz CI workflow runs each harness for up to 10000 runs / 30 seconds per pull request, and tests/test_fuzz_harnesses.py exercises the harness logic over the corpora plus a seeded random sweep in the regular (atheris-free) suite. The initial sweep found no crashes. docs/architecture.md documents the harness directory under the engine layer. Closes #349.
  • AFL-style mutators (havoc / splice / interesting) for fuzz payload: Borrowed AFL's mutator inventory into canarchy.fuzzing as three deterministic pure-function generators — havoc_payload (stacks a random sequence of AFL havoc operators: bit/byte flips, 8/16/32-bit arithmetic ± [1, 35], interesting-value injection, random byte replacement, and block deletion / insertion / overwrite), splice_payload (joins a random prefix of one corpus seed with a random suffix of another; raises on an empty corpus), and interesting_values_payload (enumerates the AFL interesting 8/16/32-bit values at each byte / word / dword offset over a zero baseline, deduplicated). All clamp output to 64 bytes. The canarchy fuzz payload --strategy surface gains havoc, splice, and interesting; havoc seeds from --data, interesting from --dlc, and splice reads a --corpus candump capture (returns MISSING_INPUT when omitted). The fuzz_payload MCP tool's strategy enum is extended and gains an optional corpus parameter. New engine and CLI tests cover determinism, mutation diversity, the empty-corpus ValueError, known interesting-value patterns, dedup, and the CLI strategy paths. Design spec: docs/design/fuzz-afl-mutators.md; test spec: docs/tests/fuzz-afl-mutators.md. Closes #348.
  • canarchy fuzz spn — J1939 SPN-aware mutation with sentinel coverage: Added a fuzz spn subcommand that mutates a single J1939 SPN using the bundled J1939 metadata (canarchy.j1939_metadata) for the SPN's byte offset, width, byte order, resolution, and offset. Five modes bake in J1939 conventions: in_bounds (seeded uniform samples in the operational range [0, op_max]), not_available (the all-ones sentinel 0xFF / 0xFFFF / 0xFFFFFFFF), error (the error sentinel 0xFE / 0xFEFF / 0xFEFFFFFF), boundary (0, op_max, and the representable ± 1 lsb neighbours), and out_of_bounds (one lsb past the operational max). The operational maximum reserves the top of the field per SAE J1939 (0xFA / 0xFAFF / 0xFAFFFFFF). Each emitted payload is an 8-byte PGN payload filled with the 0xFF not-available baseline, with the SPN bytes overwritten little-endian; the CAN frame's arbitration id is composed from the SPN's PGN via the new canarchy.j1939.compose_arbitration_id helper. --dry-run plans without an interface; live transmission honours the active-transmit safety model. The fuzz_spn MCP tool mirrors the CLI with mandatory ack_active=true and default dry_run=true. New engine, CLI, and MCP tests cover each mode, the sentinel/operational-max helpers across 1/2/4-byte widths, little-endian placement, determinism, and the error paths (INVALID_FUZZ_SPN, INVALID_RATE, ACTIVE_ACK_REQUIRED). Design spec: docs/design/fuzz-spn.md; test spec: docs/tests/fuzz-spn.md. Closes #347.
  • canarchy fuzz signal — DBC-aware signal mutation: Added a fuzz signal subcommand that targets a single signal inside a DBC message and exercises it within and beyond its declared bounds — respecting bit layout, length, byte order, scale, offset, minimum / maximum, and the choice set. Five modes: in_bounds (seeded uniform sampling inside [min, max]), out_of_bounds (one lsb past the declared min/max plus the representable type extrema, restricted to values strictly outside the range), boundary (min, max, and min/max ± 1 lsb, dropping unrepresentable steps), enum_gaps (every representable raw value that is not a defined choice), and full_field (sweeps the entire representable signal field, ignoring the declared DBC bounds — evenly spaced when --count is smaller than the field; the escape hatch for full-range signals where out_of_bounds is empty). The engine entry point canarchy.fuzzing.signal_payload works in raw signal space and encodes full-message payloads via the cantools runtime (scaling=False, strict=False) so out-of-range values can be emitted; non-target signals are held at a raw-zero baseline. --dry-run plans without opening a transport (no interface required); active-transmit safety (--ack-active, rate cap, run_id provenance) applies for live transmission. The fuzz_signal MCP tool mirrors the CLI with mandatory ack_active=true and default dry_run=true. New engine tests in tests/test_fuzz.py, CLI tests in tests/test_fuzz_cli.py, and MCP tests in tests/test_mcp.py cover each mode, scale/offset handling (including inward rounding of non-lsb-aligned bounds), the representable-bounds edge cases, the full_field sweep, determinism, the error paths (DBC_MESSAGE_NOT_FOUND, INVALID_FUZZ_SIGNAL, INVALID_RATE, ACTIVE_ACK_REQUIRED), and the MCP gate. Design spec: docs/design/fuzz-signal.md; test spec: docs/tests/fuzz-signal.md. Closes #346.
  • canarchy sequence replay — YAML/JSON multi-message coordinated transmit: Added a new sequence replay command that drives scripted CAN scenarios defined in a YAML or JSON sequence file. Each step specifies a delay_ms pause before sending and a frames list of DBC-encoded messages; each frame supplies a CAN arbitration ID and a signals dict. A top-level dbc key sets the default DBC for all frames; step- or frame-level dbc keys override it. --rate scales all inter-step delays (e.g. 2.0 plays twice as fast). --loop repeats the sequence until Ctrl-C. --dry-run returns the full frame schedule without opening a transport. Active-transmit safety (--ack-active, preflight warning, config-driven confirmation) is applied the same way as send, replay, and fuzz. The new canarchy/sequence.py module (SequenceFile, SequenceStep, FrameSpec, load_sequence, encode_sequence) is framework-independent and reusable. The sequence_replay MCP tool exposes file, interface, rate, loop, ack_active, and dry_run, with dry_run defaulting to true. 11 new tests cover dry-run plan structure, step events, DBC encoding, JSONL streaming, plan/dry_run/active modes, active-transmit ack gate, rate validation, missing-file error, and rate scaling. Design spec: docs/design/sequence-replay.md. Closes #362.
  • dbc inspect --search and canarchy dbc signals: Added a --search <pattern> flag to dbc inspect that filters the output to messages and signals matching a case-insensitive regex or substring — eliminating the manual full-table scan across large DBCs. Works additively with --message and --signals-only. Added a new canarchy dbc signals subcommand as a signal-centric shorthand (dbc signals <dbc> [--message] [--search]), equivalent to dbc inspect --signals-only. The dbc_inspect MCP tool gains an optional search parameter; a new dbc_signals MCP tool is added. 8 new tests cover filtered messages, filtered signals-only, no-match empty results, the new subcommand, text output, and case-insensitivity. Design spec: docs/design/dbc-inspect-search.md. Closes #361.
  • canarchy send --dbc — DBC-aware signal transmit: The send command now accepts --dbc <ref>, --message <name>, and --signals KEY=VAL … to encode a DBC message and transmit it in one step, eliminating the recurring throwaway-script pattern for single-frame research. --dry-run encodes and returns the planned frame without opening transport (no interface required). --count N repeats the send N times; --rate HZ inserts 1/HZ-second pauses between successive sends. The --crc-algorithm override from the existing encode runtime is supported. Active-transmit safety (--ack-active, preflight warning) applies the same way as raw send. The raw send <interface> <frame_id> <data> surface is fully backwards-compatible. 8 new tests cover dry-run, no-interface dry-run, active transmit, counted repeats, and all four validation-error paths. Design spec: docs/design/send-dbc-command.md. Closes #360.
  • Live replay to interface: canarchy replay --file <capture> --interface <iface> now transmits recorded frames onto a CAN bus with original timing scaled by --rate, gated by active-transmit safety (--ack-active). --dry-run plans the transmission without opening a transport. canarchy datasets replay <ref> --interface <iface> similarly streams dataset-sourced traffic onto a live interface instead of stdout. Planning-only mode (no --interface) is unchanged. The replay MCP tool exposes interface, ack_active, and dry_run fields with dry_run defaulting to true per the MCP safety model. Closes #359.
  • Added CRC repair support for fuzzing and DBC encode workflows. Operators can use --repair-crc with active fuzz planning/transmit commands and --crc-algorithm with encode to repair supported Stellantis, SAE J1850, and FCA Giorgio checksum bytes while preserving explicit checksum values. Closes #368.
  • Added comma.ai commaCarSegments replay planning and optional comma-rlog streaming support. Operators can list bounded dynamic segment manifests with datasets replay catalog:comma-car-segments --platform <name> --list-files --limit <n> --json, dry-run selected segments without opening rlog streams, and stream local or remote openpilot rlogs to candump/JSONL when optional openpilot LogReader support is installed. Closes #367.
  • Added [transport].default_interface / CANARCHY_DEFAULT_INTERFACE as a default CAN channel for single-interface commands. capture, send, generate, j1939 monitor, uds scan, uds trace, and active fuzz commands now use the configured default when the CLI/MCP interface argument is omitted, while explicit command-line interfaces continue to take precedence. Missing required interfaces now return INTERFACE_REQUIRED with a config hint. Closes #357.
  • Closed out the TUI v2 milestone by extending the Alerts pane with replay_event activity and adding a slash-command hotkey palette to canarchy tui. Alerts now surface replay_event entries alongside the existing warnings/errors (replay action=… reason=…), and the prompt accepts: /help, /quit, /exit, /clear (reset every pane), /capture <iface> (canonical candump capture), /save <name>, /load <name> (session management), /dbc <ref> (DBC inspect), /doctor, /config. Slash commands expand into the existing CLI argv shape and route through the same shared dispatch that drives the rest of the TUI — the "command palette" stays scriptable and consistent with the CLI contract. 13 new cases in tests/test_tui_snapshots.py cover replay_event surfacing, error-envelope routing, hotkey help rendering, quit/exit signalling, each templated hotkey expansion, missing-argument and unknown-name diagnostics, /clear resetting every pane, and the command-entry render advertising /help//quit. docs/tui_plan.md marks the milestone closed. Closes #316.
  • Added the UDS pane to canarchy tui per docs/tui_plan.md section 5. The pane records uds_transaction events emitted by uds scan and uds trace and renders one row per transaction: service=0xSS (name) req=0xRRR->0xRRR ecu=0xEE, plus either NRC=<name>, resp=<summary>, or the raw resp=<hex> outcome. Truncated multi-frame responses (complete=false) are prefixed with !! incomplete so the operator notices ISO-TP reassembly that didn't finish. Pane keeps the 8 most recent transactions, newest first. 7 new cases in tests/test_tui_snapshots.py cover empty-state, positive responses, NRC name surfacing, incomplete-flag highlighting, bounded newest-first ordering, untouched-on-non-UDS results, and the renderer header. Closes #315.
  • Added the J1939 pane to canarchy tui per docs/tui_plan.md section 4. The pane tracks PGN frequency (top 3 shown), active source addresses (top 4), recent activity (last 8 events, newest first) from j1939_pgn events emitted by any J1939 command, and surfaces a DM1 alert ribbon from j1939 dm1 messages — only when active_dtc_count > 0, so no-fault filler entries don't light up the ribbon. Each DM1 alert includes source address, transport mode, active count, lit lamps, and the first two SPN/FMI pairs. 6 new cases in tests/test_tui_snapshots.py cover empty-state rendering, top-PGN / SA aggregation, newest-first bounded recent activity, the DM1 ribbon's selective lighting, untouched-on-non-J1939 results, and an end-to-end check against tests/fixtures/j1939_heavy_vehicle.candump. docs/tui_plan.md updates the implementation status. Closes #314.
  • Added the Decoded Signals pane to canarchy tui per docs/tui_plan.md#decoded-signals. The pane fills from any command that produces signal data — canarchy decode --dbc ... (via decoded_message events), j1939 pgn --json (via the decoded_signals enrichment), j1939 spn <id> (via observations), and any future emitter of signal events. Rows render as MessageName.SignalName = value [units]; floats are rounded to three decimals. The pane keeps the 12 most recent rows, newest first, so it stays bounded without losing recent context. Eight unit cases plus an end-to-end snapshot against tests/fixtures/sample.dbc live in tests/test_tui_snapshots.py. docs/tui_plan.md is updated to mark the pane implemented; the J1939, UDS, and richer Alerts panes remain as the next milestones. Closes #313.
  • Added the fuzz_payload, fuzz_replay, and fuzz_arbitration_id MCP tools mirroring the CLI surface from #311, behind an MCP-side opt-in token. Every call must supply ack_active=true; agents that omit the field or pass ack_active=false receive ACTIVE_TRANSMIT_REQUIRES_ACK and the underlying command is never invoked. dry_run defaults to true for agent-initiated calls per REQ-ATS-13 so the agent plans the fuzz workflow safely unless the operator explicitly authorises live transmission with dry_run=false. 7 new tests in tests/test_mcp.py cover the gate (missing/false ack on all three tools), the dry-run default round-trip, and the argv builder's dry-run inclusion / exclusion. docs/mcp_install.md documents the contract. Closes #312.
  • Reintroduced canarchy fuzz {payload,replay,arbitration-id} — active-transmit fuzzing CLI built on the engine from #310 and gated by the active-transmit safety design (docs/design/active-transmit-safety.md). --dry-run is the safe planning path: events are emitted as JSONL with payload.frame.dry_run = true, no transport is opened, and the --ack-active prompt is skipped. Without --dry-run, the existing safety gate (--ack-active plus optional config-driven prompt) applies before frames are transmitted via LocalTransport.send. Every emitted event carries a stable run_id (UUID). The following spec controls are tracked as follow-ups and land in subsequent PRs: configurable rate-cap ceiling ([safety.rate_cap]), TOML target allowlist (--targets), explicit KILL_SWITCH_TRIGGERED alert on SIGINT, and MCP ack_active=true enforcement (#312). 13 new tests in tests/test_fuzz_cli.py cover dry-run determinism, run_id stamping, validation paths (bad hex ID, bad rate, bad UUID, out-of-band ID range), monotonic replay timestamps, the MISSING_INPUT gate on live replay without --interface, and ACTIVE_ACK_REQUIRED when [safety].require_active_ack=true and --ack-active is omitted. Closes #311.
  • Added src/canarchy/fuzzing.py — five pure-function mutation generators that underpin the planned canarchy fuzz command tree (#311): bitflip_payload (exhaustive single-bit walk, then seeded picks), random_payload, boundary_payload (all-zero, all-one, alternating, walking-one, walking-zero), mutate_replay (timing and payload-bitflip strategies that preserve arbitration ID and frame metadata), and arbitration_id_range (inclusive bounds with 11-/29-bit range validation). All generators are seeded and deterministic; the module performs no transport, no file I/O, and no wall-clock work. 30 unit tests in tests/test_fuzz.py cover determinism, Hamming-distance invariants, empty-input safety, range bound validation, and a guard test that asserts the module imports no transport / socket / asyncio symbols. Architecture doc lists the new module under the engine layer. Closes #310.
  • Added .github/workflows/test.yml running pytest on Python 3.12 and 3.13 for every push to main and every pull request, so PR validation no longer depends on manual local runs. The workflow uses pytest (not unittest discover) so module-level function-style tests in tests/test_mcp.py and tests/test_dbc_runtime.py are collected; 667 tests run vs. 599 under unittest discover. Closes #306.
  • Added .github/workflows/lint.yml running uv run ruff check and uv run ruff format --check on every push to main and every pull request, so style and format drift is caught before review. Declared ruff>=0.15.8 under [dependency-groups] dev in pyproject.toml so uv sync resolves the same ruff used by CI; previously uv run ruff only worked locally when ruff was installed as a global uv tool. Closes #307.
  • Added global --log-level {debug,info,warn,error} and --quiet flags on the top-level canarchy parser, wired to Python logging with stderr-only output so machine-readable stdout (--json, --jsonl, --text) is never contaminated. Place the flags before the subcommand. Closes #302.
  • Added canarchy doctor, a fast offline health-check command returning the canonical envelope with eight structured checks: Python version, python-can import, configured transport backend, ~/.canarchy/config.toml parseability, DBC / dataset / skills cache writability, opendbc cache population, MCP stdio server constructability, and package/source version consistency. Mirrored as the doctor MCP tool. Closes #303.
  • Added canarchy completion {bash,zsh,fish} emitting a shell completion script to stdout. Scripts complete the top-level subcommands and the common flags (--json, --jsonl, --text, --file, --dbc, --max-frames, --seconds, --offset, --ack-active, --log-level, --quiet). Source the output directly or save it to the shell's completion directory; install snippets are documented in docs/getting_started.md. Unsupported shells return the standard INVALID_ARGUMENTS structured error. Closes #304.

Documentation

  • Corrected the Tesla DI_torque2 vehicle-speed fuzzing cookbook recipe so the checksum caveat no longer references an unsupported checksum-repair flag on the current CLI surface. Closes #365.
  • Added a cookbook recipe for the Tesla DI_torque2 vehicle-speed fuzzing workflow. The recipe shows how to fetch and inspect opendbc:tesla_can, identify the DI_vehicleSpeed field on arbitration ID 0x118, run dry-run and active fuzz passes through the configured default interface, and account for Tesla checksum limitations before ECU acceptance testing. Closes #363.
  • Added docs/design/active-transmit-safety.md (EARS) and docs/tests/active-transmit-safety.md (Gherkin) defining the safety controls that every active-transmit command must honour going forward: --ack-active gate (inherited from active-command-safety.md), per-command rate caps with ACTIVE_TRANSMIT_RATE_EXCEEDED, TOML-format target allowlist files with ACTIVE_TRANSMIT_TARGET_BLOCKED, kill-switch on SIGINT and stdin EOF with KILL_SWITCH_TRIGGERED alert, --dry-run planning mode that emits would-send JSONL without opening a transport, run_id provenance on every emitted event, and MCP-side gating with mandatory ack_active=true (ACTIVE_TRANSMIT_REQUIRES_ACK) plus default dry_run=true for agent-initiated calls. Includes a per-command audit table showing which controls already exist and which the fuzz reintroduction (#311) and MCP gating (#312) issues will land. Wired both specs into the mkdocs Design Specs / Test Specs nav. Closes #309.
  • Added docs/mcp_install.md as the canonical install reference for wiring canarchy mcp serve into MCP-capable agent clients (Claude Desktop, Claude Code, and any generic stdio client). Covers OS-specific config paths, a verification recipe, configuration tips, and a troubleshooting table. Cookbook recipe mcp-claude-integration.md updated to point at the new canonical page. Closes #308.
  • Added a "Try it in 60 seconds" block near the top of README.md showing the pipx install canarchy quickstart followed by canarchy doctor and a fixture-backed J1939 decode. Rewrote the README.md "Installation" section to lead with the PyPI path (pipx / pip) and keep the uv-based source install under a "From source (development)" subsection. docs/getting_started.md mirrors the same split and now leads with the published-package path. The actual PyPI publish is dispatched manually via the existing .github/workflows/publish.yml (verified locally: uv build produces a clean sdist + wheel and uvx twine check passes for both). Closes #300.
  • Audited every ErrorDetail(...) call site in src/canarchy/ for hint coverage. Backfilled the two remaining missing hints (CAPTURE_EMPTY on stdin paths in stats and capture-info), each now pointing at the most common pipeline misuse. Added a Hint convention section to docs/event-schema.md documenting the contract with DBC_CACHE_MISS as the reference template. Added tests/test_cli.py::ErrorHintConventionTests with a structural scan that asserts every ErrorDetail(...) construction includes a hint= field — drift now fails CI — plus a representative-codes test that asserts hint length and content for DBC_NOT_FOUND, CAPTURE_SOURCE_UNAVAILABLE, INVALID_SESSION_NAME, INVALID_MAX_FRAMES, and INVALID_ANALYSIS_SECONDS. Closes #305.

Fixed

  • Declared requests>=2.31 under [project] dependencies in pyproject.toml. The package is imported by src/canarchy/dataset_convert.py and tests/test_dataset_provider.py, but was only present transitively via the docs group. Clean environments would fail canarchy datasets convert and could not load the 119 tests in test_dataset_provider. Closes #337.

Changed

  • Cleared the ruff check and ruff format backlog: applied the auto-fixable rules (24 unused imports, 4 redundant f-string prefixes, plus 5 trivial others), renamed 13 ambiguous l loop variables to line in test files, removed two dead local variables in src/canarchy/cli.py (tp_sessions in _j1939_compare_capture and command_label in the RE match-DBC handler), removed a dead earlier definition of format_dbc_table shadowed by the richer redefinition, fixed a buggy test_j1939_dm1_returns_rts_cts_transport_message whose body asserted TP session structure instead of DM1 messages and was already silently overridden by a correct later redefinition, dropped three other accidentally-duplicated test methods, and reformatted the 34 files that were out of ruff format compliance. Closes #335.
  • Renamed the canonical human-readable output flag from --table to --text; --table remains accepted as a compatibility alias. Closes #286.
  • Removed the generic --raw output mode from the shared command surface; use --text, --json, --jsonl, or command-specific frame-line options such as --candump instead. Closes #288.

Removed

  • Removed the --compact output mode and the placeholder fuzz command tree; fuzzing remains planned but is no longer exposed before active-transmit safety design is complete. Closes #292.

Documentation

  • Cleaned up stale homepage, overview, command spec, and design wording after the output-mode updates. Closes #290.
  • Added CONTRIBUTING.md, CODE_OF_CONDUCT.md, and SECURITY.md at the repository root and linked them from the README under a Community section. Closes #296.
  • Added GitHub issue templates (bug report, feature request, contact-link config) and a pull request template under .github/ so submissions follow the project's existing ## Summary / ## Acceptance Criteria shape. Closes #297.
  • Added docs/troubleshooting.md with a structured catalog of CLI error codes (DBC_LOAD_FAILED, DBC_CACHE_MISS, DATASET_INDEX_NOT_REPLAYABLE, INVALID_MAX_FRAMES, ANALYSIS_WINDOW_REQUIRES_FILE, and many more) including remediation snippets, and wired it into the User Guide nav. Closes #298.
  • Added a docs/cookbook/ section with task-oriented recipes covering filtering by ID/PGN, decoding SPN 110, finding counter signals, matching captures against opendbc, streaming CANdid into stats, MCP integration with Claude Desktop and Claude Code, building a virtual CAN loop, and comparing DM1 faults across captures; new top-level Cookbook nav entry. Closes #299.
  • Added docs/examples/config.toml as a fully commented sample for ~/.canarchy/config.toml and referenced it from the Getting Started guide. Closes #301.