# CLI Reference

Complete reference for all `aioson` commands.

---

## init

Create a new project directory and install AIOSON inside it. In interactive terminals, an **install wizard** runs first so you choose which AI tools and modes to install.

```bash
aioson init <project-name>
aioson init my-app --lang=pt-BR
aioson init my-app --tool=codex
aioson init my-app --no-interactive
```

**Options:**
- `--lang=en|pt-BR|es|fr` — sets `conversation_language` in the generated context and applies the matching agent locale pack. Default: `en`.
- `--tool=codex|claude|opencode` — configures the primary AI client. Affects which gateway file is used. Default: `codex`.
- `--no-interactive` — skip the wizard and install all files (CI / automation).
- `--json` — prints structured JSON result instead of human-readable output.

**What it does:**
1. Creates `<project-name>/` directory.
2. Runs the install wizard (tools + mode selection).
3. Copies only the files matching your profile.
4. Shows the AIOSON reveal animation and install summary.
5. Applies the selected locale pack.

---

## install

Install AIOSON in an existing directory (or the current directory). Runs the same wizard as `init` when in a TTY.

```bash
aioson install
aioson install ./my-project
aioson install --lang=pt-BR --tool=claude
aioson install --reconfigure
aioson install --no-interactive
```

**Options:**
- `--lang=en|pt-BR|es|fr` — sets locale pack.
- `--tool=codex|claude|opencode` — configures AI client.
- `--reconfigure` — re-run the wizard even if a profile already exists (e.g. to add another supported tool later).
- `--no-interactive` — skip the wizard and install all files.
- `--force` — overwrite existing files.
- `--dry-run` — preview without writing.
- `--json` — prints structured JSON result.

**Use this when:**
- The project already exists (legacy codebase, existing repo).
- You want to add AIOSON to a monorepo package.

---

## update

Update managed files to the latest template version. Respects the saved install profile — only updates files that were originally installed.

```bash
aioson update
aioson update ./my-project
aioson update --lang=pt-BR
```

**Options:**
- `--lang=en|pt-BR|es|fr` — re-applies the locale pack after updating. If omitted, re-applies whatever locale is currently active.
- `--json` — prints structured JSON result.

**What it updates:** all files in the `MANAGED_FILES` list that match your install profile (agents, config, gateway files, skills). Does not touch `project.context.md`, `discovery.md`, `architecture.md`, or other context files you created.

**Output:** on completion, prints `Template version applied: <version>` (and `(<sha>, <date>)` when the install is a git checkout — e.g. an `npm link`ed dogfood setup) so you can tell exactly which template landed.

---

## info

Show CLI version, installation status, and detected framework for a directory.

```bash
aioson info
aioson info ./my-project
aioson info --json
```

**Output:**
```
aioson v0.1.25
Directory: /path/to/my-project
Installed here: yes
Framework detected: Laravel
Evidence: composer.json, artisan
```

**With `--json`:**
```json
{
  "ok": true,
  "version": "0.1.25",
  "targetDir": "/path/to/my-project",
  "installed": true,
  "detection": {
    "framework": "Laravel",
    "evidence": "composer.json, artisan"
  }
}
```

---

## doctor

Verify that all managed files are present and valid. Use `--fix` to restore any missing files.

```bash
aioson doctor
aioson doctor ./my-project
aioson doctor --fix
aioson doctor --fix --dry-run
aioson doctor --json
```

**Options:**
- `--fix` — copies missing managed files from the template. Does not overwrite existing files.
- `--dry-run` — shows what `--fix` would do without making changes.
- `--json` — structured JSON output with per-check results.

**Checks performed:**
- All files in `MANAGED_FILES` exist.
- Gateway files (`CLAUDE.md`, `AGENTS.md`, `OPENCODE.md`, `OPENCODE.md`) are present.
- `.aioson/agents/` directory is populated.
- `.aioson/context/` directory exists.

**Typical workflow after an update:**
```bash
aioson update
aioson doctor --fix
```

---

## setup:context

Interactive wizard that creates `.aioson/context/project.context.md`. This is the main context file that all agents read.

```bash
# Interactive mode
aioson setup:context

# Non-interactive (CI / scripted)
aioson setup:context --defaults
aioson setup:context --defaults --framework="Laravel" --backend="PHP" --database="MySQL"
aioson setup:context --defaults --framework="Next.js" --frontend="React" --lang=pt-BR
```

**Non-interactive flags:**
- `--defaults` — skips all prompts, uses detected or provided values.
- `--framework=<name>` — e.g. `"Laravel"`, `"Next.js"`, `"Django"`, `"Hardhat"`. Any free-text value accepted.
- `--backend=<name>` — e.g. `"PHP"`, `"Python"`, `"Node.js"`.
- `--frontend=<name>` — e.g. `"React"`, `"Vue"`, `"Livewire"`.
- `--database=<name>` — e.g. `"PostgreSQL"`, `"MySQL"`, `"SQLite"`.
- `--auth=<name>` — e.g. `"Laravel Breeze"`, `"JWT"`, `"None"`.
- `--uiux=<name>` — e.g. `"Tailwind CSS"`, `"shadcn/ui"`.
- `--classification=MICRO|SMALL|MEDIUM` — override the auto-calculated score.
- `--profile=developer|beginner|team` — sets the AI interaction style.
- `--lang=en|pt-BR|es|fr` — sets `conversation_language`.
- `--json` — structured JSON output.

**Web3 flags:**
- `--web3-enabled=true|false`
- `--web3-networks=ethereum,solana`
- `--contract-framework=Hardhat`
- `--wallet-provider=wagmi`
- `--indexer="The Graph"`
- `--rpc-provider=Alchemy`

**Brownfield / legacy project example:**
```bash
aioson install .
aioson setup:context --defaults --framework="CodeIgniter 3" --backend="PHP" --database="MySQL"
```

---

## context:digest

The session-start read the gateway block (`CLAUDE.md`, `AGENTS.md`, `OPENCODE.md`) points at: one compact JSON line (about 2–3 KB) with the `context:validate` verdict, the project's frontmatter essentials and the names of its `project.context.md` sections, the Markdown rule count (subfolders of `.aioson/rules/` included), the learnings that match `--task` (up to six, the ones sharing the most words first, each as its `[title](path)` alone), the operator-memory titles that match `--task` plus the eight ranked first, the active feature, and the command or path that opens each full version. An invalid or missing context is a verdict (`valid: false`, `issues`, `next` naming setup), never a failure.

```bash
aioson context:digest . --task="<task words>" --json
```

Pass the task as a few plain words, never the request verbatim: inside double quotes a shell still runs the backticks and `$( )` a pasted request may hold.

---

## context:brief

What a concrete agent runs at activation and before each phase: the rules and docs this task must load, the optional ones, matching skills, constraints, gaps, recall and the observations addressed to the agent. The default print is compact, because it stays in the agent's conversation: every `must_load` path with a one-line reason, optional files as paths with their size and the lines to read, and only the constraint lines that are not already in a `must_load` file (about 4–5 KB instead of 7–9 KB on real projects). `--full` prints every selection reason, section outline and constraint line; `--json` is the whole package, unchanged.

```bash
aioson context:brief . --agent=dev --mode=executing --feature=<slug> --task="<surfaces this phase builds>" [--paths=<files>] [--full] [--json]
```

---

## context:validate

Validate the existing `project.context.md` file — checks YAML frontmatter structure, required fields, and allowed values.

```bash
aioson context:validate
aioson context:validate ./my-project
aioson context:validate --json
```

**What it validates:**
- File exists at `.aioson/context/project.context.md`.
- YAML frontmatter is parseable.
- All required fields are present: `project_name`, `project_type`, `profile`, `framework`, `framework_installed`, `classification`, `conversation_language`, `aioson_version`.
- `project_type` is one of: `web_app`, `api`, `site`, `script`, `dapp`.
- `classification` is one of: `MICRO`, `SMALL`, `MEDIUM`.
- `profile` is one of: `developer`, `beginner`, `team`.

**Typical use:** run after manually editing `project.context.md` to confirm it's still valid.

```bash
# edit project.context.md
aioson context:validate
# ✓ project.context.md is valid
```

---

## agents

List all registered agents with their paths, dependencies, and outputs.

```bash
aioson agents
aioson agents ./my-project
aioson agents --json
```

**Output example:**
```
Agents (locale: en):
/aioson:agent:setup (setup)
  Path: .aioson/locales/en/agents/setup.md
  Active: .aioson/agents/setup.md
  Depends on: none
  Output: .aioson/context/project.context.md

/aioson:agent:product (product)
  Path: .aioson/locales/en/agents/product.md
  Active: .aioson/agents/product.md
  Depends on: none
  Output: .aioson/context/prd.md
...
```

The locale shown reflects the active agent locale pack (from `project.context.md` or the `--lang` flag).

---

## agent:prompt

Print the activation prompt for a specific agent, ready to paste into any AI CLI that does not support slash commands.

```bash
aioson agent:prompt setup
aioson agent:prompt setup --tool=codex
aioson agent:prompt planner --tool=claude
aioson agent:prompt dev --tool=opencode --json
```

**Arguments:**
- `<agent>` — agent id: `setup`, `briefing`, `refiner`, `product`, `sheldon`, `planner`, `dev`, `qa`, `orchestrator`, and the other shipped agents. Retired ids (`deyvin`, `analyst`, `architect`, `pm`, `ux-ui`, `scope-check`, `discovery-design-doc`) still resolve to the absorbing agent.

**Options:**
- `--tool=codex|claude|opencode` — formats the prompt for the target CLI. Default: `codex`.
- `--json` — returns structured JSON with the prompt string.

**When to use:** if you're using an AI CLI that doesn't support `/aioson:agent:setup` slash commands, run this to get the exact text to paste into the chat.

```bash
# Copy the prompt for @planner in OpenCode
aioson agent:prompt planner --tool=opencode
# → paste the output into OpenCode
```

---

## workflow:plan

Show the recommended agent sequence for the current project. `classification` controls proportional depth and budget; it does not change the canonical stage chain.

```bash
aioson workflow:plan
aioson workflow:plan ./my-project
aioson workflow:plan --classification=SMALL
aioson workflow:plan --json
```

**Options:**
- `--classification=MICRO|SMALL|MEDIUM` — override the value from `project.context.md`.
- `--json` — structured JSON with `sequence`, `commands`, and `notes` arrays.

**Output example:**
```
Workflow plan — SMALL:
  @setup
  @product
  @planner
  @dev
  @qa

Notes:
  — Framework not installed: agents will include installation steps.
```

**Canonical sequence at every classification:**

`@setup → @product → @sheldon → @planner → @dev → @qa`

Briefing and Refiner precede Product when raw sources need framing; visual scope must leave an approved owned prototype. Sheldon always enriches and hash-bind approves the PRD between Product and Planner.

`@orchestrator` is explicitly requested and never inserted by classification; the former consultants were retired into Product, Planner, Refiner, and QA. Tester, Pentester, and Validator are disabled by default.

**Feature development workflow (after initial setup):**

Once the project is set up, each new feature follows a shorter sequence — no `@setup` required:

`/aioson:agent:product → @sheldon → @planner → @dev → @qa`

`@product` creates the single feature-scoped `prd-{slug}.md`. Mandatory `@sheldon` independently reviews that same PRD and seals a current hash-bound PASS. `@planner` creates the single `implementation-plan-{slug}.md`. `@dev` implements and integrates the plan. `@qa` proves every required CAP/AC through the normal production path and writes `qa-report-{slug}.md`. Close/archive remains a separate human-authorized action.

The `SMALL` and `MEDIUM` outputs include a note reminding you of this sequence.

---

## rule:new

Scaffold a project-authored rule under `.aioson/rules/`. Rules are how a project extends agent behavior without adding an agent: `context:select` scores them by `agents`, `paths`, `triggers`, `task_types`, `priority`, and `load_tier`, so a well-formed rule reaches every agent that touches matching work.

```bash
aioson rule:new . --name=visual-quality-contract \
  --description="Our design system outranks generic visual guidance" \
  --agents=dev,qa,refiner \
  --paths="src/**,resources/**" \
  --triggers="layout,UI,component"
```

- `--name` must be kebab-case; it becomes the filename and the frontmatter `name`.
- Declare at least one of `--agents`, `--paths`, `--triggers`, or `--task-types`, or the rule is rarely selected (it warns when you don't).
- `--priority` defaults to `50`, above the framework's own 5–10 band, so a project rule outranks shipped guidance.
- `--load-tier=always` loads the rule on every activation; the default `trigger` loads it only on a match.
- It never overwrites an existing rule without `--force` — a rule on disk is project-authored content.

The generated file carries a `## Precedence` section stating that the rule outranks framework defaults, design-skill guidance, and `.aioson/brains/` nodes. Fill in the placeholder statements, then verify it:

```bash
aioson verify:artifact . --kind=rule --file=.aioson/rules/visual-quality-contract.md
```

That check proves the frontmatter routes and that the scaffold placeholders were replaced with concrete, checkable requirements.

### Born tested

`rule:new` and `doc:new` prove the new file at birth through the real brief builder (the call every agent makes): it **reaches each agent it names**, in the mode that agent actually consults in, and **stays out** of the nearest agent it does not name and of an unrelated task. Pass the words agents really use with `--examples="task one|task two"` (`|` separates tasks; each is proven for the first agent). A miss prints the cause and the frontmatter fix, for example `mode_filter — widen modes: to include planning`. The scenarios are saved to `.aioson/evals/project-knowledge.evals.json` (project-owned; `aioson update` never touches it), so `aioson context:evals .` keeps re-proving them as the catalog grows. `--no-evals` writes the file without proving it; `--aliases=a,b` adds user/domain terms to the routing.

## doc:new

Scaffold a procedure — the intelligence an agent consults when the task calls for it — under `.aioson/docs/`, with the same routing flags and the same birth proof as `rule:new`. A doc carries no `priority` (procedure, not law); `--folder=<topic>` groups it for people while routing still comes from the frontmatter.

```bash
aioson doc:new . --name=customer-integration --folder=dev \
  --description="Reuse the existing customer integration before writing a new one" \
  --agents=dev --triggers="customer integration,cadastro de clientes" \
  --examples="integrate the customer registry with the ERP"
```

## decide

Make an implementation decision once. Before choosing a library, pattern or approach, an agent asks the project:

```bash
aioson decide . --question="Which queue backs the e-mail jobs?" --options="Redis|database table" --paths=src/jobs/mailer.js
```

1. **Precedent** — a recorded decision doc under `.aioson/docs/decisions/` matches the question through a hard signal: it is printed, no model involved.
2. **Governing knowledge** — rules and docs that govern the question are listed to read first.
3. **Recommendation** — with JEV configured and no precedent, a bounded Choice over the options plus "needs a human". JEV only recommends (confidence ≥ 0.7, probability ≥ 0.6); it never records. Unsettled → raise it with `decision:add`.

Record the choice once:

```bash
aioson decide . --question="Which queue backs the e-mail jobs?" --options="Redis|database table" \
  --record --choice=Redis --why="Redis already runs in the stack" --by=@dev --triggers="queue,jobs"
```

The decision becomes a routed doc (options as aliases, the question as its birth example), proven at birth to reach the next agent who asks — a rephrased question sharing the triggers finds it as precedent. The shipped `.aioson/docs/implementation-decisions.md` is routed to agents whose task is a choice, so they learn this protocol on demand instead of from their kernel.

---

## observe / observation:list / observation:resolve

The project's working memory for what an agent notices outside its current scope: a defect beside the feature, an improvement idea, a process gap, a risk, a question a later stage will need. One line on record instead of a fix in passing or a detail the next compaction drops.

```bash
aioson observe . --kind=defect --summary="Profile avatar upload fails after the storage change" --paths=src/profile/avatar.js
aioson observe . --kind=idea --summary="Order history could offer a reorder button"
aioson observe . --kind=process --summary="Seed the test database before the walkthrough next time"
```

Kinds: `defect` · `idea` · `process` · `risk` · `question`. The feature defaults to the active one (an explicit `--feature` must be a slug; a slug with no live row in `features.md` is recorded, counts as project-wide until the feature is registered, and the command says so) and the agent to the active one; the same summary observed again raises its `seen` count; a settled one observed again reopens when it was `fixed`, or `planned`/`promoted` into a feature that has since closed or against a plan path that no longer exists, while a `dismissed` or `answered` one stays settled in any feature and prints its outcome (`--reopen` reopens it for new evidence and appends its `--detail` to the earlier one); an open item of the same kind on the same paths or in near-identical words is named as `possibly already on record`. Secrets are redacted on write. Absolute paths inside the project are stored relative; relative `--paths` are read from the directory the command runs in. Run from a subfolder, the command walks up to the project root; outside any project it writes nothing. The store is `.aioson/context/observations.json`, written only by the CLI.

Where it surfaces: `workflow:status` (`Open observations: N (defect 2, idea 1), 1 stale`, and `openObservations` in `--json` — @neo's dashboard reads it), `context:brief` and `context:select` (`Open observations for you (N)`: the items whose kind addresses the agent, ranked by its feature, then the paths it passed, then project-wide — at most five, with `+N more`; the feature's answered questions follow with their answer until it closes), the handoff (`[Observations] N open for @<next>` from `workflow:next` and `agent:done`; inside the prompt from `agent:prompt`), `feature:close` (on an accepting verdict, open items bound to the closed feature are carried to the project hub with `origin_feature` kept, never deleted; `--preflight` lists them or names an unreadable store), `hygiene:scan` (`stale_observations`: open for 30 days or more; `unreadable_observations`) and the post-compaction recap (items touched in the last 24 hours, open ones first).

```bash
aioson observation:list . [--kind=<kind>] [--feature=<slug>|project] [--all|--resolved] [--json]
aioson observation:resolve . --id=OBS-xxxxxx --as=<fixed|planned|promoted|answered|dismissed> [--ref=<plan path|feature slug>] [--why="..."] [--by=<who>]
```

`planned`/`promoted` need an existing `--ref` (a Simple Plan path, a registered feature slug or its briefing/feature folder or PRD, a rule or learning path) — an outcome recorded against nothing is refused; `dismissed`/`answered` need `--why`; `--by` defaults to `AIOSON_AGENT`, else `owner`. `observation:list` exits 1 when the store is unreadable: repair it or rename it aside, never delete it. Observations are noncanonical memory: never scope, never approval, never a gate. The routed `.aioson/docs/observations.md` carries the full protocol.

---

## verify:artifact --kind=visual

Static visual telemetry: it reads the HTML/CSS that was actually written and returns numbers instead of opinion. No browser, no build, no toolchain — identical behavior on any host or model.

```bash
aioson verify:artifact . --kind=visual --slug=orders --advisory      # the feature-owned prototype
aioson verify:artifact . --kind=visual --file=app/index.html --json
aioson verify:artifact . --kind=visual --dir=src/ui --advisory
```

Locator precedence: `--file` → `--dir` → `--slug` (resolves `.aioson/briefings/{slug}/prototype.html`).

**Metrics** (the JSON `metrics` field): token adherence (%), spacing values off the 4px grid, active depth strategies, font families, animation count and whether `prefers-reduced-motion` is handled, state coverage, maximum card nesting, media elements.

**Blocking findings** — only what is provable from the text: a decorative blob (one rule that is simultaneously absolutely positioned, fully rounded, and blurred); animation with no `prefers-reduced-motion` block; card containers nested three deep. **Warnings** — thresholds that need judgment: token adherence below 60%, five or more off-grid spacing values, three simultaneous depth strategies, more than three font families, an interactive surface with no state marker.

Heuristics that would need a DOM, a rendered layout, or taste are excluded by construction — a gate that cries wolf gets switched off within a week. Utility-class markup (Tailwind and friends) expresses tokens in HTML, so it returns `applicable: false` rather than inventing a verdict.

### `--runtime` (opt-in)

```bash
aioson verify:artifact . --kind=visual --slug=orders --runtime --advisory
```

Adds what only exists after layout, at 1280px and 360px: horizontal overflow, clipped text, elements pushed off-screen, tap targets under 44px, and real computed WCAG contrast (translucent foregrounds composited against the nearest opaque ancestor). Playwright is an optional dependency, exactly as for `qa:run`; when it is absent the run reports that it did not happen instead of degrading into a pass.

`--screenshots` stores a first-fold capture per route and width under `.aioson/context/features/{slug}/visual-screenshots/` (`--screenshots=full` keeps whole pages; `--screenshot-dir=<dir>` names another folder, which is never cleared). Nothing in the default folder is removed before the browser has measured; then a `--slug` run over the whole matrix removes the captures it did not produce, while a run narrowed by `--route`/`--routes` (and every slug-less run) replaces only its own. A `--no-persist` run writes no capture there (pass `--screenshot-dir` for a diagnostic one). The evidence records what the folder holds (`metrics.runtime.screenshot_capture`: dir, mode, count, bytes), and a fold finding names the capture that shows it. Captures are regenerable diagnostics, not evidence: the installer's gitignore policy keeps them out of the repository, `feature:archive` drops them when the feature closes, and `evidence:prune` removes them. A later static measurement of the same bytes (the `agent:done` auto-fire included) carries the `runtime` section forward instead of erasing it; a changed prototype gets `runtime evidence dropped` and needs `--runtime` again.

`prototype:check` runs the same telemetry automatically whenever it resolves an owned prototype, always as an advisory block — it never changes the binding verdict.

---

## briefing:sources

Discover heterogeneous source packs under `plans/{slug}/` without requiring a manifest or changing the user's physical organization.

```bash
aioson briefing:sources . --json
aioson briefing:sources . --slug=legacy-system --json
```

- Without `--slug`, it lists selectable directories and backward-compatible loose files under `plans/` without loading content.
- Conventional archive roots such as `plans/done/` are excluded from new-pack candidates and reported in `ignored_directories`.
- With `--slug`, it fingerprints and classifies every source, builds logical groups, and orders detectable SQL migrations.
- Packs may mix Markdown, SQL, contracts, source code, examples, and references in any physical layout.
- It never moves, renames, or executes sources; credentials, binary databases, large files, and row-bearing dumps receive restrictive load policies.
- `load_modules` tells `@briefing` which specialized modules are justified for that selected pack.

---

## briefing:migrate-lineage

Preview or migrate a registered legacy briefing to the canonical `Source Inventory` and `Source Promise Map` schemas.

```bash
aioson briefing:migrate-lineage . --slug=legacy-feature
aioson briefing:migrate-lineage . --slug=legacy-feature --dry-run --json
aioson briefing:migrate-lineage . --slug=legacy-feature --write
```

- Preview is the default and changes no files; `--dry-run` makes that intent explicit.
- `--write` is mutually exclusive with `--dry-run`. It uses the analyzed briefing hash as a compare-and-swap precondition.
- Draft, approved, and approved-with-generated-PRD registry entries are supported.
- Only lineage sections in `briefings.md` are rewritten. Registry, PRD, implementation plan, prototype, and historical review files remain unchanged.
- Real source-pack files under `plans/` receive canonical IDs and SHA-256 fingerprints. Research, code, URLs, conversations, and unavailable post-PRD prework remain complementary non-canonical evidence.
- Successful writes create a content-addressed backup and immutable JSON audit report under `.aioson/briefings/{slug}/lineage-migration/`.
- Repeating `--write` on a canonical briefing changes no bytes and creates no new backup or report.
- Invalid/traversing slugs, real-path escapes, ambiguous promises, incomplete generated-PRD coverage, concurrent edits, and conflicting write flags fail before destructive mutation.

Run the relevant `review:prepare` flow only for agents listed in `affected_reviews`, then rerun the normal artifact/gate validation.

---

## Visual exploration commands

These commands manage non-canonical design candidates under `.aioson/explorations/{slug}/`:

| Command | Purpose |
|---|---|
| `exploration:init` | Create frozen task/intake scaffolding and choose single, sequential, or arena policy. |
| `exploration:configure` | Change open exploration defaults; use it to grow `single` into `sequential` without overwriting the first run. |
| `exploration:references` | Copy and fingerprint supplied screenshots/reference files. |
| `exploration:intake` | Validate and persist the confirmed understanding and screenshot coverage. |
| `exploration:scan` | Produce a bounded current-front-end source inventory (`none`, `targeted`, or `full`). |
| `exploration:add-run` | Allocate one immutable variant for manual/native generation. |
| `exploration:record` | Validate and record a completed or failed variant with exact model provenance. |
| `exploration:run` | Run explicitly bound `host:model` variants through read-only external adapters. |
| `exploration:validate` / `exploration:status` | Check intake, artifacts, and current structured state. |
| `exploration:review` | Generate the blind/labeled browser comparison and feedback JSON. |
| `exploration:select` | Apply exported feedback or select a completed variant. |
| `exploration:promote` | Create a fingerprinted `plans/{briefing-slug}/visual-exploration.md` source pack. |

See [Visual exploration and multi-model arena](../3-recipes/visual-exploration-arena.md) for the end-to-end flow. Selection is not Briefing approval.

---

## workflow:next

Advance the active workflow, complete the current stage, trigger a controlled detour, or skip ahead until `@dev`.

```bash
aioson workflow:next
aioson workflow:next ./my-project --tool=codex
aioson workflow:next ./my-project --complete
aioson workflow:next ./my-project --agent=pentester
aioson workflow:next ./my-project --skip=dev
```

**What it does:**
- initializes `.aioson/context/workflow.state.json` if it does not exist
- infers the current project stage from canonical artifacts such as `project.context.md`, `prd-{slug}.md`, `implementation-plan-{slug}.md`, and `qa-report-{slug}.md`
- follows the canonical sequence; classification adjusts proportional work inside a stage rather than changing stage order
- supports detours such as `--agent=pentester`, then returns to the saved next stage automatically
- allows skipping ahead only until `@dev`; it never allows skipping past `@dev`

**Notes:**
- `workflow:next` is the canonical command
- `agent:next` is an alias for compatibility
- `workflow.config.json` and `workflow.state.json` live under `.aioson/context/`, so normal framework updates preserve them
- **the binding follows the feature registry.** `workflow.state.json` is bound to the feature `project-pulse.md` names as `active_feature` (the single source of truth `feature:current` answers from) when that feature is `in_progress` in `features.md`; the last handoff and the last feature in progress are the fallbacks. When the registry moves (`aioson pulse:update . --feature=<slug>` — `--feature` alone, without `--agent`, moves only `active_feature`; a feature not `in_progress` in `features.md` does not bind the workflow, and the command says so), the next `workflow:next` or `workflow:status` moves the binding with it: the previous feature's progress is archived at `.aioson/context/features/<slug>/workflow.state.json` (never discarded) and restored when the registry returns to it; a `binding_moved` event is appended to `workflow.events.jsonl` (also on the `--expect-feature` path and when `workflow:execute --feature=<slug>` moves the binding, which archives and restores the same way). A slug outside the canonical feature-slug rule has no archive: the move warns and skips it. The QA→Dev cycle budget is per feature — another feature's cycle file is parked under `.aioson/runtime/review-cycles/<slug>/`, never reset or overwritten. The state file is derived — edit the registry, never the JSON. `--expect-feature=<slug>` still guards explicit continuation, and its mismatch message names where the binding comes from (the registry, or the fallback it fell back to).

### workflow:execute --seed (full-feature autopilot)

`aioson workflow:execute . --feature=<slug> --seed --tool=<tool>` seeds the agentic scheme (`.aioson/context/workflow-execute.json` with `agentic_policy.enabled: true`) without advancing a stage. Product, Sheldon, or Planner may seed the canonical chain described in [Autopilot handoff](./autopilot-handoff.md). Add `--step` to seed it disarmed. A stale `workflow.state.json` left by a closed/abandoned feature is discarded and reseeded automatically; a genuinely different active feature returns `different_active_feature`.

New `agent-execution-{slug}.json` manifests use schema v2 and default to `orchestration.mode: autopilot`. `workflow:execute` uses `orchestration.max_checkpoints` (10 by default) rather than the legacy one-transition default. The mode also accepts `inherit` or `step_by_step`; create-once manifests are never rewritten by resume/reseed and explicit `--step` still wins.

---

## feature:close

Close a feature after QA sign-off, updating the spec, features registry, and project pulse — and automatically archive all feature artefacts on PASS. When feature completeness applies, PASS also requires a fresh successful `harness:check` result mapped to every required CAP/AC; ledger status strings alone are not proof.

```bash
aioson feature:close . --feature=checkout --verdict=PASS --residual="none"
aioson feature:close . --feature=checkout --verdict=FAIL --notes="critical auth bug"
aioson feature:close . --feature=checkout --verdict=PASS --no-archive
```

**Options:**
- `--feature=<slug>` — feature identifier (required).
- `--verdict=PASS|FAIL` — QA result (required).
- `--residual="..."` — residual risks or open notes for PASS (optional).
- `--notes="..."` — failure reason for FAIL (optional).
- `--no-archive` — skip automatic archival (useful for idempotent re-runs).
- `--json` — structured JSON output.

**What it does:**
1. Appends a `## QA sign-off` section to `spec-{slug}.md`.
2. Updates `features.md` with the new status (`done` or `qa_failed`) and completed date, rewriting the index in its canonical shape; any note about this feature left inside `features.md` moves to `features/{slug}/registry-notes.md`, so it is archived with the feature.
3. Clears active work from `project-pulse.md`.
4. If `verdict=PASS` and `--no-archive` is not set, calls `feature:archive` automatically to move all artefacts to `.aioson/context/done/{slug}/`.

**When to use:** after reviewing QA's verdict, when the user explicitly authorizes close/archive. QA and autopilot never run it automatically.

---

## feature:register / feature:tidy

`features.md` is a rows-only index (slug, status, started, completed): a count summary, then one table per situation — **In progress** (including `qa_failed`/`qa_blocked`, in file order, because the workflow binding reads the last `in_progress` row), **Planning**, **Paused**, **Done** and **Abandoned** (newest first); empty sections are omitted. Agents never hand-edit it: decisions, scope history and pause reasons belong in the feature folder (`.aioson/context/features/{slug}/`), which leaves with the feature when it is archived.

```bash
aioson feature:register . --feature=checkout                    # new row, in_progress, started today
aioson feature:register . --feature=checkout --status=paused    # move an existing row
aioson feature:tidy . --dry-run                                  # preview the migration
aioson feature:tidy .                                            # apply it
```

- `feature:register` upserts one row; `--status` accepts `planning`, `in_progress`, `paused`, `qa_failed`, `qa_blocked`, `abandoned` (sets the completed date). `done` is refused — only `feature:close` closes a feature.
- `feature:tidy` migrates an index that grew narrative: rows are regrouped into one table per situation (rows that sat outside a table header are rejoined; for a duplicated slug the last row wins and the earlier one is kept as a note), and every `<!-- slug: … -->` note moves verbatim to `registry-notes.md` in that feature's folder — live (`features/{slug}/`) or archived (`done/{slug}/dossier/`). Notes naming no registered feature go to `done/registry-notes.md`. The previous file is kept in `.aioson/backups/features-registry/`.
- `aioson doctor` warns when the index carries notes, headerless rows or status spellings no reader matches (`in-progress`, `active`, `em andamento`…), `aioson doctor --fix` runs the same migration, and `aioson update` prints the advisory — it never rewrites `features.md` itself.
- Spellings with a canonical meaning are rewritten by `feature:tidy` (`in-progress`/`active` → `in_progress`, `on-hold` → `paused`, `draft` → `planning`, `cancelled` → `abandoned`). Delivery spellings (`completed`, `shipped`) are never mapped to `done`.

---

## feature:triage

Measures where every registered feature really stands and cleans the lifecycle through the commands that own it. Read-only without flags; `@neo` runs it in its guarded feature-lifecycle mode.

```bash
aioson feature:triage .                                   # report (add --json)
aioson feature:triage . --apply --dry-run                 # preview the mechanical fixes
aioson feature:triage . --apply                           # rewrite spellings, archive closed work, clear a pulse naming a closed feature
aioson feature:triage . --close=checkout --pause=search --abandon=old-import --resume=reports
```

| Finding | Decided by | Meaning |
|---|---|---|
| `ready_to_close` | owner | QA verdict PASS (or ACCEPTED_WITH_FOLLOWUPS) and the row is still open. `changed_after_qa` marks a spec/plan rewritten after the verdict — re-verify first |
| `stale_open` / `stale_paused` | owner | No artifact activity for `--stale-days` (21) / `--paused-days` (60); the active feature is never stale |
| `status_alias` / `unknown_status` | mechanical / owner | A spelling no reader matches / a status with no lifecycle meaning |
| `closed_not_archived` | mechanical | `done`/`abandoned` row whose files are still in the live context |
| `active_is_closed` / `active_not_registered` | mechanical / owner | The pulse names a closed feature / a slug nothing in the project carries |

- Every decision is checked before any runs; one refusal (no current QA PASS, spec changed after QA, active feature without `--include-active`, wrong status) and nothing changes.
- `--close` runs `feature:close` with the verdict QA recorded. Its gates still apply: a blocked close is reported with its `--preflight` command and never forced.
- `--pause`/`--abandon`/`--resume` go through `feature:register` (abandoning archives to `abandoned/{slug}/`).
- `hygiene:scan` carries the same findings in `features_ready_to_close`, `stale_features` and `feature_status_aliases`.

---

## evidence:prune

Remove the regenerable binaries the visual and browser gates leave beside their reports — runtime captures under `visual-screenshots/` and per-step snapshots and screenshots under `browser/{script}/` — never the reports themselves.

```bash
aioson evidence:prune . --dry-run
aioson evidence:prune . --slug=checkout
aioson evidence:prune . --all
```

- Default scope: orphans — files the latest report no longer references (a failure snapshot of a step that passes now, a capture of a route since renamed).
- `--all` removes every capture and snapshot; each report carries the line that regenerates its folder (`Replay:` in a walkthrough report, `verify:artifact --kind=visual --runtime --screenshots` for captures).
- `--slug=<feature>` narrows to one owner (feature, briefing, or archived feature); `--dry-run` counts without deleting; `--json` returns the per-folder table.

`hygiene:scan` lists the same folders under `heavy_evidence_artifacts` when they are orphaned or above 1 MB, and `feature:archive` drops them (instead of moving them into `done/`) unless `--keep-diagnostics` is passed.

---

## storage:triage

How much disk aioson itself takes — in the project, and with `--global` on the machine — and the cleanup that is safe. Read-only without flags.

```bash
aioson storage:triage .                                   # report (add --json)
aioson storage:triage . --global                          # every project's doc snapshots + the old machine-wide recall index
aioson storage:triage . --apply --dry-run                 # preview the mechanical cleanup
aioson storage:triage . --apply                           # retention + log trimming
aioson storage:triage . --remove=.aioson/runtime/scratch-db --dry-run
```

| Finding | Decides | What `--apply` / `--remove` does |
|---|---|---|
| `doc_snapshots` | auto | Keeps the newest 10 doc snapshots `agent:done` took in `~/.aioson/backups/{project}/` and removes the rest |
| `rollback_backups` | auto | Keeps the newest 5 update rollback folders in `.aioson/backups/` and removes the rest |
| `oversized_log` | auto | Trims a `.log`/`.out`/`.err` above 20 MB inside `.aioson/` to its first 64 KB and last 256 KB (a log written in the last 10 minutes is left alone) |
| `legacy_recall_index` | auto | `--global`: retires `~/.aioson/search/context-search.sqlite`, the recall index every project shared before each kept its own |
| `heavy_path` | owner | A path of 50 MB or more aioson cannot regenerate: scratch under `.aioson/runtime/` or `.aioson/tmp/`, a backup aioson did not write, a `researchs/{slug}` folder, a file someone left in `~/.aioson/search/` (`--global`). Removed only by `--remove=<path>`, exactly as the report prints it |

- One `--remove` path the report did not list refuses the whole call and nothing changes. Links are never followed; the runtime database, live sessions and the evidence binaries keep their own procedures (`runtime:prune`, `agent:recover`, `evidence:prune`).
- The producers keep the same retention on their own: `agent:done` (and `backup:local`) skips a snapshot when nothing changed, leaves closed-feature archives (`done/`, `abandoned/`) out of it, never snapshots a project that lives under the OS temp folder into `~/.aioson` (set `AIOSON_BACKUPS_DIR` to keep one elsewhere), and keeps the newest 10; `aioson update` keeps the newest 5 rollback folders.
- `hygiene:scan` lists what is left under `disk_footprint` (an owner path listed in `.aioson/context/hygiene-retention.md` is no longer reported), and `doctor`/`update` warn (`runtime:disk_footprint`) while retention is past due.
- The recall index (`context:search`, `context:brief --recall`) lives in each project's `.aioson/runtime/context-search.sqlite` (gitignored): rebuilt from the project's Markdown when missing, deleted with the project, never a cleanup target. A folder that is not an AIOSON project is indexed in memory only, and opening a project's own index retires the old machine-wide one.

---

## feature:archive

Move feature artefacts to the archive directory and maintain a manifest for lightweight historical lookup.

```bash
aioson feature:archive . --feature=checkout
aioson feature:archive . --feature=checkout --dry-run
aioson feature:archive . --feature=checkout --restore
aioson feature:archive . --feature=checkout --restore --dry-run
aioson feature:archive . --feature=checkout --force
```

**Options:**
- `--feature=<slug>` — feature identifier (required).
- `--dry-run` — preview what would be moved or restored without making changes.
- `--keep-diagnostics` — archive the regenerable browser evidence (`visual-screenshots/`, `browser/{script}/`) instead of dropping it; by default the reports travel and the binaries are removed, with the count and bytes in the output.
- `--restore` — move artefacts back from `.aioson/context/done/{slug}/` to the context root.
- `--force` — archive even if the feature is not registered in `features.md` or is still `in_progress`.
- `--json` — structured JSON output with `moved`, `skipped`, `archiveDir`, and `manifestEntry`.

**What it moves:** any file in the root of `.aioson/context/` whose name contains the feature slug: `prd-{slug}.md`, `spec-{slug}.md`, `requirements-{slug}.md`, `sheldon-enrichment-{slug}.md`, `qa-report-{slug}.md`, `conformance-{slug}.yaml`, etc.

**What it never moves:** global files (`project.context.md`, `project-pulse.md`, `features.md`, `discovery.md`, etc.) and subdirectories (`bootstrap/`, `forensics/`, `parallel/`, `done/`).

**Manifest:** after each archive run, `.aioson/context/done/MANIFEST.md` is updated with a row summarizing the feature. Agents like `@briefing`, `@neo`, `@discover`, and `@sheldon` read this manifest instead of loading full archived files.

---

## feature:export

**Copy** all artefacts of a feature into a clean output directory, leaving the source tree untouched. Sibling of `feature:archive`, but a non-destructive copy to an arbitrary `--out` — turns AIOSON's markdown output into a portable deliverable. Use it to analyse a feature's specs outside the project, hand them to a client, or use AIOSON purely as a spec generator.

```bash
aioson feature:export . --feature=checkout
aioson feature:export . --feature=checkout --out=../checkout-specs
aioson feature:export . --feature=checkout --flatten
aioson feature:export . --feature=checkout --no-index
aioson feature:export . --feature=checkout --dry-run --json
```

**Options:**
- `--feature=<slug>` — feature identifier (required).
- `--out=<dir>` — destination directory. Default: `<target>/{slug}-export`.
- `--flatten` — collapse the mirrored structure into a single level; nested files become `label-...-file.ext` (collision-free). Default: mirrored (`dossier/`, `plans/`, `briefings/`, `done/`).
- `--no-index` — skip the generated `INDEX.md`. Default: an `INDEX.md` manifest is written listing every exported file and its source.
- `--dry-run` — preview what would be copied without writing anything.
- `--json` — structured JSON output with `outDir`, `count`, `copied`, and `index`.

**What it copies:** the same surface `feature:archive` enumerates — root `*-{slug}.{md,yaml,yml,json}` files (minus global files), the per-slug `dossier/`, `plans/`, and `briefings/` directories, plus `context/done/{slug}/` when the feature is already archived. The slug-collision guard is honoured, so a sibling slug (`checkout-v2`) never leaks into a `checkout` export.

**Non-destructive:** the source artefacts are never moved or deleted. Re-running overwrites files in the out dir but does not remove stale ones. Unlike `feature:archive`, there is no `features.md` status guard — you can export an in-progress feature.

---

## test:smoke

End-to-end integration test that installs AIOSON in a temporary directory, runs all major commands, and verifies the output. Used for CI and release validation.

```bash
aioson test:smoke
aioson test:smoke --lang=pt-BR
aioson test:smoke --web3=ethereum
aioson test:smoke --web3=solana
aioson test:smoke --web3=cardano
aioson test:smoke --profile=mixed
aioson test:smoke --profile=parallel
aioson test:smoke --keep
aioson test:smoke --json
```

**Options:**
- `--lang=en|pt-BR|es|fr` — runs the test with the given locale active.
- `--web3=ethereum|solana|cardano` — seeds a Web3 project structure and tests Web3 context generation.
- `--profile=standard|mixed|parallel` — `standard` runs the default flow; `mixed` runs a combined locale+web3 test; `parallel` includes `parallel:init` and `parallel:assign`.
- `--keep` — preserves the temporary directory after the test for inspection.
- `--json` — structured JSON output with per-step results.

**What the standard profile tests:**
1. `install` in temp dir
2. `setup:context --defaults`
3. `locale:apply`
4. `agents` list
5. `agent:prompt setup`
6. `context:validate`
7. `doctor`
8. `update`
9. `workflow:plan`

**Note:** this command is intended for contributors and CI pipelines, not for daily project use.

---

## test:package

Simulate `npm pack` in a temporary directory to verify what would be published and that the package installs correctly.

```bash
aioson test:package
aioson test:package ./path/to/source
aioson test:package --keep
aioson test:package --dry-run
aioson test:package --json
```

**Options:**
- `--keep` — preserves the temp directory after the test.
- `--dry-run` — checks prerequisites without actually running `npm pack`.
- `--json` — structured JSON output.

**What it does:**
1. Runs `npm pack` on the source directory.
2. Extracts the `.tgz` in a temporary directory.
3. Verifies the key files are present in the package.
4. Reports pass/fail.

**Note:** requires Node.js and npm to be available. Intended for release validation.

---

## context:load

Record that an agent loaded a rule or brain. Writes a `rule_loaded` or `brain_loaded` event to `execution_events`. Used by the Active Learning Loop to detect stale rules.

**Tier:** 1 (silent — no output by default)

```bash
aioson context:load --target=rule:authn-rules --agent=dev
aioson context:load --target=brain:sheldon-005 --agent=sheldon --feature=auth-flow --verbose
aioson context:load --target=rule:authn-rules --agent=dev --batch="jwt-patterns,session-mgmt" --json
```

**Options:**
- `--target=<rule|brain>:<slug>` — **required**. Type and identifier. E.g. `rule:authn-rules`, `brain:sheldon-005`.
- `--agent=<name>` — **required**. Agent name loading the rule/brain.
- `--batch="a,b,c"` — additional slugs to register in one transaction (same type and agent).
- `--feature=<slug>` — associate with an active feature (stored in payload).
- `--verbose` — print a confirmation line per event.
- `--json` — structured JSON output `{ ok, event, target, agent }`.

**Behavior:** creates a row in `execution_events` with `event_type='rule_loaded'` or `'brain_loaded'`. No filesystem validation — pure telemetry. Payload capped at 4KB; paths normalized to forward-slash cross-platform.

See [Active Learning Loop — CLI reference](../active-learning-loop/cli-commands.md) for full details.

---

## Neural Chain impact queue

Neural Chain stores causal follow-up work in `chain_work_items` inside `.aioson/runtime/aios.sqlite`. Files under `.aioson/context/noises/` are stable, human-readable projections; they are no longer the authoritative queue.

```bash
aioson chain:list . --feature=checkout --json
aioson chain:claim . --id=NC-12 --agent=dev --json
aioson chain:resolve . --id=NC-12 --agent=dev --token=<claim-token> \
  --outcome=verified-no-change --evidence="target inspected; focused tests passed"
aioson chain:release . --id=NC-12 --agent=dev --token=<claim-token>
aioson chain:reconcile . --json
```

- `chain:list` lists actionable work; add `--include-resolved` for history.
- `chain:claim` atomically leases one or more items so parallel DEV runs do not duplicate work. Expired leases reopen automatically.
- `chain:resolve` requires a claim token and concrete evidence. Supported outcomes are `fixed`, `verified-no-change`, `false-positive`, and `obsolete`.
- `chain:release` returns unfinished work to the queue.
- `chain:reconcile` imports legacy timestamped noise files, applies manually checked projection items, releases expired claims, and regenerates projections.

An item is evidence that a relationship should be inspected, not proof that its target needs an edit. Repeated false positives reduce confidence and eventually retire the relation. Weak one-off co-edit correlations are not materialized unless stronger test or repeated evidence exists.

---

## memory:search

BM25 full-text search over `project_learnings` (title + evidence) via SQLite FTS5.

**Tier:** 1 (silent — no notify emitted)

```bash
aioson memory:search "authentication JWT"
aioson memory:search "rate limiting" --surface=rules --limit=10 --json
aioson memory:search "session" --include-archived
```

**Options:**
- `"<query>"` — **required**. Search text, max 500 chars.
- `[path]` — project root directory (default: `.`).
- `--limit=N` — max results (default: 5).
- `--surface=<value>` — where to search: `rules`, `learnings` (default), or `all`.
- `--include-archived` — include entries with status `archived`.
- `--json` — structured JSON output `{ ok, query, results[], total }`.

**Query sanitization:** each whitespace-separated token is wrapped in phrase quotes and AND-ed. FTS5 operator characters are stripped before conversion.

See [Active Learning Loop — CLI reference](../active-learning-loop/cli-commands.md) for full details.

---

## memory:archive

Archive a rule, learning, or brain: moves the file to `_archived/YYYY-MM-DD/` and records history in `evolution_log`.

**Tier:** 2 (notified — emits `notify --level=warn` before mutation). **Human-only:** refuses when `AIOSON_RUNTIME_HOOK=1`.

```bash
aioson memory:archive --id=rule:legacy-session-cookies --reason="replaced by JWT auth" --dry-run
aioson memory:archive --id=rule:legacy-session-cookies --reason="replaced by JWT auth"
aioson memory:archive --id=learning:jwt-draft-1 --reason="superseded" --feature=auth-flow --json
```

**Options:**
- `--id=<rule|learning|brain>:<slug>` — **required**. Type and slug.
- `--reason="<text>"` — **required**. Archival reason (stored in `evolution_log`).
- `--feature=<slug>` — associate with a feature for traceability.
- `--dry-run` — simulate with zero side effects.
- `--json` — structured JSON output.

**Behavior:** atomic (BEGIN TRANSACTION → move file → INSERT evolution_log → COMMIT). Idempotent: re-archive of already-archived target returns `already_archived`. Cross-volume fallback via copy+unlink.

See [Active Learning Loop — CLI reference](../active-learning-loop/cli-commands.md) for full details.

---

## memory:restore

Restore an archived rule, learning, or brain to its original path. Records `event_type='restored'` in `evolution_log`.

**Tier:** 2 (notified). **Human-only:** refuses when `AIOSON_RUNTIME_HOOK=1`.

```bash
aioson memory:restore --id=rule:rate-limiting-rules --dry-run
aioson memory:restore --id=rule:rate-limiting-rules --reason="still needed — removal was premature"
```

**Options:**
- `--id=<rule|learning|brain>:<slug>` — **required**.
- `--reason="<text>"` — archival reason (optional but recommended).
- `--feature=<slug>` — associate with a feature.
- `--dry-run` — simulate with zero side effects.
- `--json` — structured JSON output.

See [Active Learning Loop — CLI reference](../active-learning-loop/cli-commands.md) for full details.

---

## scout:prep

Prepare a sub-task scout: validate inputs, check caps, and generate the standardized prompt for the harness sub-agent.

**Tier:** 1 (silent — use `--json`)

```bash
aioson scout:prep \
  --question="Why does workflow:next inherit stale completion records?" \
  --scope-paths="src/commands/workflow-next.js,src/handoff-contract.js" \
  --parent-agent=dev \
  --parent-session-id=sess-abc123 \
  --parent-session-excerpt="User reported state inheritance bug; inspect loadOrCreateState" \
  --feature-slug=current-feature \
  --json
```

**Options:**
- `--question="<text>"` — **required**. The question the sub-agent must answer.
- `--scope-paths="<paths>"` — **required**. Comma-separated files/dirs. Directories expand 1 level.
- `--parent-agent=<name>` — **required**. Use `"dev"` (the legacy `"deyvin"` is still accepted).
- `--parent-session-id=<id>` — **required**. Session ID for cap tracking.
- `--parent-session-excerpt="<text>"` — **required** (50-1000 chars). Why the scout was dispatched — cold-load comprehension field; blocked if absent.
- `--feature-slug=<slug>` — associate with feature for archival on `feature:close`.
- `--json` — structured output `{ ok, id, prompt, output_path, cap_remaining }`.

**Exit codes:** 0 = prepared; 2 = invalid arg, cap exceeded, scope too large, path outside root.

See [Sub-task Scout — CLI reference](../deyvin-subtask-scout/cli-commands.md) for full details.

---

## scout:validate

Validate the JSON returned by the sub-agent against the output schema. Tracks retries in the state file.

**Tier:** 1 (silent)

```bash
aioson scout:validate --input=.aioson/runtime/scouts/scout-2026-05-14-a3b7c1.json
aioson scout:validate --input=<path> --json
```

**Options:**
- `--input=<path>` — **required**. Path to the JSON file the sub-agent wrote.
- `--json` — structured output on failure: `{ ok, error: { code, details[] }, retry_remaining }`.

**Exit codes:** 0 = PASS; 2 = schema invalid, retry exhausted, file not found.

See [Sub-task Scout — CLI reference](../deyvin-subtask-scout/cli-commands.md) for full details.

---

## scout:commit

Persist the validated scout report, emit telemetry, and decrement the cap counter.

**Tier:** 1 (silent)

```bash
aioson scout:commit --input=.aioson/runtime/scouts/scout-2026-05-14-a3b7c1.json
aioson scout:commit --input=<path> --json
```

**Options:**
- `--input=<path>` — **required**. Path to the validated JSON.
- `--json` — structured output `{ ok, committed, id, path, cap_remaining }`.

**Behavior:** idempotent — re-commit of same id returns `{ committed: false, reason: "already_committed" }`. Emits `type=sub_task action=committed` to `agent_events`.

**Exit codes:** 0 = committed (or no-op); 1 = file not found, lock failure.

See [Sub-task Scout — CLI reference](../deyvin-subtask-scout/cli-commands.md) for full details.

---

## harness:check

Run the `criteria[].verification` shell commands from `harness-contract.json` deterministically — **outside** the self:loop and **read-only** over `progress.json`. Each criterion's command runs in the sandbox; exit code `0` = pass. Reuses the loop's `runCriteria`/`executeInSandbox` machinery (timeouts, process-tree kill, credential redaction, failure signatures). Persists `last-check-output.json` and emits `criteria_check_failed` telemetry on failure.

```bash
# Run every verifiable criterion of the active contract (auto-discovered)
aioson harness:check . --slug=checkout

# Run only a subset of criteria
aioson harness:check . --slug=checkout --criteria=C1,C3

# Custom timeout and JSON output (exit 0 = pass)
aioson harness:check . --slug=checkout --timeout=120000 --json

# Strict mode: binary criteria without verification block the result
aioson harness:check . --slug=checkout --strict
```

**Options:**
- `--slug=<feature>` — feature slug matching the harness contract. If omitted, the active contract is auto-discovered.
- `--criteria=C1,C2` — run only the listed criteria instead of all verifiable ones.
- `--timeout=<ms>` — per-criterion timeout override.
- `--strict` — fail when binary criteria lack executable `verification` or no executable criterion exists.
- `--json` — structured output; exit code propagated.

**What it does:** the `verification` field is authored per criterion by `@sheldon` for every mechanically-checkable `binary: true` criterion (prefer the project test runner; deterministic; cross-platform; exit 0 = pass). `harness:check` is the standalone deterministic verification of those criteria — it never touches the circuit-breaker state (that stays exclusive to `harness:validate`/`apply-validation`). Legacy contracts without `verification` remain valid; `validateContract` only emits an advisory **warning** for `binary: true` criteria lacking it. `@validator` runs `harness:check` first and copies the exit-code verdicts verbatim into `results[].passed`, LLM-judging only the criteria without `verification`.

See [Executable verification](./executable-verification.md) for the full theme.

---

## ac:test-audit

Map declared acceptance criteria to deterministic test evidence.

```bash
aioson ac:test-audit . --feature=checkout
aioson ac:test-audit . --feature=checkout --strict
aioson ac:test-audit . --feature=checkout --json
```

**What it does:** extracts `AC-*` IDs from `requirements-{slug}.md`, `prd-{slug}.md`, and `conformance-{slug}.yaml`, then maps each ID to an asserting test or a criterion proven by the latest successful `harness:check`. `--strict` rejects zero ACs plus skipped, todo, commented, string-only, or assertion-free pseudo-evidence. Gate D additionally requires the harness result to be newer than the traced feature artifacts and implementation files.

---

## sdd:benchmark

Generate a deterministic SDD quality snapshot for a feature.

```bash
aioson sdd:benchmark . --feature=checkout
aioson sdd:benchmark . --feature=checkout --strict --json
```

**What it does:** combines artifact presence, `spec:analyze`, and `ac:test-audit` into a reproducible score and writes `.aioson/context/retro/sdd-benchmark-{slug}.md`.

---

## harness:validate

Generate the `validator-prompt.txt` for the binary success contract and append a self-contained **review payload** so the validator can judge in a fresh, isolated context. Consumes the verdict back through the circuit breaker.

```bash
# Generate the validator prompt with review payload
aioson harness:validate . --slug=checkout

# Resolve the diff against an explicit base
aioson harness:validate . --slug=checkout --base=main

# Skip the diff (review payload still includes check results + changed files)
aioson harness:validate . --slug=checkout --no-diff

# Cap the embedded diff size
aioson harness:validate . --slug=checkout --max-diff-bytes=200000
```

**Options:**
- `--slug=<feature>` — **required**. Feature slug matching the harness contract.
- `--base=<ref>` — git ref to diff against. Resolution order: `--base` > `baseline.json` head > merge-base with `main`/`master` > `HEAD`.
- `--no-diff` — pure boolean flag; omit the unified diff from the review payload.
- `--max-diff-bytes=<n>` — cap the embedded diff (default `200000`); truncation happens on a line boundary.

**What it does:** the review payload (built by `src/harness/review-payload.js`) contains (a) the `harness:check` results, (b) the changed-file list (untracked files included, `.aioson/**` framework state filtered out), and (c) a unified diff against the resolved base. It degrades gracefully outside a git repo. The protocol is that `@validator` runs in a **fresh, isolated context** (a subagent / Task tool, or a separate session) — never inline in the implementing session, because implementation history biases the verdict. Typical flow: `harness:check` → `harness:validate` → isolated subagent run → re-run `harness:validate` to consume the verdict through the circuit breaker.

See [Executable verification](./executable-verification.md) for the full theme.

---

## harness:approve

Approve a pending human gate in the self:loop (loop guardrails). Persists the decision (who, when) to `.aioson/plans/{slug}/gates/{id}.json` and resumes the loop.

```bash
aioson harness:approve . --slug=<feature> --gate=<gate-id>
aioson harness:approve . --slug=checkout --gate=database_destructive_change-1
```

**Options:**
- `--slug=<feature>` — **required**. Feature slug matching the harness contract.
- `--gate=<id>` — **required**. Gate id shown in `harness:status` output.
- `--by=<name>` — override the "decided by" field (defaults to `git config user.name`).

**Idempotent:** re-approving an already-decided gate is a no-op with a warning.

---

## harness:reject

Reject a pending human gate. Ends the current loop attempt with a summary. Requires `--reason`.

```bash
aioson harness:reject . --slug=<feature> --gate=<gate-id> --reason="needs revert"
```

**Options:**
- `--slug`, `--gate` — same as `harness:approve`.
- `--reason=<text>` — **required** on reject. Recorded in the gate decision file.

---

## harness:status

Human-readable view of the current loop state for a feature.

```bash
aioson harness:status . --slug=<feature>
aioson harness:status . --slug=checkout --json
```

**Shows:** circuit state (open/closed), current iteration / max, estimated token budget (used/ceiling), last-attempt checks (passed/failed), last failure signature, pending human gates, and recommended next action.

**Options:**
- `--slug=<feature>` — **required**.
- `--json` — structured output.

---

## harness:retro

Deterministically mine the failure trail of a feature and materialize a retrospective dossier at `.aioson/context/retro/{slug}.md`. LLM-free, network-free. Source files are never modified.

```bash
aioson harness:retro . --feature=<slug>
aioson harness:retro . --last=<N>          # last N features by PASS date
aioson harness:retro . --feature=checkout --json
```

**Options:**
- `--feature=<slug>` — mine a specific feature (mutually exclusive with `--last`).
- `--last=<N>` — mine the N most recently completed features.
- `--json` — structured output; exit codes are propagated.
- `--locale=<l>` — output locale (default: project `interaction_language`).

**Exit codes:** 0 = success (including empty dossier); 1 = unexpected I/O error; 12 = input error (invalid slug, conflicting flags, feature not found).

**Sources mined:** QA reports, implementation verification reports (non-confirming `Machine Report` findings only), correction plans, dossier FAIL→PASS cycles, execution events, attempt artifacts, failure signatures, devlogs. Raw auditor output, stderr, prompt packages, and finding evidence text are not mined.

---

## harness:preview

Display a truncated, UTF-8-safe preview of an artifact file. Used in self:loop criteria-fail feedback to avoid dumping full file contents into the agent context.

```bash
aioson harness:preview <file>
aioson harness:preview .aioson/context/retro/checkout.md
```

Read-only. Best-effort write for the preview artifact.

---

## spec:analyze

The deep-content sibling of `artifact:validate` (which checks chain presence plus the canonical feature-completeness sections). Runs deterministic cross-artifact consistency checks before the execution gate. Persists `spec-analyze-{slug}.json`.

```bash
# Analyze cross-artifact consistency for a feature
aioson spec:analyze . --feature=checkout

# JSON output for gate scripting (errors → exit 1)
aioson spec:analyze . --feature=checkout --json
aioson spec:analyze . --feature=checkout --strict --json
```

**Options:**
- `--feature=<slug>` — **required**. Feature slug.
- `--json` — structured output; `error` findings flip `ok: false` (exit 1).
- `--strict` — promotes advisory harness coverage/linkage findings to errors.

**What it does:** runs deterministic checks across the feature's artifacts:
1. **REQ/AC ID traceability** — declared-but-unreferenced IDs = coverage-gap warning; referenced-but-undeclared IDs = orphan/drift warning (noise-guarded for prose plans).
2. **Staleness** — an upstream artifact modified after a downstream one = warning (60s tolerance; the project-global `architecture.md` is excluded).
3. **Readiness** — `blocked` = error; `ready_with_warnings` = info.
4. **Harness-contract sanity** — schema errors = error; executable-coverage = info.
5. **AC→contract linkage** = info.
6. **Feature capability closure** — validates Product Capability Map → requirements lens matrix → repository leverage → delivery plan, including conditional operational decisions; any missing required link = error.
7. **Parallel-wave consistency** — same-wave phases that share Primary files = warning.

An `error` flips `ok: false` (exit 1 in `--json`). `@qa`'s scope-drift review runs `spec:analyze`: errors are blockers, warnings are pre-computed drift evidence. When the plan carries a `Wave` column, it also runs the `wave_file_overlap` check (same-wave phases sharing Primary files = warning; plans without a `Wave` column skip it).

See [Executable verification](./executable-verification.md) for the full theme.

---

## forge:compile

**Lane B.** Compile a MEDIUM feature's artifacts into `.aioson/plans/{slug}/forge-run.workflow.js` — an auditable, versionable Claude Code dynamic-workflow script that is committed alongside the spec. Opt-in entry point is the `@forge-run` agent.

```bash
# Compile the feature into a forge-run.workflow.js
aioson forge:compile . --feature=checkout

# JSON output (hard preflights may refuse compilation)
aioson forge:compile . --feature=checkout --json
```

**Options:**
- `--feature=<slug>` — **required**. Feature slug.
- `--json` — structured output; refusals are reported with the owning agent named.

**What it does:** the generated workflow mirrors the executable-verification roadmap:
- one `parallel()` per **Wave** (file-disjoint dev agents; blocked-wave early stop),
- a deterministic `harness:check` convergence loop bounded by the governor's `error_streak_limit` (sequential fixes — only waves prove disjointness) plus a token-budget guard,
- a 3-lens adversarial review (correctness / completeness / regression-risk; majority survives; refute-by-default) for binary criteria **without** `verification`,
- a fresh-context validator stage closing through `harness:validate` → `last-validator-output.json` → `apply-validation`.

**Hard preflights** refuse compilation and name the owning agent: invalid/missing contract, zero executable criteria, plan without a `Wave` column, `spec:analyze` errors, and `wave_file_overlap` (a *warning* in `spec:analyze`, an **error** here). Generated code is deterministic by construction: pure-literal metadata, plain JS, no `Date.now`/`Math.random`/`new Date`, artifact text via `JSON.stringify` (injection-safe). It **never** runs `feature:close`. New module: `src/harness/plan-waves.js`.

See [@forge-run](../4-agents/forge-run.md) and [Executable verification](./executable-verification.md).

---

## agent:execution

Feature-scoped sub-agent execution with a manifest, safe model resolution, bound reports, and resumable telemetry.

```bash
aioson agent:execution:init . --feature=checkout --host=codex
aioson agent:execution:validate . --feature=checkout --json
aioson agent:execution:show . --feature=checkout --json
aioson agent:execution:dispatch . --feature=checkout --agent=qa
aioson agent:execution:dispatch . --feature=checkout --lane=backend
aioson agent:execution:resume . --feature=checkout
aioson agent:execution:status . --feature=checkout --json
aioson agent:execution:events . --feature=checkout --run=<run_id> --json
```

The same resolver is used by `verification:plan`. Human-readable values such as `GPT 5.6 Terra` and short typos resolve to a local Codex slug only when the match is unique and numeric tokens agree. Ambiguous models, incompatible `reasoning_effort`, invalid catalogs, and unsafe paths fail closed.

The manifest enables DEV and QA by default. Development lanes and Tester/Pentester/Validator are opt-in. Schema v2 also carries `orchestration` and `chain_work_policy`; test/security work falls back to DEV unless the corresponding specialist is enabled. Existing v1 manifests remain valid. See [Agent execution, development lanes, and model resolution](./agent-execution.md).

---

## Operator memory commands

Identity-scoped decision memory is optional and local to `~/.aioson/operators/`.

```bash
aioson op:identity show --json
aioson op:capture --signal=authorization --quote="..." --proposal="..." --source-agent=dev
aioson op:list --include-archived
aioson op:show <slug> --json
aioson op:reinforce <slug> --json
aioson op:forget <slug>
```

`authorization`, `exclusion`, and `correction` promote on the first detection; `confirmation` requires two. Re-detection of an existing decision reinforces it in place and does not duplicate FTS rows or reset `promoted_at`. Enable automatic loading with `AIOSON_OPERATOR_MEMORY=true`.

Every `op:*` command takes an optional `[path]` first (`aioson op:list ../client-app --json --titles-only`; a slug command also reads `<slug> [path]`, so `op:show <slug> .` works): the project a decision is scoped to is resolved from that path, and from the working directory only when no path is given. `--locale` wins over the project's language for the lines `op:capture` and `op:promote` print. A decision binds the project it was said in (`scope: project`) and widens to every project when the same signal is detected in a second distinct project or when the user's own quote names every project; `op:list` lists what applies in the current project, `--all` lists every project's.

`op:list --json --titles-only` is the recall shape (a session reads it through `context:digest`, which asks for the eight ranked first plus the eight that best match the task; run it directly for a new subject), so by default it lists the 40 decisions ranked first — this project's, then every other's; within each group exclusions and corrections before authorizations and confirmations (a forgotten prohibition is a failure the agent cannot see, a forgotten permission only costs a question), then the freshest by the decay model (reinforcements raise a decision, its category's half-life lowers it with age) — and always reports `total` and `omitted` (0 when nothing is cut) plus the way to the rest: `--match="<words>"` keeps only the decisions whose title or body shares a word of two letters or more (grammar words aside; `match_ignored: true` says when no usable word was left), `--limit=<n>` sets the head (`0` = all). The head applies only to that activation shape: `--feature` and `--proposals` listings are cut only by an explicit `--limit`, which then reports the same counts.

See [Operator memory](./operator-memory.md).

---

## Review intelligence commands

These additive commands bind an agent review to an exact feature artifact and its current authorities. They provide auditability for the role-aware two-pass review; they do not run models, tests, web research, workflow transitions, or gates.

```bash
aioson review:prepare [path] --agent=<agent> --feature=<slug> [--artifact=<path>] [--json]
aioson review:check   [path] --agent=<agent> --feature=<slug> --report=<path> [--json]
aioson review:status  [path] --feature=<slug> [--json]
```

`review:prepare` selects the approved profile for the agent, hashes the artifact and known authorities, publishes an immutable `review-packet/v1`, and returns `draft_path`, a bound report template, and the exact next command. Omitting `--artifact` uses only the agent's declared default; a missing or ambiguous default fails without creating a packet. Repeating prepare with unchanged bytes returns the same packet ID and path.

The agent completes at most two evidence passes and writes a candidate report. `review:check` validates schema, paths, limits, packet bindings, current hashes, evidence, and state coherence before promoting the report immutably. Structurally valid actionable reports are retained; malformed, mismatched, unsafe, or stale reports are not promoted.

`review:status` reports the latest current result per agent. An empty review store is intentionally non-gating. Delivery assurance exposes five separate axes — specification fidelity, acceptance coverage, code health, runtime truth, and residual risk — with no aggregate score.

| Exit | Meaning |
|---|---|
| `0` | Operation succeeded and the current review is `pass`; empty status also returns `0` |
| `1` | A valid current report was stored with `blocked`, `decision_required`, or `unverified` |
| `2` | Invalid invocation/report, unsafe path, missing binding, limit violation, or stale artifact/authority |

Exit `1` is actionable evidence, not a schema failure. Exit `2` must not be ignored: correct the report or run prepare again after an artifact/authority change. Review results inform each agent's existing approval or QA contract but never change `phase_gates`, workflow state, or handoff state automatically. On older installations without the skill or commands, the participating agents use the same bounded review manually and preserve their previous workflow behavior.

## Commit guard boundaries

For a staged scan, `git:guard` reads `.aioson/git-guard.json` from the Git index. An unstaged or untracked allow rule therefore cannot authorize staged content. New exceptions should use path-and-rule-scoped `contentAllowRules`; whole-file `contentAllowPaths` remains legacy compatibility only.

`commit:prepare --agent-safe` accepts only `--mode=headless`. The interactive `guarded` and user-reviewed `trusted` modes are rejected in agent-safe execution; high-confidence guard errors always remain blocking.

`commit:prepare . <path...>` stages explicit operands (files or directories) without the picker and is valid in agent-safe/headless mode. Staging runs in two lanes — tracked paths through `git add -u --` (immune to `.gitignore` rules, stages deletions) and untracked paths through `git add --` — chunked under the command-line ceiling and retried on `index.lock` contention. A refusal surfaces `gitMessage` (git's own lines, EOL warnings stripped), `failedPaths`, `stagedBeforeFailure` and the exit status. `trackedIgnored` reports tracked files that the ignore policy covers (advisory; remedy `git rm -r --cached -- <paths>`); `aioson update` and `aioson setup` measure the same list.

The generic secret heuristic skips credential descriptors (`confirm_password_label`, `API_KEY_HEADER`, `TOKEN_TTL`), mask and label values (`••••••••`, `"Password"`), and suppresses — as visible notices — findings inside localization resources (`i18n/`, `locales/`, `lang/`, locale-named files such as `messages/pt-BR.json`, `.po/.arb/.xliff/.resx`) and word-shaped symbol names under `token` keys (lint/AST reports). Provider-key rules still apply everywhere.

## host:signature

```bash
aioson host:signature [path] --host=<claude|codex|grok|kimi|opencode|qwen> [--model=<id>|configured-default] [--effort=<level>] [--unattended-probe=false] [--ttl=<hours>] [--timeout=<ms>] [--json]
aioson host:signature [path] --host=<host> [--model=<id>] [--effort=<level>] --status [--json]
aioson host:signature [path] --list [--json]
```

Probes whether a `(host, model, effort)` combination actually works on this machine — CLI installed, login valid, model id accepted, effort supported — and records the result in `~/.aioson/hosts/signatures.json` (override: `AIOSON_HOST_SIGNATURES`) with a TTL (default 24h). The probe uses the exact non-interactive argv of the execution adapter in provider read-only mode, inside an empty temporary directory, with a one-word prompt; it never touches a project. Hosts come from the single registry behind `tool:capabilities` — Antigravity, Claude Code, Codex, Grok, Kimi Code, OpenCode and Qwen Code are dispatchable; Muse remains interactive-only. The logical `antigravity` host resolves to `agy`, never the Electron editor launcher. A host without a registered read-only flag (OpenCode or Antigravity) is probed without that precaution (`probe.sandbox: none`) instead of being kept out of the lanes. After the read-only probe passes, an **unattended write probe** runs the exact unattended `workspace-write` argv a lane worker gets in another empty temporary directory and asks for one file: written → `verified`, exited without it → `unverified` (valid; the run's preflight warns), alive past the probe budget → `blocked`, refused → `failed` — the last two invalidate the signature with `host_not_unattended`. The result is kept under `unattended.yolo`; `--unattended-probe=false` skips the write probe and keeps what an earlier one proved.

The probe's exit code is the verdict (`ok` = signature valid; `reason` carries `executable_not_found` with the install command, `auth`, `invalid_model`, `capacity`, `timeout`, `crash`, `effort_unsupported_by_host`, `host_not_unattended`, `permission_mode_unsupported` for a host with no unattended flag). `--status` and `--list` are read-only and always exit 0; read the `state` field (`valid | expired | invalid | missing`). `aioson agent:execution:validate --feature=<slug> --strict` requires a valid signature for every enabled agent and lane of the manifest and warns on unsigned declared fallbacks; without `--strict` the manifest keeps its `validated_at_dispatch` contract.

## execution:offer

```bash
aioson execution:offer [path] [--feature=<slug>] [--json]
```

Answers whether the orchestrated execution path (compiled lanes as parallel external processes, one host/model per role) is available in this project on this machine: `.aioson/config/execution-roles.json` present, valid and enabled — the unlock file the planner seeds disabled (`execution:seed`) and a person or the supervising desktop client enables — every role still at the default model confirmed, **and** every declared role signed (`host:signature`) and unexpired. `available:false` carries `reason`, `pending_confirmation[]` and the exact onboarding action. With `--feature` it also describes the compiled plan, measured scale and recommendation. The `execution` block exposes spawner support/configuration plus `context_limit_enabled:false` and `time_limit_enabled:false`; AIOSON reports context use and duration but does not terminate orchestrated workers for either. Always exits 0 — it is a question, not a gate. See [Agent execution — Orchestrated execution](agent-execution.md#orchestrated-execution-roles-offer-compile).

## execution:seed

```bash
aioson execution:seed [path] --lanes=<lane-a,lane-b> [--feature=<slug>] [--json]
```

Writes `.aioson/config/execution-roles.json` for the lanes given — or, with `--feature` and no `--lanes`, for the plan's `## Development execution lanes` table, or, before that table exists, one lane per measured surface of a two-surface plan (`lanes_source: surfaces`) — **disabled**: one `{lane}_dev` role per lane plus `integration_dev` and `qa`, each on an execution host installed on this machine (the reviewer on a second host when there is one, `independent_review: false` otherwise), every model the harness default `configured-default`, `source` naming the planner and the feature. Never touches an existing file (`already_present`, with `missing_roles` the lanes need and the file lacks — exit 0). Refuses with the cause when no execution host is installed (`no_execution_host`, with the install command per registered host), when the write fails (`write_failed`), or when the lanes are missing or malformed (`lanes_required`, `lane_invalid`, `too_many_lanes`) — exit 1. Choosing the models, enabling the file and signing the hosts stay the owner's acts; the framework seeds, it never unlocks.

## execution:configure

```bash
aioson execution:configure [path] --feature=<slug> [--lanes=backend,frontend] --json
aioson execution:configure [path] --feature=<slug> --config=<reviewed-json-file> --expect-digest=<expected_digest> --confirm --json
```

Describes a wizard for the main monitoring chat without writing configuration or launching hosts. Single DEV remains the recommended implementation default; orchestration is an explicit choice. The chat asks CLI, model and reasoning effort for each implementation lane, QA and final integration supervisor (`integration_dev`). Model IDs and compatible efforts come from the local catalog when available; an unavailable catalog permits an exact model ID, validated before execution. Existing settings and CLI defaults require explicit keep/change answers. Show the complete summary, then confirm, edit or cancel.

The confirmed command requires every role's `host`, `model` and `reasoning_effort` in the reviewed document; `null` explicitly selects the configured effort. It saves atomically and records a role-map-bound confirmation. A stale or missing `--expect-digest` refuses the write. The current chat remains the coordinator; `integration_dev` selects the external final integration DEV. Follow `next` to validate the chosen routes, then `compile_command`. The executor refuses unconfirmed default models before automatic host validation or dispatch, including `--resume` and `--detach`.

## execution:profiles:validate

```bash
aioson execution:profiles:validate [path] [--profile=<name[,name2]>] [--concurrency=<1..10>] [--ttl=<hours>] [--timeout=<ms>] [--refresh] [--status] [--json]
```

Validates every unique host/model/effort route in the enabled execution profiles through the same read-only plus unattended-write harness as `host:signature`. Missing, expired and invalid routes are probed in parallel (three at once by default); valid cached signatures are reused unless `--refresh` is set. Probe results are merged atomically into the machine signature store. `routing` reports whether every role in the active profile has a valid primary or transitive fallback; `routes` preserves every configured binding and its evidence. `--status` starts no harness. Exit 0 only when active routing is ready and every selected enabled route is valid; otherwise exit 1 with the failed alternatives still visible. This command is an optional full-profile diagnostic: an actual `execution:run` performs the required active-chain validation automatically.

## execution:compile

```bash
aioson execution:compile [path] --feature=<slug> [--dry-run] [--json]
```

Compiles the planner's `## Development execution lanes` and `## Execution Sequence` tables, crossed with the roles file and the host signatures, into `.aioson/context/execution-plan-<slug>.json` (units = phase × lane or integration owned by dev, waves, per-unit capabilities/acceptance criteria/verification, roles per lane, source digests), one prompt per lane unit and per lane under `.aioson/context/execution-prompts/<slug>/` (the dev-lane profile derived from the installed `dev.md` + the unit contract + the PRD/plan rows of that unit's capabilities), and updates only `development_lanes` and `orchestration.execution` in `agent-execution-<slug>.json`. Refuses with named findings and writes nothing when the tables, ownership, waves, roles, signatures or the dev kernel are not right (`lanes_table_missing`, `no_wave_column`, `phase_mixed_ownership`, `wave_file_overlap`, `integration_before_lanes`, `lane_write_paths_overlap`, `lane_without_role`, `qa_role_missing`, `role_signature_missing|expired|invalid`, `dev_kernel_missing`, …); exit 1 on refusal. `--dry-run` computes the plan and findings without writing. The compiled plan is verified by `verify:artifact --kind=execution-plan --slug=<slug>` (digest-bound to the plan, the roles, the manifest lanes, the prompts and the signatures), which auto-fires at the planner's `agent:done` and stays silent for features that never compiled one.

## execution:run

```bash
aioson execution:run [path] --feature=<slug> [--preflight] [--resume] [--fresh] [--wave=<n>] [--json]
```

Runs the compiled plan by readiness, with each unit as a `dev → qa` pipeline and up to 10 disjoint unit pipelines at once (`parallel.max_concurrent_lanes` is the backward-compatible field name). Several units from one logical lane may overlap. Real dependencies and file conflicts still gate launch. The saved execution-role configuration is live: before starting, and whenever that file changes before a later stage, the engine JIT-probes missing/expired/invalid routes in the active transitive fallback chain, then reloads the active profile, model, effort, fallbacks and independent-QA policy; the scheduler reloads pool capacity. Validation never rewrites the selected model. A failed primary probe advances to a working saved fallback, so the run pauses only when no configured route works. These edits do not stale the compiled plan. `--preflight` is deliberately read-only and starts no harness. If `integration_dev` is configured before the final boundary, one final correcting integration DEV runs the complete verification after all units, followed by shared independent QA. A process already in flight retains its launch identity; the next dispatch obeys the saved choice. The run holds the feature lease, persists every transition and resumes idempotently. AIOSON imposes no token or wall-clock deadline; context use, elapsed time and file activity remain report-only telemetry.

Convergence is bounded by behavior, not by elapsed time: four identical structured actions or 24 consecutive read-only actions stop an unproductive attempt; one equivalent no-progress retry is automatic, then the circuit opens; and QA may return a unit to DEV at most five times. A sixth failed review becomes `decision_required` with `dev_qa_cycle_limit`, preserving all findings for diagnosis. Cross-unit contract repair routes to the unique compiled owner in the same or an earlier wave and coalesces duplicate pending repairs so consumers wait for one corrected producer. Scope drift, silence, disk activity and reports remain measured and visible. Live lines go to stdout (stderr with `--json`), and `execution:status --watch` remains the durable view when a wrapper swallows process output.

## execution:decide

```bash
aioson execution:decide [path] --feature=<slug> --unit=<unit-id> --choice=retry|fallback:<host>/<model>[/<effort>]|skip|skip-qa|abort [--json]
```

Answers a pending decision of one unit, between runs (refuses `run_active` while the feature lease is held). `retry` re-queues the stage; `fallback:` re-queues it on another host/model — which must carry a valid host signature (`fallback_signature_missing` otherwise) and, for an effort, a host that accepts one; `skip` (dev stage) hands the unit to the integration owner and records `unit_skipped`; `skip-qa` (qa stage) keeps the implementation and records `qa_skipped`; `abort` cancels the run. The decision is recorded in the state (`decisions[]`) and as a `decision_applied` telemetry event; the answer carries the `resume_command`.

## execution:status

```bash
aioson execution:status [path] --feature=<slug> [--watch[=<seconds>]] [--format=full|line] [--json]
```

The consolidated ledger of the current run: summary (status, waves, unit counts, pending decisions), waves with their units, per-unit dev/qa status (host, model, verdict, reason, report path, findings, measured corrections, cap breaches, `started_at`/`finished_at`/`elapsed_ms`, the `live` block of a running stage and the `activity` of a finished one), all findings (dev, qa, run-level scope), decisions applied and pending, integration units and `resume_command`. Two things only the outside view can tell: `engine` — is the process behind the state alive? `alive` when the state's heartbeat is fresh (three intervals, at least 10 s), `missing` when the state says running but nobody has written it (a killed terminal, a shell timeout, a closed client; the message names the `--resume` that reclaims the interrupted units), `idle` when the run ended — and `running[]`, one entry per running stage with its live measurement (elapsed, last write and file among the unit's own files, files changed, budget, stall/unproductive flags, `measured_on`/`measured`), rendered as one `▶` line each in human mode. `--watch` re-reads every 5 s (`--watch=<seconds>` for another cadence) until the run leaves `running` — the second-terminal view of a run launched detached, the command the run itself prints at start; with `--json` every tick is one JSON line on stdout and the final document closes the stream. `--format=line` renders one line (feature, state, wave, counts, what runs now) for a status pane or a bar. Read-only; exit 0 even with no run (`compiled, not started` / `no execution plan compiled`). A state that exists and cannot be read reports `state_unreadable` with its cause — never "no run" — and a watch keeps watching through it; one whose bytes never parse reports `run_state_corrupt` (`state_corrupt`, exit 1) with the way out, and a watch ends there.

## execution:graph

```bash
aioson execution:graph [path] --feature=<slug> [--format=ascii|mermaid|json] [--json]
```

The compiled execution plan drawn as the graph it is: nodes are the units (lane units and the integration units the session DEV runs after the lanes), edges are the passage rules — the explicit `Depends on` edges (`after_dev` / `after_qa`) and, for units that declare none, the implicit wave-barrier edges from the previous wave. When a run state exists it is laid over the nodes (dev/qa status, host, verdict, pending decision) and over the waves. `ascii` is the terminal view, `mermaid` renders in any client that draws it, `json` is the structured document a supervising client consumes; `--json` wraps the document with `rendered`. Read-only; exit 1 only when no plan was compiled (`plan_not_compiled`) or the format is unknown.
