@aihq/harness 1.0.0 → 1.2.0

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,40 +8,54 @@
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
- > Implements the architectural blueprint *"Enterprise DevSecOps AI Bootstrapping:
23
- > Cryptographic Trust, Local Performance Optimization, and Unified Observability"*
24
- > as a tested CLI.
23
+ See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the shipped architecture and
24
+ current trust boundaries.
25
25
 
26
26
  > **Provided as open-source software under Apache-2.0 on an "AS IS" basis.** No warranty,
27
27
  > support obligation, SLA, indemnity, consulting, or professional advice is provided. `aih`
28
28
  > is dry-run by default — review the plan before running `--apply`. See [DISCLAIMER.md](DISCLAIMER.md).
29
29
 
30
+ ## The 1.0 contract
31
+
32
+ Pin `@aihq/harness@^1` and automate against it. Every command, flag, and deprecated
33
+ alias is snapshot-tested in CI against a committed fixture, the `--json` envelope is
34
+ schema-pinned, and exit-code semantics are pinned — a surface change fails the build
35
+ until it ships as a reviewed contract decision. Renames ship as deprecated aliases
36
+ (the old name keeps working, with a one-line warning) before a major removes them,
37
+ and security fixes land on the latest and the previous minor. The full policy:
38
+ [STABILITY.md](STABILITY.md).
39
+
30
40
  ## Design posture
31
41
 
32
- - **Dry-run by default.** `aih <cmd>` computes and prints a plan; nothing is
33
- written until you add `--apply`. Add `--verify` to run read-only checks.
42
+ - **Dry-run by default for managed project changes.** `aih <cmd>` computes and
43
+ prints a plan; repo/workstation mutations wait for `--apply`. Named output
44
+ files (`--sarif`, `--support-out`, report outputs), browser launch flags
45
+ (`--open`, `--refresh`, `--demo`), the local run ledger, and `AIH_APPLY=1`
46
+ are explicit opt-ins rather than silent writes. Add `--verify` to run
47
+ read-only checks.
34
48
  - **Gated writes.** `--apply` refuses a dirty git worktree unless you add
35
49
  `--force`. Commands resolve a governance posture (`--posture vibe|team|enterprise`,
36
50
  default `vibe`): the skill-install gate refuses unapproved skills at
37
51
  `team`/`enterprise` and stays advisory at `vibe`; pack installs are fail-closed
38
52
  at every posture. Once a repo is initialised, every run is recorded in the
39
53
  local [run ledger](#run-ledger).
40
- - **Never mutates a remote system.** Every unit of work is a local `write`, a
41
- local `exec` (icacls/chmod/junction…), a read-only `probe`, or a `doc` (the
42
- exact commands for cloud setup SSO, gateways, Langfuse, MDM emitted for a
43
- human, never executed). There is no code path that provisions cloud infra, so
44
- an automated run cannot "fake" it.
54
+ - **No remote mutation except explicit signing flows.** Normal work is local:
55
+ `write`, `remove`, `exec`, `envblock`, `digest`, read-only `probe`, or `doc`
56
+ instructions for humans to run. The exceptions are opt-in provenance paths:
57
+ GitHub attestations can write to GitHub's attestation store, and keyless
58
+ cosign signing can append to Rekor.
45
59
  - **Idempotent & non-destructive.** Shell-profile edits live in marked managed
46
60
  blocks; JSON configs are deep-merged (your keys survive); every overwrite is
47
61
  backed up to `*.aih.bak` and rolls back as a transaction on failure.
@@ -60,6 +74,7 @@ Verify the install's origin — every release is published with build provenance
60
74
 
61
75
  ```bash
62
76
  npm audit signatures
77
+ aih verify-release # also checks GitHub release sums + cosign bundle
63
78
  ```
64
79
 
65
80
  <details><summary>From source (contributors)</summary>
@@ -81,51 +96,84 @@ aih init . --apply # apply it
81
96
 
82
97
  ## Command surface
83
98
 
99
+ One honest line per command — the long-form behavior detail for every command lives in
100
+ [docs/commands.md](docs/commands.md), and `aih <command> --help` is authoritative for flags.
101
+
102
+ ### Workstation & runtime
103
+
104
+ | Command | What it does |
105
+ | --- | --- |
106
+ | [`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. |
107
+ | [`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. |
108
+ | [`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. |
109
+ | [`aih ready`](docs/commands.md#aih-ready) | Grade a blocker-aware readiness verdict: can a developer start work with an AI agent here, now? |
110
+ | [`aih hardware`](docs/commands.md#aih-hardware) | Profile CPU/RAM/GPU and emit tuned Ollama/llama.cpp settings. |
111
+ | [`aih vdi`](docs/commands.md#aih-vdi) | Detect VDI (Citrix/WorkSpaces/RES/RDP) and redirect caches + SQLite to local scratch. |
112
+ | [`aih bootstrap`](docs/commands.md#aih-bootstrap) | Orchestrate the workstation 4-phase rollout (certs → hardware/vdi → telemetry). |
113
+
114
+ ### Repo canon & bootstrap
115
+
116
+ | Command | What it does |
117
+ | --- | --- |
118
+ | [`aih init`](docs/commands.md#aih-init) | Initialize a repo in one pass: profile + superpowers + bootstrap-ai + scaffold + secrets + guardrails + mcp + sandbox. |
119
+ | [`aih profile`](docs/commands.md#aih-profile) | Detect the repo's stack recursively and synthesize Cursor stack rules (`.cursor/rules/*.mdc`). |
120
+ | [`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. |
121
+ | [`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. |
122
+ | [`aih contract`](docs/commands.md#aih-contract) | Synthesize the machine-readable repo contract (`project.json`) from the detected stack. |
123
+ | [`aih adopt`](docs/commands.md#aih-adopt) | Converge an existing AI canon onto aih's managed model without overwriting your work (brownfield migration). |
124
+ | [`aih prune`](docs/commands.md#aih-prune) | Remove the stale per-CLI artifacts left for CLIs the repo no longer targets (reversible by default). |
125
+ | [`aih ecc`](docs/commands.md#aih-ecc) | Install affaan-m/ECC (skills, instincts, memory) for the selected CLIs via ECC's own installer. |
126
+ | [`aih superpowers`](docs/commands.md#aih-superpowers) | Install obra/Superpowers (brainstorm → plan → TDD → subagent-review skills) for the selected CLIs. |
127
+ | [`aih crispy`](docs/commands.md#aih-crispy) | Run the CRISPY context-engineering stage machine (deterministic, gate-ordered). |
128
+ | [`aih workspace`](docs/commands.md#aih-workspace) | Scaffold a multi-repo workspace at the parent folder: cross-repo map, combined MCP, `.code-workspace`. |
129
+
130
+ ### Skill governance & supply chain
131
+
84
132
  | Command | What it does |
85
133
  | --- | --- |
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. |
121
-
122
- 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).
134
+ | [`aih trust`](docs/commands.md#aih-trust) | Vet, pin, and gate external GitHub repos and skills before an agent acquires them. |
135
+ | [`aih skill`](docs/commands.md#aih-skill) | Govern the skill lifecycle vet approve inventory quarantine remove anchored in `aih-skills.lock.json`. |
136
+ | [`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. |
137
+ | [`aih marketplace`](docs/commands.md#aih-marketplace) | Build, validate, and publish a reproducible, verifiable distribution artifact from the approval lock never a registry. |
138
+ | [`aih policy`](docs/commands.md#aih-policy) | Validate the committed org policy or a policy-bundle envelope — as a read-only CI gate. |
139
+ | [`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. |
140
+ | [`aih bundle`](docs/commands.md#aih-bundle) | Build a deterministic fleet bundle (contract + policy + config) with checksums; `aih verify-bundle` re-checks any copy. |
141
+ | [`aih verify-release`](docs/commands.md#aih-verify-release) | Verify a published aih release: npm signatures, GitHub release cosign bundle, and tarball hash. |
142
+ | [`aih secrets`](docs/commands.md#aih-secrets) | Scan for plaintext `.env*`/`secrets/` and write agent deny rules; `--verify` is the secret-scan CI gate. |
143
+ | [`aih guardrails`](docs/commands.md#aih-guardrails) | Generate `.gitleaks.toml`, `.pre-commit-config.yaml`, and a CI license gate that blocks AGPL/strong-copyleft. |
144
+
145
+ ### Trust configuration notes
146
+
147
+ `trust.internalScopes` is intentionally inert until an org configures internal package scopes in
148
+ policy. Without that scope list, dependency-confusion checks still report general package risk but do
149
+ not guess which names are private to your organization.
150
+
151
+ ### Analytics & operations
152
+
153
+ | Command | What it does |
154
+ | --- | --- |
155
+ | [`aih report`](docs/commands.md#aih-report) | Render the read-only analytics digest context footprint, adoption, trends; `--v9`/`--open` build the offline HTML dashboard. |
156
+ | [`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. |
157
+ | [`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. |
158
+ | [`aih telemetry`](docs/commands.md#aih-telemetry) | Inject OpenTelemetry env, a redacting Bindplane collector, and an analytics fetcher. |
159
+ | [`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. |
160
+ | [`aih sandbox`](docs/commands.md#aih-sandbox) | Generate a devcontainer + managed sandbox settings (egress allowlist, `failIfUnavailable`). |
161
+
162
+ ### Verification
163
+
164
+ | Command | What it does |
165
+ | --- | --- |
166
+ | [`aih doctor`](docs/commands.md#aih-doctor) | Verify the workstation/repo configuration fail-closed; workspace mode validates each child repo. |
167
+ | [`aih status`](docs/commands.md#aih-status) | Show a read-only inventory of what the harness has configured. |
168
+
169
+ 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`/`verify-release` take the relevant subset).
123
170
  Settings also read from `AIH_*` env vars (`AIH_APPLY`, `AIH_CONTEXT_DIR`, `AIH_LOG`, …).
124
171
 
125
172
  ### Plugins
126
173
 
127
174
  At startup `aih` probes for exactly one optional peer package: **`@aihq/enterprise`** — the literal
128
- name, never env- or config-selectable, so nothing can point the probe at other code. When installed,
175
+ name, never env- or config-selectable, so nothing can point the probe at other code. The package name
176
+ is a reserved extension point; the open-source harness does not require it to be published. When installed,
129
177
  its `aihCommands` export (a `CommandSpec[]`) registers as native subcommands through the identical
130
178
  path as the built-ins: shared flags, posture resolution, the dirty-worktree gate, and the run ledger
131
179
  all apply unchanged. Not installed → zero output, fully local. `AIH_NO_PLUGINS=1` disables the
@@ -272,59 +320,22 @@ It writes, at the parent (it does **not** touch the child repos — run `aih ini
272
320
 
273
321
  ### Support tickets
274
322
 
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).
323
+ Any verifying command (`aih doctor`, `aih heal`, `aih secrets --verify`, …) turns a failed or skipped
324
+ check that carries a `Check.code` into a ticket-ready support template — three registers keyed off who
325
+ fixes the issue, and external tickets are tool-neutral by contract (they never name aih). Labels print
326
+ by default; `--support-out <dir>` writes full tickets, `--json` carries them. Registers, redaction, and
327
+ the `SETUP.md` context markers: [docs/commands.md](docs/commands.md#support-tickets).
318
328
 
319
329
  ### Run ledger
320
330
 
321
331
  Every `aih` invocation appends one structured row to **`.aih/runs/YYYY-MM.jsonl`** (UTC, month-sharded,
322
- append-only) — a "what happened" diagnostics trail: run id, capability, redacted argv, status (`success` /
323
- `failed` / `partial` / `error`), exit code, mode (apply/verify/json/sarif), platform, write tally, and
324
- verification + support counts. It's distinct from `.aih/history.jsonl` (the per-commit metrics behind
325
- `aih report` trends). Logging is **on only after the repo is initialised** (a committed `.aih-config.json`
326
- marker exists) and never fails a command; opt out with **`--no-log`** or **`AIH_LOG=0`**. Like all of
327
- `.aih/`, the ledger is gitignored local diagnostics — never committed.
332
+ append-only) — a "what happened" diagnostics trail: schema version, run id, capability, redacted argv,
333
+ status (`success` / `failed` / `partial` / `error`), exit code, mode (apply/verify/json/sarif), platform,
334
+ host hash, repo remote hash, write tally, and verification + support counts. It's distinct from
335
+ `.aih/history.jsonl` (the per-commit metrics behind `aih report` trends). Logging is **on only after the
336
+ repo is initialised** (a committed `.aih-config.json` marker exists) and never fails a command; opt out
337
+ with **`--no-log`** or **`AIH_LOG=0`**. Like all of `.aih/`, the ledger is gitignored local diagnostics
338
+ — never committed. For tamper-evident sharing, package it with `aih evidence build`.
328
339
 
329
340
  ### Examples
330
341
 
@@ -346,11 +357,14 @@ aih usage --rollup ../repo-a,../repo-b
346
357
  [GitHub Milestones](https://github.com/samartomar/ai-harness/milestones).
347
358
  - **Changelog** — [CHANGELOG.md](CHANGELOG.md); tagged builds on
348
359
  [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.
360
+ - **Versioning & support** — [VERSIONING.md](VERSIONING.md). SemVer; from 1.0, security
361
+ fixes land on the latest **and the previous minor** (N-1) of the current major.
351
362
  - **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`.
363
+ **provenance** and ships an **SPDX SBOM**, a **SHA256 checksum**, its keyless **cosign
364
+ signature bundle** (`SHA256SUMS.txt.sigstore.json`), and the Sigstore **build-provenance
365
+ bundle** on the GitHub Release. This is SLSA v1 provenance material, but the project does
366
+ not claim a SLSA level. Verify an install with `npm audit signatures` and
367
+ `aih verify-release [version]`.
354
368
  - **Support** — [SUPPORT.md](SUPPORT.md) · **Security** — [SECURITY.md](SECURITY.md)
355
369
  (private reporting) · **Contributing** — [CONTRIBUTING.md](CONTRIBUTING.md).
356
370
 
@@ -370,14 +384,12 @@ levels so coverage only ratchets up; CI and releases fail on regression. See
370
384
 
371
385
  ### Stability
372
386
 
373
- The CLI surface and machine-readable outputs are contract-tested in
387
+ The tests behind [The 1.0 contract](#the-10-contract) live in
374
388
  [tests/contract/](tests/contract/): every command and option is snapshotted against a
375
389
  committed fixture ([command-surface.json](tests/contract/command-surface.json)), the
376
- `--json` envelope is schema-pinned, and exit-code semantics are pinned. Any drift fails
377
- CI and forces a reviewed decision additive changes regenerate the fixture in the same
378
- PR (label it `contract:additive`); removals or renames of anything pinned are breaking
379
- and ship in majors only, per the stability policy in [STABILITY.md](STABILITY.md) —
380
- renames ship with a deprecated alias of the old name until the removing major.
390
+ `--json` envelope is schema-pinned, and exit-code semantics are pinned. Additive changes
391
+ regenerate the fixture in the same PR (label it `contract:additive`); removals or renames
392
+ of anything pinned are breaking and ship in majors only, per [STABILITY.md](STABILITY.md).
381
393
 
382
394
  ## License
383
395