Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Command Reference

In brief: ah is the espectacular CLI — espectacular is an alias for the same binary. The primary commands are ah check (run in CI to enforce specs) and ah init (run once per repo to set up). Use ah explain <topic> to get guidance on any finding or error.


ah init

Create or refresh .espectacular/ files and hook integration.

ah init

Idempotent: safe to re-run after updating specs or changing hook frameworks. Stubs contract files for any scenarios that have no existing contract. Installs ah check into lefthook or prek if detected.

Exit codes: 0 on success, non-zero if the OpenSpec directory is missing.


ah check

Validate deployed specs and run declared tests. Prints a stable JSON envelope to stdout.

ah check [--changes <id>]

Flags:

FlagDescription
--changes <id>Include one or more staged change overlays (repeat for multiple)

Exit codes: 0 when findings contains no structural or execution findings; 1 otherwise. Quality findings (quality-*) never cause a non-zero exit.

Note: All JSON examples below show the data field of the genesis envelope — actual output wraps these fields in {ok, envelope_version, cli_version, envelope_kind, data, warnings, hints, meta}.

Example — clean run:

ah check
{
  "ok": true,
  "envelope_version": "0.1",
  "cli_version": "0.4.0",
  "envelope_kind": "ok",
  "data": {
    "scope": { "deployed": true, "changes": [] },
    "summary": { "structural": 0, "execution": 0, "passed": 3, "counts_by_kind": {} },
    "findings": []
  },
  "warnings": [],
  "hints": [],
  "meta": { "duration_ms": 0, "tx": null, "request_id": null, "author": null }
}

Example — with a staged change:

ah check --changes add-parser-validation
{
  "scope": { "deployed": true, "changes": ["add-parser-validation"] },
  "summary": { "structural": 0, "execution": 0, "passed": 4, "counts_by_kind": {} },
  "findings": []
}

Example — with a finding:

{
  "scope": { "deployed": true, "changes": [] },
  "summary": { "structural": 1, "execution": 0, "passed": 0, "counts_by_kind": { "no-toml": 1 } },
  "findings": [
    {
      "kind": "no-toml",
      "category": "structural",
      "spec": "parser",
      "spec_path": "openspec/specs/parser/spec.md",
      "scenario": { "id": "empty-input-is-rejected", "title": "Empty input is rejected" },
      "suggested_action": "run_ah_scenario_new",
      "playbook_command": "ah explain run_ah_scenario_new"
    }
  ]
}

Run the playbook_command from any finding to get step-by-step guidance:

ah explain run_ah_scenario_new

Finding kinds:

KindCategoryMeaning
no-tomlstructuralscenario has no matching contract file
orphan-tomlstructuralcontract exists without a matching scenario
slug-collisionstructuraltwo scenarios in one spec have the same id
id-mismatchstructuralscenario slug, filename, and TOML id disagree
no-tests-declaredstructuralcontract has no runnable test entries
missing-runnerstructurala non-shell test type has no configured runner
malformed-contractstructuralTOML cannot be parsed or validated
missing-replacementstructuralsuperseded contract points to an absent replacement
overlay-conflictstructuralselected changes define conflicting staged scenarios
test-failingexecutiona declared test timed out or exited non-zero
quality-mutationqualitymutation score meets threshold (informational)
quality-propertyqualityproperty-based tests passing (informational)
quality-snapshotqualitysnapshot tests passing (informational)

ah doctor

Detect configured frameworks and diagnose config, path, hook, and archetype issues.

ah doctor [--enable <capability>]

Flags:

FlagDescription
--enable <capability>Write the config block for a detected-but-unconfigured capability

Capabilities for --enable: pytest, cargo, vitest, mutation, property, snapshot

Example output:

framework: pytest (configured)
recommendation: vitest detected via manifest — run: ah doctor --enable vitest

Example — enable vitest:

ah doctor --enable vitest

Writes the [runners.vitest] entry to .espectacular/config.toml. If already configured, exits 0 with an “already enabled” message.

Exit codes: 0 when no problems are found (recommendations do not affect exit code); 1 when structural problems exist. --enable exits 0 on success, non-zero for unknown capabilities.

ah doctor --json

Emit diagnostic output as JSON, with each recommendation appearing as a structured finding.

ah doctor --json
{
  "findings": [
    {
      "kind": "recommendation",
      "suggested_action": "enable_capability",
      "playbook_command": "ah explain enable_capability",
      "apply_command": "ah doctor --enable cargo",
      "detail": "cargo detected via manifest",
      "capability": "cargo"
    }
  ]
}

Each recommendation finding carries playbook_command and apply_command for agent-consumable remediation.

Exit codes: same as ah doctor.


ah report

Display a conformance coverage matrix across all deployed specs and archetypes.

ah report [--json]

Flags:

FlagDescription
--jsonEmit the matrix as JSON

Text output (default):

spec                 archetype     covered   missing   failing    total
compiler                                      0         0         0         3
adapters                                      0         0         0         1
parser                                         0         1         0         1

covered: 3 | missing: 1 | failing: 0 | total: 5

JSON output (--json):

{
  "matrix": [
    {
      "spec": "compiler",
      "archetype": "",
      "covered": 3,
      "missing": 0,
      "failing": 0,
      "total": 3
    }
  ],
  "summary": {
    "total_scenarios": 5,
    "total_contracts": 4,
    "covered": 3,
    "missing": 1,
    "failing": 0
  }
}

Exit codes: 0 when all scenarios are covered by contracts; 1 when any scenarios are missing or failing.


ah explain

Print guidance for a finding kind or suggested action.

ah explain [<topic>] [--list] [--json]

Arguments:

ArgumentDescription
<topic>Finding kind or action slug to explain

Flags:

FlagDescription
--listList all available topics
--jsonEmit the topic list as JSON (use with --list)

Example — explain a finding:

ah explain no-toml
## no-toml — Missing contract file

A scenario declared in a spec file has no corresponding contract .toml file
in .espectacular/<component>/.

How to fix: run `ah scenario new` with the spec, scenario id, and heading
to generate the contract stub, then populate the test entries.

    ah scenario new <change> <spec> --requirement <scenario-id> <heading>

Example — list all topics:

ah explain --list

Exit codes: 0 on success; 1 for unknown topics (includes “did you mean” suggestions).


ah signals

Read dont rejection events and emit drift signals as JSON.

ah signals

dont is a companion tool that tracks epistemic claims made by AI agents. When an agent makes a claim that is later rejected, dont records it as an event. ah signals reads those events from .dont/events/*.json and re-emits them as structured DriftSignal JSON that CI or the wai project-context tool can consume to surface spec-behavior gaps.

Exit codes: always 0; returns an empty JSON array if no events are found.


ah type

List built-in archetypes, or print full documentation for one.

ah type [<code>]

Example — list all:

ah type
PF — Pure Functional: Deterministic behavior where outputs are a function of explicit inputs.
SA — Stateful API: Behavior involving state transitions, persisted data, or ordered operations.
BP — Boundary Protocol: Behavior at an external boundary or protocol seam.
CE — Contract/Event: Behavior expressed as emitted events, messages, claims, or cross-tool signals.
NR — Non-Regression: Behavior asserting existing guarantees remain true while nearby changes land.

Example — full docs for one archetype:

ah type PF
## PF — Pure Functional

Deterministic behavior where outputs are a function of explicit inputs.

Use for:
- parsers
- formatters
- validators
- pure transformations
- deterministic calculations

Typical test shapes:
- unit examples for representative inputs
- property-based tests for invariants
- boundary input examples

Exit codes: 0 on success; 1 for unknown archetype codes (includes “did you mean” suggestions).


ah scenario new

Append a new scenario to a spec and stage its TOML contract.

ah scenario new <change> <spec> --requirement "<scenario-id>" "<heading>"

Arguments:

ArgumentDescription
<change>Change id (the change directory must exist under openspec/changes/)
<spec>Spec name (e.g. parser)
--requirementRequirement grouping name — must match a ### Requirement: heading already in the spec; the new #### Scenario: is appended under it
<heading>Human-readable scenario heading to append

Appends the scenario under the named requirement block and creates the contract stub at .espectacular/changes/<change>/<spec>/<scenario-id>.toml.

Exit codes: 0 on success; 1 if the change or spec is missing, or the requirement block is absent.


ah scenario supersede

Stage a supersession update for an existing contract.

ah scenario supersede <spec> <old-id> --with=<new-id> --in-change=<change>

Marks the old contract status = "superseded" and sets superseded_by to the new scenario id. The replacement scenario must already exist in the named change overlay.

Exit codes: 0 on success; 1 if the deployed contract or replacement is missing.


ah archive

Move staged change contracts into deployed .espectacular/ locations.

ah archive <change>

Run after a change merges. Moves TOML files from .espectacular/changes/<change>/ into .espectacular/<spec>/, failing if any collision would overwrite an active contract without a supersession in place.

Exit codes: 0 on success; 1 on collision or missing staged change.


ah upgrade

Report tool-version drift and update .espectacular/config.toml.

ah upgrade

Compares tool_version in .espectacular/config.toml with the running binary version. Updates the config if they differ, then exits non-zero so CI can detect compatibility changes.

Exit codes: 0 when versions match; 1 when drift is detected (even after updating the config).