@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 +126 -114
- package/dist/{chunk-HPWF2YPV.js → chunk-GU5HPSI6.js} +346 -216
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +16 -6
- package/dist/index.js +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -8,40 +8,54 @@
|
|
|
8
8
|
[](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
|
|
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
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
evidence — anchored in a
|
|
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
|
-
|
|
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
|
|
33
|
-
|
|
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
|
-
- **
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
87
|
-
| `aih
|
|
88
|
-
| `aih
|
|
89
|
-
| `aih
|
|
90
|
-
| `aih
|
|
91
|
-
| `aih
|
|
92
|
-
| `aih
|
|
93
|
-
| `aih
|
|
94
|
-
| `aih
|
|
95
|
-
| `aih
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
| `aih
|
|
108
|
-
| `aih
|
|
109
|
-
| `aih
|
|
110
|
-
| `aih
|
|
111
|
-
| `aih
|
|
112
|
-
| `aih
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
| `aih
|
|
119
|
-
| `aih
|
|
120
|
-
|
|
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.
|
|
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
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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,
|
|
323
|
-
`failed` / `partial` / `error`), exit code, mode (apply/verify/json/sarif), platform,
|
|
324
|
-
verification + support counts. It's distinct from
|
|
325
|
-
`aih report` trends). Logging is **on only after the
|
|
326
|
-
marker exists) and never fails a command; opt out
|
|
327
|
-
`.aih/`, the ledger is gitignored local diagnostics
|
|
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;
|
|
350
|
-
latest minor
|
|
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
|
|
353
|
-
|
|
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
|
|
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.
|
|
377
|
-
|
|
378
|
-
|
|
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
|
|