Skip to content

Design Spec: Fuzz-Replay Culprit Identification

Document Control

Field Value
Status Implemented
Command surface canarchy fuzz identify
Primary area CLI, fuzzing, safety
Related specs docs/design/active-transmit-safety.md, docs/design/replay-command.md, docs/design/response-feedback-fuzz.md
Issues #464

Goal

Add a safe, bounded, human-in-the-loop workflow for isolating the specific frame (or minimal frame window) in a fuzz log or capture that produced an observed effect — the analogue of CaringCaribou's fuzzer identify mode. CANarchy has replay / fuzz / guided-fuzz primitives but no explicit narrowing workflow.

User-Facing Motivation

After a fuzz campaign or a captured anomaly, the operator knows that some frame in a log caused an effect (a warning light, a reset, a state change) but not which one. Re-deriving that by hand is tedious and error-prone. fuzz identify replays bisected windows of the log and, from the operator's effect/no-effect observations, narrows the candidate set to a single culprit frame — and stays automation-friendly by taking observations from flags or a file rather than hidden interactive prompts.

Requirements

ID Type Requirement
REQ-FZID-01 Ubiquitous The system shall provide canarchy fuzz identify <log> that loads a candump capture or a JSONL fuzz log / replay plan and bisects toward the culprit frame.
REQ-FZID-02 Ubiquitous The narrowing engine shall be pure and deterministic: given the frame count and the recorded observations, it shall return the candidate range, the next window to replay, and a resolved culprit once converged.
REQ-FZID-03 Optional feature Operators shall be able to mark observed effect / no-effect outcomes non-interactively via --observe effect|no-effect flags (repeatable) and/or a JSON --observations file.
REQ-FZID-04 Unwanted behaviour The workflow shall not issue hidden interactive prompts in non-interactive mode; the only interactive element is the active-transmit YES confirmation, which is bypassable via --ack-active semantics.
REQ-FZID-05 Event-driven When an interface is supplied and the search is unresolved, the system shall replay the next bisected window on the bus behind the active-transmit safety model (preflight warning, --ack-active).
REQ-FZID-06 Optional feature Where --dry-run is supplied, or no interface is given, the system shall report the narrowing plan and next window without transmitting.
REQ-FZID-07 Ubiquitous JSON output shall include the replayed/next frame window, the recorded observations, the candidate range and frames, the resolved culprit, a confidence value and rationale, and provenance (source, frame count, planned rounds).
REQ-FZID-08 Unwanted behaviour If the log is missing, unreadable, or contains no replayable frames, the system shall return a structured error (FUZZ_IDENTIFY_LOG_UNAVAILABLE / FUZZ_IDENTIFY_INVALID_LOG) with exit code 1.
REQ-FZID-09 Unwanted behaviour If an observation token is not effect/no-effect, or the observations file is not a JSON array, the system shall return a structured error with exit code 1.
REQ-FZID-10 Optional feature Where --max-window is supplied and the next replay window exceeds it, the system shall refuse with FUZZ_IDENTIFY_WINDOW_TOO_LARGE (exit 1) rather than replay an over-large window.
REQ-FZID-11 Ubiquitous fuzz identify shall be a CLI-only operator workflow and shall not be exposed as an MCP tool.

Command Surface

canarchy fuzz identify <log> [--interface can0] [--observations FILE] [--observe effect|no-effect ...]
                       [--rate 100] [--max-window N] [--ack-active] [--dry-run] [--json|--jsonl|--text]

<log> is a candump capture or a JSONL fuzz log / replay plan (one CAN-frame object per line, with top-level or payload-nested arbitration_id + data).

Narrowing Model

The search maintains an inclusive candidate range [lo, hi] over the log's frame indices, starting at the whole log. Each round replays the lower half [lo, mid] (mid = (lo + hi) // 2); an effect observation keeps the lower half (hi = mid), no-effect keeps the upper (lo = mid + 1). The search resolves when lo == hi, in ceil(log2(N)) rounds for a single culprit frame. Confidence is 1 − (hi − lo) / (N − 1)0.0 over the full log, 1.0 when resolved. Observations beyond resolution are ignored. The engine assumes a single causal frame whose presence in a replayed window reproduces the effect; the candidate window is still reported when that assumption does not hold, so the operator can inspect the minimal window directly.

Responsibilities And Boundaries

In scope: log/plan/capture loading, the pure deterministic bisection engine, non-interactive observation input, one-round-per-invocation replay behind the active-transmit gate, and structured output with confidence/rationale/provenance.

Out of scope: automatic effect detection (the operator supplies observations); multi-frame ddmin minimisation beyond a single-culprit bisection; mutation of the log during replay (frames are replayed verbatim).

Error Contracts

Code Trigger Exit code
FUZZ_IDENTIFY_LOG_UNAVAILABLE log missing / unreadable 1
FUZZ_IDENTIFY_INVALID_LOG log parsed to zero frames 1
FUZZ_IDENTIFY_INVALID_OBSERVATION observation token not effect/no-effect 1
FUZZ_IDENTIFY_INVALID_OBSERVATIONS observations file not a JSON array 1
FUZZ_IDENTIFY_OBSERVATIONS_UNAVAILABLE observations file unreadable 1
FUZZ_IDENTIFY_WINDOW_TOO_LARGE next window exceeds --max-window 1
ACTIVE_ACK_REQUIRED active replay without --ack-active while ack is required 1
TRANSPORT_UNAVAILABLE replay interface unavailable 2