> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crucihil.io/llms.txt
> Use this file to discover all available pages before exploring further.

# crucihil author

> Author a self-verified test suite from component source code

## Synopsis

```bash theme={null}
crucihil author <source> [options]
```

## Description

`crucihil author` is the self-verifying authoring loop: point it at a firmware component's source and get a test suite that is **proven to catch regressions**, not just one that passes.

```
analyze (contract) → generate → baseline gate → [--verify: mutate → repair] → write
```

1. **Analyze** — extracts the component's signal contract (with evidence chains) from the source, the DBC corpus, and — with `--repo` — the cross-component port graph.
2. **Generate** — an AI generates a suite from the contract; a deterministic static generator is the guaranteed fallback.
3. **Baseline gate** — every candidate must compile, import, load as a manifest, and run green on the rig before it is accepted. Failures feed back into AI repair rounds.
4. **Verify** (with `--verify`) — the suite is mutation-verified and weak tests are regenerated from the mutation evidence, ending with the strength matrix.
5. **Write** — the promoted suite lands in `--output-dir` after a confirmation prompt (skipped with `--yes`).

<Note>
  Broken AI output never reaches disk. Every candidate must pass the compile → import → manifest-load → green-baseline-run gate; after the AI repair rounds are exhausted, the deterministic static generator takes over — and it must itself pass the gate before anything is written.
</Note>

## Options

<ParamField path="source" type="path" required>
  Component source file or directory to author tests for. With `--protocol`, this is a protocol description instead (C packet header, protobuf, or prose spec).
</ParamField>

<ParamField path="--component" type="string">
  Component name. Defaults to the source directory name. Short form: `-c`.
</ParamField>

<ParamField path="--rig" type="path" default="rigs/virtual.toml">
  Rig TOML the baseline gate runs against (virtual rig by default). Short form: `-r`.
</ParamField>

<ParamField path="--dbc" type="path">
  DBC file for the signal corpus. Repeatable.
</ParamField>

<ParamField path="--repo" type="path">
  Firmware repo root — enables cross-component port-graph resolution for the contract.
</ParamField>

<ParamField path="--dep" type="path">
  Dependency path (shim headers etc.), parsed alongside the primary source. Repeatable.
</ParamField>

<ParamField path="--output-dir" type="path" default="tests/suites">
  Directory the promoted suite (YAML + Python) is written to.
</ParamField>

<ParamField path="--suite-name" type="string">
  Suite name. Default: `<component>_contract`.
</ParamField>

<ParamField path="--framework" type="string" default="crucihil">
  Output format: `crucihil` (native YAML + Python), `pytest` (`test_*.py` + wrapper manifest), or `robot` (`.robot` suite + wrapper manifest). See [Framework output](#framework-output).
</ParamField>

<ParamField path="--provider" type="string">
  AI provider: `anthropic`, `openai`, or `gemini`. If omitted, auto-detected from environment variables. Short form: `-p`.
</ParamField>

<ParamField path="--repair-rounds" type="integer" default="2">
  Max AI repair rounds before the static fallback takes over.
</ParamField>

<ParamField path="--yes" type="boolean" default="false">
  Skip the write confirmation prompt. Short form: `-y`.
</ParamField>

<ParamField path="--verify" type="boolean" default="false">
  After authoring: mutation-verify the suite, regenerate weak tests from the mutation evidence, and end with the strength matrix — the full self-verifying loop.
</ParamField>

<ParamField path="--max-iterations" type="integer" default="3">
  Repair-loop cap for `--verify`: verify → regenerate → re-verify rounds.
</ParamField>

<ParamField path="--protocol" type="boolean" default="false">
  Treat `source` as a protocol description: generate a declarative wire-format YAML instead of tests. See [Protocol import mode](#protocol-import-mode).
</ParamField>

<ParamField path="--spec-output" type="path">
  Output path for `--protocol`. Default: `<protocol>.yaml` in the current directory.
</ParamField>

## Exit codes

| Code | Meaning                                                                                                                                                                               |
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0`  | Suite authored, gated, and written                                                                                                                                                    |
| `2`  | Pipeline failure — analysis error, every candidate (including the static fallback) failed the baseline gate, protocol import failed the round-trip harness, or the write was declined |

## Output format

```
Component : BrakeController
Rig       : rigs/virtual.toml
Analyzing component (contract extraction)...
Generating + gating suite on the rig (may take a minute)...

  Suite     : tests/suites/brakecontroller_contract.yaml
  Tests     : tests/suites/brakecontroller_contract.py  (5 functions)
  Contract  : contracts/BrakeController.json
  Generator : ai
  Baseline  : 5/5 passed on rigs/virtual.toml

  Run it:   crucihil run --suite tests/suites/brakecontroller_contract.yaml --rig rigs/virtual.toml
```

If any tests came from low-confidence signal matches, a `⚠ Review` line lists them. If AI attempts failed the gate before one succeeded, a `Repairs` line reports how many.

## Framework output

With `--framework pytest` or `--framework robot`, the baseline gate runs through the framework executors instead of the native runner, and the promoted output is a **native test file plus a wrapper manifest**:

* `pytest` → `test_<suite>.py` + `<suite>.yaml`
* `robot` → `<suite>.robot` + `<suite>.yaml`

The wrapper manifest points `crucihil run` at the foreign file via the `framework:` and `path:` fields:

```yaml theme={null}
suite:
  name: brakecontroller_contract
  version: "1.0.0"
  description: "Contract tests for BrakeController"

framework: pytest
path: tests/suites/test_brakecontroller_contract.py

tests: []
```

The result is runnable via [`crucihil run`](/cli/run) like any other suite, and verifiable via [`crucihil verify`](/cli/verify).

<Note>
  With `--verify --framework pytest|robot` you get the strength report, but the evidence-driven auto-repair loop regenerates **native** suites only — weaknesses in foreign-format output are reported for manual review.
</Note>

## The `--verify` loop

`--verify` chains mutation verification onto the authored suite: baseline run + one run per mutation (dead DUT, stuck outputs, latency violations, declared faults), then regenerates any test that missed a mutation, up to `--max-iterations` rounds. The command ends with the tests × mutations strength matrix:

```
  ✓ Every planned mutation is caught — the suite is verified.
```

or, if the iteration cap is reached with weaknesses remaining:

```
  ⚠ 2 residual weakness(es) remain after the iteration cap — review these tests by hand.
```

See [crucihil verify](/cli/verify) for the mutation kinds, outcomes, and report format.

## Protocol import mode

With `--protocol`, `source` is a protocol description — a C packet header, a protobuf definition, or a prose spec — and the output is a **declarative wire-format YAML**, not tests. The AI writes the spec, never code, and the spec must pass the round-trip verification harness (encode → decode → compare) before it is written. Failed attempts are repaired up to `--repair-rounds` times.

```bash theme={null}
crucihil author protocol_header.h --protocol
```

```
Importing protocol from protocol_header.h...
Generating spec + round-trip verification (may repair)...

  Spec      : telemetry.yaml  (harness-verified)
  Protocol  : telemetry
  Messages  : StatusReport, SensorFrame  (12 signals)

  Wire it into a rig:
    [rig.custom.telemetry]
    backend     = "virtual_datagram"
    definitions = "telemetry.yaml"
```

## Examples

### Author a suite for one component (virtual rig gates the output)

```bash theme={null}
crucihil author src/brake_controller/ -c BrakeController --dbc defs/vehicle.dbc
```

### The full loop: author + mutation-verify + regenerate weak tests

```bash theme={null}
crucihil author src/brake_controller/ -c BrakeController --repo firmware/ --verify -y
```

### Emit the suite in your team's own framework

```bash theme={null}
crucihil author src/brake_controller/ -c BrakeController --framework pytest
crucihil author src/brake_controller/ -c BrakeController --framework robot
```

### Import a custom protocol spec instead of authoring tests

```bash theme={null}
crucihil author protocol_header.h --protocol
```

## See also

* [crucihil verify](/cli/verify) — mutation verification as a standalone command
* [crucihil analyze](/cli/analyze) — the contract-extraction step on its own
* [crucihil run](/cli/run) — run the promoted suite
* [YAML Manifest Reference](/test-authoring/yaml-manifest) — suite and wrapper manifest schema
