@aihq/harness 0.6.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,16 +8,17 @@
8
8
  [![Node ≥20](https://img.shields.io/badge/node-%E2%89%A520-339933.svg)](package.json)
9
9
 
10
10
  <p align="center">
11
- <img src="docs/assets/aih-overview.svg" alt="aih — extract corporate trust, self-heal the runtime, tune the workstation, bootstrap a governed repo, and run AI-assisted coding behind a proxy" width="100%">
11
+ <img src="docs/assets/aih-overview.svg" alt="aih — extract corporate trust, self-heal the runtime, tune the workstation, bootstrap a governed repo, govern agent skills, and run AI-assisted coding in enterprise environments" width="100%">
12
12
  </p>
13
13
 
14
14
  A cross-platform CLI that helps prepare developer workstations and repositories for
15
- **reviewable, governed AI-assisted coding behind a corporate proxy**. It extracts
16
- corporate trust, tunes local inference, adds repo guardrails, wires up
17
- MCP / observability / sandboxing, and lays down a tool-agnostic context
18
- architecture all from one command surface. On top of that setup it runs a
19
- governance loop for external agent skills vet approve pack marketplace →
20
- evidence — anchored in a committed approval lock (`aih-skills.lock.json`).
15
+ **reviewable, governed AI-assisted coding in enterprise environments** from
16
+ locked-down, TLS-intercepted networks to open ones. It extracts corporate trust,
17
+ tunes local inference, adds repo guardrails, wires up MCP / observability /
18
+ sandboxing, and lays down a tool-agnostic context architecture all from one
19
+ command surface. On top of that setup it runs a governance loop for external
20
+ agent skills — vet → approve → pack → marketplace → evidence — anchored in a
21
+ committed approval lock (`aih-skills.lock.json`).
21
22
 
22
23
  > Implements the architectural blueprint *"Enterprise DevSecOps AI Bootstrapping:
23
24
  > Cryptographic Trust, Local Performance Optimization, and Unified Observability"*
@@ -27,6 +28,16 @@ evidence — anchored in a committed approval lock (`aih-skills.lock.json`).
27
28
  > support obligation, SLA, indemnity, consulting, or professional advice is provided. `aih`
28
29
  > is dry-run by default — review the plan before running `--apply`. See [DISCLAIMER.md](DISCLAIMER.md).
29
30
 
31
+ ## The 1.0 contract
32
+
33
+ Pin `@aihq/harness@^1` and automate against it. Every command, flag, and deprecated
34
+ alias is snapshot-tested in CI against a committed fixture, the `--json` envelope is
35
+ schema-pinned, and exit-code semantics are pinned — a surface change fails the build
36
+ until it ships as a reviewed contract decision. Renames ship as deprecated aliases
37
+ (the old name keeps working, with a one-line warning) before a major removes them,
38
+ and security fixes land on the latest and the previous minor. The full policy:
39
+ [STABILITY.md](STABILITY.md).
40
+
30
41
  ## Design posture
31
42
 
32
43
  - **Dry-run by default.** `aih <cmd>` computes and prints a plan; nothing is
@@ -81,43 +92,68 @@ aih init . --apply # apply it
81
92
 
82
93
  ## Command surface
83
94
 
95
+ One honest line per command — the long-form behavior detail for every command lives in
96
+ [docs/commands.md](docs/commands.md), and `aih <command> --help` is authoritative for flags.
97
+
98
+ ### Workstation & runtime
99
+
100
+ | Command | What it does |
101
+ | --- | --- |
102
+ | [`aih certs`](docs/commands.md#aih-certs) | Extract the corporate root CA from the OS trust store and propagate trust to npm/pip/cargo/conda. |
103
+ | [`aih heal`](docs/commands.md#aih-heal) | Diagnose and repair the broken runtime behind any TLS-intercepting proxy — corporate trust, npm, PATH, MCP pre-flight. |
104
+ | [`aih tools`](docs/commands.md#aih-tools) | Install the agent shell tools the harness leans on (`rg`/`fd`/`jq`, `ast-grep`, `gh`, …) through the platform package manager. |
105
+ | [`aih ready`](docs/commands.md#aih-ready) | Grade a blocker-aware readiness verdict: can a developer start work with an AI agent here, now? |
106
+ | [`aih hardware`](docs/commands.md#aih-hardware) | Profile CPU/RAM/GPU and emit tuned Ollama/llama.cpp settings. |
107
+ | [`aih vdi`](docs/commands.md#aih-vdi) | Detect VDI (Citrix/WorkSpaces/RES/RDP) and redirect caches + SQLite to local scratch. |
108
+ | [`aih bootstrap`](docs/commands.md#aih-bootstrap) | Orchestrate the workstation 4-phase rollout (certs → hardware/vdi → telemetry). |
109
+
110
+ ### Repo canon & bootstrap
111
+
112
+ | Command | What it does |
113
+ | --- | --- |
114
+ | [`aih init`](docs/commands.md#aih-init) | Initialize a repo in one pass: profile + superpowers + bootstrap-ai + scaffold + secrets + guardrails + mcp + sandbox. |
115
+ | [`aih profile`](docs/commands.md#aih-profile) | Detect the repo's stack recursively and synthesize Cursor stack rules (`.cursor/rules/*.mdc`). |
116
+ | [`aih scaffold`](docs/commands.md#aih-scaffold) | Scaffold repo hygiene — secret deny-list, pre-commit hook, `.gitignore` entries; `--canon legacy` adds the full context-doc family. |
117
+ | [`aih bootstrap-ai`](docs/commands.md#aih-bootstrap-ai) | Emit and verify the repo's Layer-2 canon — `RULE_ROUTER.md`, per-CLI adapters, root bootloaders; `--verify` is the drift gate. |
118
+ | [`aih contract`](docs/commands.md#aih-contract) | Synthesize the machine-readable repo contract (`project.json`) from the detected stack. |
119
+ | [`aih adopt`](docs/commands.md#aih-adopt) | Converge an existing AI canon onto aih's managed model without overwriting your work (brownfield migration). |
120
+ | [`aih prune`](docs/commands.md#aih-prune) | Remove the stale per-CLI artifacts left for CLIs the repo no longer targets (reversible by default). |
121
+ | [`aih ecc`](docs/commands.md#aih-ecc) | Install affaan-m/ECC (skills, instincts, memory) for the selected CLIs via ECC's own installer. |
122
+ | [`aih superpowers`](docs/commands.md#aih-superpowers) | Install obra/Superpowers (brainstorm → plan → TDD → subagent-review skills) for the selected CLIs. |
123
+ | [`aih crispy`](docs/commands.md#aih-crispy) | Run the CRISPY context-engineering stage machine (deterministic, gate-ordered). |
124
+ | [`aih workspace`](docs/commands.md#aih-workspace) | Scaffold a multi-repo workspace at the parent folder: cross-repo map, combined MCP, `.code-workspace`. |
125
+
126
+ ### Skill governance & supply chain
127
+
128
+ | Command | What it does |
129
+ | --- | --- |
130
+ | [`aih trust`](docs/commands.md#aih-trust) | Vet, pin, and gate external GitHub repos and skills before an agent acquires them. |
131
+ | [`aih skill`](docs/commands.md#aih-skill) | Govern the skill lifecycle — vet → approve → inventory → quarantine → remove — anchored in `aih-skills.lock.json`. |
132
+ | [`aih pack`](docs/commands.md#aih-pack) | Curate committed sets of approved skills (`aih-packs.json`); every ref is cross-checked against the lock, fail-closed. |
133
+ | [`aih marketplace`](docs/commands.md#aih-marketplace) | Build, validate, and publish a reproducible, verifiable distribution artifact from the approval lock — never a registry. |
134
+ | [`aih policy`](docs/commands.md#aih-policy) | Validate the committed org policy — or a policy-bundle envelope — as a read-only CI gate. |
135
+ | [`aih evidence`](docs/commands.md#aih-evidence) | Package the audit trail aih already emits (locks, cards, vet evidence, run logs) into one deterministic evidence bundle. |
136
+ | [`aih bundle`](docs/commands.md#aih-bundle) | Build a deterministic fleet bundle (contract + policy + config) with checksums; `aih verify-bundle` re-checks any copy. |
137
+ | [`aih secrets`](docs/commands.md#aih-secrets) | Scan for plaintext `.env*`/`secrets/` and write agent deny rules; `--verify` is the secret-scan CI gate. |
138
+ | [`aih guardrails`](docs/commands.md#aih-guardrails) | Generate `.gitleaks.toml`, `.pre-commit-config.yaml`, and a CI license gate that blocks AGPL/strong-copyleft. |
139
+
140
+ ### Analytics & operations
141
+
142
+ | Command | What it does |
143
+ | --- | --- |
144
+ | [`aih report`](docs/commands.md#aih-report) | Render the read-only analytics digest — context footprint, adoption, trends; `--v9`/`--open` build the offline HTML dashboard. |
145
+ | [`aih track`](docs/commands.md#aih-track) | Record one metrics sample (commits, LOC delta, adoption) to `.aih/history.jsonl` — the time-series behind `aih report` trends. |
146
+ | [`aih usage`](docs/commands.md#aih-usage) | Install the multi-tool usage-capture layer → `.aih/usage.jsonl` — local activity counts only, no cost, no prompts. |
147
+ | [`aih telemetry`](docs/commands.md#aih-telemetry) | Inject OpenTelemetry env, a redacting Bindplane collector, and an analytics fetcher. |
148
+ | [`aih mcp`](docs/commands.md#aih-mcp) | Generate the MCP server config for the targeted CLIs; per-tool guidance where a generated file would be wrong. |
149
+ | [`aih sandbox`](docs/commands.md#aih-sandbox) | Generate a devcontainer + managed sandbox settings (egress allowlist, `failIfUnavailable`). |
150
+
151
+ ### Verification
152
+
84
153
  | Command | What it does |
85
154
  | --- | --- |
86
- | `aih certs` | Extract the corporate root CA from the OS trust store, lock it down, and propagate trust to npm/pip/cargo/conda. |
87
- | `aih heal` | Diagnose **and repair** the broken runtime `certs` assumes works — corporate TLS trust, npm, PATH, and MCP pre-flight — generically for any TLS-intercepting proxy (`--ca-pattern`/`AIH_CA_PATTERN`, never hardcoded). Diagnoses by default (exits non-zero when broken) and repairs under `--apply`; the npm self-heal is emitted as an operator-run script (never executed) and the only mutation is a local Windows registry write to persist the CA for GUI-launched apps (Claude/Kiro), so the harness never contacts a remote. `--scope certs,npm,path,mcp,all`. |
88
- | `aih tools` | Install the agent shell tools the harness leans on — `rg`/`fd`/`jq` plus `ast-grep`/`comby`/`tree`/`gh`/`code-review-graph` — through the platform package manager. Dry-run previews; `--apply` installs. A blocked install on a locked-down box is escalated as an IT ticket rather than failing silently. |
89
- | `aih ready` | Readiness gate — one graded, blocker-aware verdict answering "can a developer start work with an AI agent here, now?", composed from aih's read-only probes (runtime/TLS/PATH/core tools, per-CLI loadability, contract, secret scan). Diagnoses by default (non-zero when blocked); the one auto-fixable blocker (missing `rg`/`fd`/`jq`) installs under confirmation. Surfaces a `sec-ready` panel in `aih report --v9`. |
90
- | `aih hardware` | Profile CPU/RAM/GPU; compute memory/thread/parallel limits + quantization; emit tuned Ollama/llama.cpp settings. |
91
- | `aih vdi` | Detect VDI (Citrix/WorkSpaces/RES/RDP) and redirect caches + SQLite to local scratch (junction on Windows). |
92
- | `aih profile` | Recursively detect the repo's stack and synthesize Cursor stack rules (`.cursor/rules/*.mdc`). Root bootloaders are owned by `bootstrap-ai`. |
93
- | `aih ecc` | Install [affaan-m/ECC](https://github.com/affaan-m/ECC) (skills, instincts, memory, security, research-first) for the selected CLIs, scoped to the detected stack: Claude plugin path, `ecc-install` for codex/cursor/zed/opencode, `consult` advisor otherwise. |
94
- | `aih superpowers` | Install [obra/Superpowers](https://github.com/obra/Superpowers) (brainstorm → plan → TDD → subagent-review skills) for the selected CLIs. |
95
- | `aih scaffold` | Create the canonical context dir (`--context-dir`, default `ai-coding`) — INDEX/SKILL skeleton, an agent **`SETUP-TASKS.md`** playbook (fill context + guardrails from the code), a write-once `project-guardrails.md`, a secret deny-list, and a pre-commit hook. (Bootloaders are `bootstrap-ai`'s job.) |
96
- | `aih guardrails` | Generate `.gitleaks.toml`, `.pre-commit-config.yaml`, and a CI license gate that blocks AGPL/strong-copyleft. |
97
- | `aih secrets` | Scan for plaintext `.env*`/`secrets/` and write agent deny rules + vault-injection guidance. `--verify` is the **secret-scan CI gate** (exit 1 when plaintext secrets exist); `--sarif <file>` emits one error-level result per path for GitHub code-scanning. |
98
- | `aih trust` | Vet, pin, and gate external GitHub repos and skills before an agent acquires them. `scan <target>` grades danger (auto-exec hooks, dependency-confusion, typosquat, incoming-MCP, secrets) and emits SARIF; `allow`/`pin` record reviewed sources + pinned SHAs in org policy; `list`/`verify` audit the committed policy and trust-lock evidence. |
99
- | `aih skill` | The **skill lifecycle** on top of `trust` — a complete governance loop for external agent skills. `vet <src>` runs the read-only gate pipeline (shape, license, trust scan) to a **GREEN/YELLOW/RED/UNKNOWN** verdict + a local evidence artifact (never installs). `card`/`approve --pin --owner` turn that evidence into committed governance: a skill card + a root **`aih-skills.lock.json`** entry, behind a fail-closed chain (pin → evidence → approvable verdict → license → owner; RED blocked, UNKNOWN refused, YELLOW = the manual review). The lockfile has **install-time teeth**: `workspace add` refuses promoting a skill with no committed approval *for that source's pinned commit* at `team`/`enterprise` posture (advisory at `vibe`) — a same-named skill from an unrelated source never inherits an approval, and stale approvals are refused. `inventory` joins on-disk skills against the approvals — approved / unapproved / stale-pin / quarantined, one row per physical install — and feeds a "Skill governance" panel in `report --v9`. `quarantine --name <skill>` **disables reversibly** (dir → `.aih/quarantine/`, approval kept; move it back to restore). `remove --name <skill>` retracts: archives the skill dir reversibly (`--delete` to hard-delete), drops the approval + card; refuses ambiguous duplicates, nested-skill collateral, machine-root installs, and stranding a parked copy's approval; cleans up orphaned approvals. |
100
- | `aih pack` | **Curation manifests** on top of the per-skill lifecycle — a committed root `aih-packs.json` names sets of approved skills so a team installs "the docs-quality pack", not N individual approvals. The `aih-skills.lock.json` stays the **pin authority**: every manifest ref is a fail-closed cross-check against the lock entry (`pack.pin-mismatch` blocks; a disagreeing manifest is never a second pin). `status`/`validate` grade each pack on the two orthogonal axes (approval × install) — `validate` is the **CI gate** (coded findings: `pack.missing-approval`, `pack.pin-mismatch`, `pack.duplicate-name`). `add`/`remove-entry`/`init` author the manifest with refs **derived from the lock** (authoring never invents a pin; `init` seeds a pack from `skill approve --pack` tags; an emptied pack is dropped whole). `plan`/`install` drive the gated two-phase acquisition once per source — **gate ALL sources before promoting ANY**, promote only the pack's refs (subset-exact), route drifted installs back through the gate, resume idempotently — fail-closed at every posture (clean approvals required even at `vibe`; `--acknowledge` refused, acknowledgements stay per-source). `uninstall` retracts every installed member with `skill remove`'s exact per-member semantics — reversible archive (or `--delete`), approval + card dropped, loader-ref advisories, the same refusal guards, and **one blocked member refuses the whole plan**; the manifest curation stays. Installed skills' pack tags roll up in the report's Skill-governance panel. |
101
- | `aih marketplace` | Package the approved skill set into a **reproducible, verifiable distribution artifact** — a directory a team can host anywhere (git repo or static host), never a registry/server. `build` reads `aih-skills.lock.json` (the **approval authority**) and emits the exact vetted skill bytes (trust-lock hash cross-checked), the committed skill cards, the content-addressed vet evidence, a `marketplace.json` manifest, and `SHA256SUMS` — byte-identical across builds from identical inputs (no wall-clock; `--stamp` is operator-supplied), and **fail-closed whole**: an approved skill that is uninstalled, drifted, ambiguous, or missing its card/evidence refuses the entire build. `validate` is the **read-only CI gate** over a built or fetched artifact (coded findings: `marketplace.manifest-parse`, `marketplace.path-traversal`, `marketplace.missing-file`, `marketplace.checksum-mismatch`, `marketplace.sums-coverage`, `marketplace.unapproved-verdict`, `marketplace.signature`), containment-checking every manifest/sums path **before** touching the filesystem with it. `publish` signs the artifact's `SHA256SUMS` (cosign or a GitHub attestation — a publish without a signer is refused; that's just a build); `validate --require-signature` then **fails rather than skips** when that signature can't be verified. Consumers stay on `aih workspace add` — the vet gate still runs at consume time. |
102
- | `aih mcp` | Generate the MCP server config **for the targeted CLIs** (`--cli`/`--all-tools`, default claude): Claude/Cursor/Kiro/Kimi get their correct project file written (`.mcp.json`, `.cursor/mcp.json`, …); Codex (TOML), Copilot, OpenCode, Zed, and global-config tools get exact per-tool guidance instead of a file aih would get wrong. Scopes: local/project/remote. For locked-down orgs, `--mode offline` (vendored local-command servers) or `--mode none` (no MCP + a CLI-tool fallback) plus a `managed-mcp.json` admin template. |
103
- | `aih sandbox` | Generate a devcontainer + managed sandbox settings (egress allowlist, `failIfUnavailable`). |
104
- | `aih telemetry` | Inject OpenTelemetry env, a redacting Bindplane collector, and an analytics fetcher (usage + skills endpoints → `{ usage_report, skills }`). |
105
- | `aih report` | Read-only analytics digest. Local: a dev console — agent **context footprint** (token bloat) plus a **per-turn load-group** panel (the heaviest single tool's always-loaded bootloaders — what one tool actually pays per turn, not the union sum; `--gate --token-budget <n>` exits non-zero in CI when it's exceeded). The footprint is **gitignore-honoring** (counts only tracked/untracked-not-ignored source, never generated per-CLI copies — `--all-files` to override; `--since <ref>` narrows to files changed in a PR), **repo & branch status** (current branch, ahead/behind vs main, dirty; `--team` adds in-progress team branches via a `gh` → `git ls-remote` → last-fetched ladder that degrades gracefully when gh/network is blocked), repo config presence, local AI-CLI tooling saturation, and **trends** (unicode sparklines of commits/LOC/adoption/branches over recorded history — see `aih track`). Org (`--org <export.json>`): top skills, tokens by type, **cache savings** (net-of-write estimate), and accept/reject from a saved Admin-API export. Body prints verbatim; `--json` carries structured data; `--format md\|html` writes a static artifact under `--apply`. **`--v9`** opts into the developer-console HTML dashboard with LIVE / PREVIEW / EMPTY panel honesty, machine-relative ECC inventory, usage-by-CLI, heavy lifters, dormant ECC skills, MCP parity, remediation wins, and no-cost local usage analytics; legacy and `--v4` remain opt-in/unchanged. **`--open`** builds the self-contained HTML dashboard and launches it in your browser (implies html + apply); **`--refresh <sec>`** keeps it live — opens once, then regenerates every `<sec>`s while the page auto-reloads (Ctrl+C to stop). Dark by default with a light toggle; fonts are embedded so it works fully offline. Network-free by default; `--team` is the lone opt-in network call. |
106
- | `aih track` | Record one metrics sample (commits 7d, LOC delta, adoption score, branch count, tracked files) to `.aih/history.jsonl` — the time-series behind `aih report` trends. Read-only git/filesystem; dry-run previews, `--apply` appends (idempotent per commit). Wire into a commit / agent-stop hook so history accumulates — e.g. Kiro's `metrics-on-stop` hook (`aih bootstrap-ai --cli kiro`) runs `aih track --apply` automatically. |
107
- | `aih usage` | Install the **multi-tool usage-capture** layer → `.aih/usage.jsonl` (rendered by `aih report` and `aih report --v9`). The **universal floor** is a git `post-commit` hook that records commit activity for **any** tool (it keys off the commit, not the agent). The per-tool **skill/MCP** layer wires in via each CLI's verified local hook (Claude/Codex/Cursor/Gemini/Kiro/…); skills aggregate by source (ECC/canon/user), and `--rollup <repo,repo>` aggregates local logs across repos on demand. Usage is local activity counts only — **no cost, no prompts, no arguments**, machine-local and gitignored. |
108
- | `aih crispy` | Run the CRISPY context-engineering stage machine (deterministic, gate-ordered). |
109
- | `aih bootstrap` | Orchestrate the workstation 4-phase rollout (certs → hardware/vdi → telemetry). |
110
- | `aih bootstrap-ai` | Emit + verify the repo's Layer-2 `ai-coding/` canon: `RULE_ROUTER.md`, per-CLI adapters, and root bootloaders (tool preamble + a regenerated shared block). `--verify` is the drift gate **and a weak-model-safety lint of the generated canon** — every `#[[file:…]]`/backtick reference must resolve and no leftover `<insert>`/`TODO` scaffolding ships (a dangling reference fails the gate; soft-imperative/taste-word prose is advisory). |
111
- | `aih contract` | Synthesize the machine-readable repo contract (`project.json`) from the detected stack — the structured seam agents and tooling read for build/test/lint commands and conventions, alongside the `ai-coding/` prose canon. Merges over any user-added keys (write-once-safe); dry-run previews, `--apply` writes. |
112
- | `aih prune` | Remove the stale per-CLI artifacts a repo still carries for a CLI it no longer targets (the inverse of `bootstrap-ai`). Dry-run preview by default; `--apply` moves aih-owned files to gitignored `.aih/legacy/` (reversible), subtracts aih's managed block **in place** from co-owned bootloaders (never deletes them), and leaves unmarked MCP/settings as manual advisories. Diffed against **committed intent only** (`.aih-config.json`), so a bare run is safe anywhere; a dirty/untracked target refuses without `--force`. `--delete` hard-deletes to a gitignored `*.aih.bak` sibling (never overwriting a prior backup) instead of archiving; `--unrunnable` also prunes a still-targeted CLI whose binary is absent from `PATH` (loud warning; never the default). |
113
- | `aih init` | Initialize a repo: profile + superpowers + bootstrap-ai + scaffold + secrets + guardrails + mcp + sandbox in one pass (one writer per file). ECC is a separate gated network step — run `aih ecc` when ready (it points at ECC's own installer). |
114
- | `aih adopt` | Converge an **existing** AI canon onto aih's managed model **without overwriting your work** (brownfield migration) — for a repo that already has an `AGENTS.md`/`.cursor`/`ai-*` setup. `--migrate-cli` folds committed CLI-native content into the canon (copy + pointer-convert, content-verified, backed up); `--ack <paths>` marks paths as intentionally tool-native so adopt stops flagging them. |
115
- | `aih workspace` | Scaffold a **multi-repo** workspace (parent-only): cross-repo architecture map (write-once) + per-repo discipline, a VS Code `.code-workspace`, combined graph/filesystem MCP spanning every child repo, and a `.aih-workspace.json` marker. |
116
- | `aih bundle` | Build a deterministic **fleet bundle** — the repo contract, org policy, and managed config packaged with a checksum manifest (and an optional `gh`-attested signature) for distribution to a team or CI. `aih verify-bundle` re-checks a bundle against its checksums + signature. |
117
- | `aih policy` | Schema gates for the org policy. `validate` is the **read-only CI gate** over the committed `aih-org-policy.json` — a missing file is a friendly skip (vibe repos carry no org policy), a parse/schema failure is a coded finding (`org-policy.invalid`) — or, under `--bundle <path>`, over a distributable **policy-bundle envelope** (`org-policy.bundle-invalid`, naming which layer failed: the envelope or the embedded policy). |
118
- | `aih evidence` | Package the **audit trail aih already emits** — approval lock, packs manifest, trust lock, skill cards, vet evidence, run logs, report/SARIF outputs — into one deterministic **evidence bundle** (`build`): the exact fleet-bundle layout (`files/<rel>` copies, `manifest.json`, `SHA256SUMS`, optional best-effort `--sign cosign\|gh`) plus `evidence.json`, a typed kind index. Byte-identical across builds from identical inputs (no wall-clock); absent artifact kinds are skipped silently; re-check any copy with `aih verify-bundle --bundle <out>`. |
119
- | `aih doctor` | Fail-closed verification of the workstation/repo configuration (+ workspace mode: validates each child repo). Includes a **canon markdown lint** (read-only) over the scaffolded `ai-coding/` tree. |
120
- | `aih status` | Read-only inventory of what the harness has configured. |
155
+ | [`aih doctor`](docs/commands.md#aih-doctor) | Verify the workstation/repo configuration fail-closed; workspace mode validates each child repo. |
156
+ | [`aih status`](docs/commands.md#aih-status) | Show a read-only inventory of what the harness has configured. |
121
157
 
122
158
  Shared flags: `--apply`, `--force`, `--verify`, `--json`, `--posture <vibe|team|enterprise>`, `--support-out <dir>`, `--no-log`, `--context-dir <dir>`, `--root <dir>`, `--cli <list>`, `--all-tools`, `--detect`, `--yes` (the read-only `doctor`/`status`/`verify-bundle` take the relevant subset).
123
159
  Settings also read from `AIH_*` env vars (`AIH_APPLY`, `AIH_CONTEXT_DIR`, `AIH_LOG`, …).
@@ -272,49 +308,11 @@ It writes, at the parent (it does **not** touch the child repos — run `aih ini
272
308
 
273
309
  ### Support tickets
274
310
 
275
- Any verifying command (`aih doctor`, `aih heal`, `aih bootstrap-ai --verify`, `aih secrets --verify`, …)
276
- turns a failed or skipped check that carries a `Check.code` into a **ticket-ready, tool-neutral support
277
- template** so a developer blocked by corporate environment config (untrusted CA, broken npm, blocked
278
- registry) can escalate without hand-writing the ask. `aih report` also derives its own **advisory**
279
- findings from the analytics panels (per-turn context **over budget**, incomplete **adoption** in an
280
- initialised repo) as developer self-fix notes — they never fail the run (a bare `aih report` still exits
281
- 0; only `--gate` makes the budget a CI gate). Templates render in three registers, keyed off who fixes
282
- the issue:
283
-
284
- - **External escalation** — an external-audience check that **failed**; the fix is a system change owned
285
- by IT, security, or the dev-platform team (untrusted corporate CA, broken package manager, unreachable
286
- registry). Blocking failures lead with `[<project>] Blocking setup issue — …`.
287
- - **External improvement request** — an external-audience check that **skipped**: a non-blocking
288
- configuration gap that degrades the setup without blocking it.
289
- - **Developer self-fix note** — a developer-audience finding the developer resolves directly (install
290
- git, `aih mcp --apply`); terse, runnable, and the only register that may name `aih`.
291
-
292
- By default the terminal prints one `[copy] …` label per template under a **Support templates:** heading.
293
- Add **`--support-out <dir>`** to write each full ticket to a repo-contained `<dir>/<code>.md` file (you
294
- named the path — that's the consent, same as `--sarif <file>`). **`--json`** carries the data under a
295
- top-level `support: { findings, templates }` key. Support output is **suppressed when streaming SARIF**
296
- (`--sarif -`) so stdout stays a clean code-scanning artifact.
297
-
298
- **External tickets are tool-neutral by contract** — they never name aih or its commands; they describe
299
- the failed *internal configuration* the recipient must fix at the system level. Each follows the
300
- structure **Summary → Impact → Issue → Observed evidence → Environment → Requested fix → Acceptance
301
- criteria**, and every escalation ends with a security work-around guard (keep TLS verification and secret
302
- controls enabled; don't change project code). Evidence, affected area, and acceptance criteria are canned
303
- per code — never guessed — with the live check detail riding along as evidence (redacted: home-dir
304
- scrubbed, secret-aware argv masking).
305
-
306
- **Project context (`SETUP.md`).** A project can shape the tickets with opt-in HTML-comment markers in
307
- `SETUP.md`, `docs/SETUP.md`, or `.aih/SETUP.md` (first found wins):
308
-
309
- - `<!-- support:why -->…<!-- /support:why -->` — *why a correct environment matters for this project*,
310
- woven into the ticket's Impact / "Why this helps" section. Falls back to the first paragraph under a
311
- `## Why` / `## Overview` / `## Purpose` / `## Background` / `## About` heading, so existing setup files
312
- contribute without edits.
313
- - `<!-- support:routing -->…<!-- /support:routing -->` — real routing metadata (assignment group, ticket
314
- prefix) rendered verbatim in the Environment block. **Never invented** — shown only when you provide it.
315
- - `<!-- support:language -->…<!-- /support:language -->` — an instruction to adapt the message to the
316
- org's corporate language, surfaced as a **terminal note** to the author, never embedded in the ticket
317
- body (which stays clean to paste).
311
+ Any verifying command (`aih doctor`, `aih heal`, `aih secrets --verify`, …) turns a failed or skipped
312
+ check that carries a `Check.code` into a ticket-ready support template — three registers keyed off who
313
+ fixes the issue, and external tickets are tool-neutral by contract (they never name aih). Labels print
314
+ by default; `--support-out <dir>` writes full tickets, `--json` carries them. Registers, redaction, and
315
+ the `SETUP.md` context markers: [docs/commands.md](docs/commands.md#support-tickets).
318
316
 
319
317
  ### Run ledger
320
318
 
@@ -346,11 +344,12 @@ aih usage --rollup ../repo-a,../repo-b
346
344
  [GitHub Milestones](https://github.com/samartomar/ai-harness/milestones).
347
345
  - **Changelog** — [CHANGELOG.md](CHANGELOG.md); tagged builds on
348
346
  [Releases](https://github.com/samartomar/ai-harness/releases).
349
- - **Versioning & support** — [VERSIONING.md](VERSIONING.md). SemVer; while pre-1.0 only the
350
- latest minor receives fixes.
347
+ - **Versioning & support** — [VERSIONING.md](VERSIONING.md). SemVer; from 1.0, security
348
+ fixes land on the latest **and the previous minor** (N-1) of the current major.
351
349
  - **Supply chain** — every release publishes via npm **Trusted Publishing** with build
352
- **provenance** and ships an **SPDX SBOM** + **SHA256 checksum** on the GitHub Release.
353
- Verify an install with `npm audit signatures`.
350
+ **provenance** and ships an **SPDX SBOM**, a **SHA256 checksum**, its keyless **cosign
351
+ signature bundle** (`SHA256SUMS.txt.sigstore.json`), and the Sigstore **build-provenance
352
+ bundle** on the GitHub Release. Verify an install with `npm audit signatures`.
354
353
  - **Support** — [SUPPORT.md](SUPPORT.md) · **Security** — [SECURITY.md](SECURITY.md)
355
354
  (private reporting) · **Contributing** — [CONTRIBUTING.md](CONTRIBUTING.md).
356
355
 
@@ -368,6 +367,15 @@ are enforced in [vitest.config.ts](vitest.config.ts) — set just below the achi
368
367
  levels so coverage only ratchets up; CI and releases fail on regression. See
369
368
  [CONTRIBUTING.md](CONTRIBUTING.md) for the contributor workflow.
370
369
 
370
+ ### Stability
371
+
372
+ The tests behind [The 1.0 contract](#the-10-contract) live in
373
+ [tests/contract/](tests/contract/): every command and option is snapshotted against a
374
+ committed fixture ([command-surface.json](tests/contract/command-surface.json)), the
375
+ `--json` envelope is schema-pinned, and exit-code semantics are pinned. Additive changes
376
+ regenerate the fixture in the same PR (label it `contract:additive`); removals or renames
377
+ of anything pinned are breaking and ship in majors only, per [STABILITY.md](STABILITY.md).
378
+
371
379
  ## License
372
380
 
373
381
  [Apache-2.0](LICENSE).