runward

RW™ · V0.22.0

Docs · Décisions · ADR-0014

ADR-0014.

The `runward characterize` command contract

Date: 2026-07-09 Status: accepted Deciders: Thibault Souris (maintainer) Method: decision-loop — first build piece of the retro-documentation surface scoped in ADR-0013. Contract decided against the never-a-runtime and zero-LLM-gate invariants. Decision only; no code in this ADR.

Amendment (2026-07-10, before implementing --mine). Reconciled --mine with the zero-LLM-tool invariant and ADR-0007: runward's --mine is deterministic (git archaeology) and makes no model call — the original "may use an agent/LLM" wording is corrected below. The LLM refinement of a candidate into an argued hypothesis lives in the harness (the operating agent), exactly like the advisory verify workflow; a model behind a port remains possible but runward bundles none.

Amendment (2026-07-20, resume-existing audit). The Decision's inventory list described three capabilities ahead of the code; reconciled here rather than left as drift. Pinned versions and git churn are now implemented (ADR-0035, ADR-0036) — those claims are now true. "reported coverage" is withdrawn: characterize deliberately reads test presence and a file count, never a coverage figure — reading a coverage report would mean trusting a generated artifact the command never produced, against the "parse at rest" line. In the Surface, --yes and --dry-run are global flags (runward --dry-run characterize), not command options; the command's own options are --path and --mine. Separately, the "two runs agree" promise now rests on deterministic ordering (every filesystem scan is sorted — ADR-0034, which also adds monorepo/workspace coverage), and --mine now mines across languages and groups by family (ADR-0038). None of these loosen the read-only / zero-LLM / operator-owns-the-gate contract; they fulfil it.

Context

ADR-0013 adopts retro-documentation as the transmission phase pointed backward and names runward characterize as the one genuinely new primitive: the read-only entry point that turns an undocumented system into the start of a governed mission. Today the brownfield entry mode is a workflow the agent reads (brownfield.md) with no CLI verb; "characterize before touching" is a manual instruction, not a tool.

Before writing code, the command's contract must be locked, because characterize is the highest-temptation surface in runward: it is the one place an agent reads a real codebase, and the pull is to let it conclude — to emit "here is your architecture / here are your decisions / here is your compliance posture" as fact. That would put an LLM's judgment on the path to the gate and make runward an oracle. The contract exists to make that impossible by construction, not by good intentions.

Decision

runward characterize is a read-only command that produces the raw material of a brownfield mission: a factual inventory plus candidate decisions, all explicitly unvalidated. It reads artifacts at rest and writes only into runward/ — never into .git/, never the user's source, and it never executes the user's system.

Two layers, sharply separated:

  • Deterministic inventory (default, zero-LLM). Parses artifacts at rest: repo tree, dependency manifests and lockfiles (pinned versions), entrypoints, CI/workflow config, container/deploy files, test presence and reported coverage, and the shape of git log (age, churn, authors — counts, not interpretation). Emits runward/characterization.md: a factual inventory with a confidence: high header, no opinions, no why. Reproducible — two runs on the same commit agree.
  • Candidate ADR-mining (opt-in, --mine). Only under an explicit flag, and deterministic — runward makes no model call. It reads git history and the inventory at rest to propose candidate structural decisions (the stack/language choice, containerization, the CI pipeline, notable dependency families) and writes only runward/adr/DRAFT-*.md files, each with status: hypothesis, the evidence pointers (file paths, first-seen dates) that suggest a decision, and an explicit why: UNKNOWN — needs operator field. Turning a candidate into an argued hypothesis, and supplying the why, is the harness/agent's job downstream (per ADR-0007), never runward's. It writes nothing else and touches no manifest.

The contract's hard lines:

  • Read-only, never a runtime. characterize opens files; it does not install, build, run, or instrument the target. No network to the target, no execution of its code.
  • Zero-LLM, no model call. The whole command is deterministic: the inventory is pure parsing, and --mine is git archaeology. runward calls no model and bundles none — the LLM refinement of candidates lives in the harness (ADR-0007's advisory posture), strictly upstream of any gate, and even there its only output is DRAFT hypotheses the operator must ratify.
  • Nothing it emits can pass the gate. DRAFT ADRs carry status: hypothesis; check --strict (per ADR-0013's lifecycle) requires status: accepted + a human-written why + a trigger. characterize produces material for the operator to ratify, never a conformance verdict.
  • Facts are labelled facts; guesses are labelled guesses. characterization.md is confidence: high (mechanical). DRAFT ADRs are hypotheses with provenance. No output is ever presented as original design intent or as compliance.
  • Idempotent and non-destructive. Re-running refreshes characterization.md and adds/updates DRAFTs; it never overwrites an operator-ratified ADR (status: accepted) or any mission state.

Surface: runward characterize [--path <dir>] [--mine] [--yes] [--dry-run]. Exit codes follow the house convention: 0 inventory produced, 2 no repo/target found. --mine never changes the exit code (advisory). Default (no --mine) is deterministic and offline.

Alternatives discarded

  • Let characterize run or instrument the system to observe real behavior. Violates never-a-runtime and would require executing untrusted code. Characterization tests that do run belong to the operator in their own harness (brownfield workflow), not to a runward command. Rejected.
  • Emit ADRs directly (no DRAFT state), or auto-accept mined decisions. Launders a hypothesis into a validated fact and lets an LLM's guess satisfy the gate. Rejected — it breaks operator-owns-the-gate (ADR-0013).
  • Put the mining in the default path (no opt-in flag). Makes every characterize an LLM call and blurs the deterministic/advisory line. Rejected — the deterministic inventory must stand alone, offline and reproducible.
  • One combined artifact (inventory + decisions in one file). Confuses confidence: high facts with hypothesis guesses. Rejected — separate characterization.md (facts) from adr/DRAFT-*.md (hypotheses).

Consequences

  • Positive. The named-but-untooled entry mode becomes a real, safe primitive; the operator gets the raw material of a brownfield mission in one read-only pass; the deterministic inventory is useful on its own (offline, no keys), and the advisory layer accelerates ADR reconstruction without ever asserting truth.
  • Negative, accepted. A useful --mine run depends on an agent whose proposals are fallible — surfaced honestly as hypothesis/why: UNKNOWN, never smoothed over. The command does not finish the retro-doc; it starts it (the operator must ratify, and prove autonomy — ADR-0013's caveat).
  • On other boundaries. A new src/commands/characterize.ts; a runward/characterization.md convention and a DRAFT-*.md ADR shape; init/doctor unaffected; the deterministic gate and its zero-LLM invariant untouched (this command sits entirely upstream of it).

Reevaluation trigger (mandatory, dated)

Reopen if --mine proposals are trusted without ratification in practice (operators promoting DRAFTs unread), or if the deterministic inventory is asked to make judgments beyond parsing. At that point, add friction to DRAFT promotion (an explicit per-ADR confirm) or narrow the inventory, rather than let characterize drift toward asserting conclusions.

Trigger set on: 2026-07-09 · Watched via: field use of characterize --mine and any DRAFT promoted without an operator-written why.

References

  • ADR-0013 — the retro-documentation decision and the ADR hypothesis → accepted lifecycle this command feeds.
  • ADR-0001 — the deterministic gate characterize sits upstream of.
  • docs/retro-documentation.md — the capability brief, confidence model, and anti-overclaim guardrails.
  • templates/workflows/brownfield.md, docs/when-to-use.md — the documented entry mode this command tools.
← Tous les ADR