# 0.1.0 / 1.0 Readiness Gates

Status: **0.5.4** is the current release line (10 active packages, family subpaths, `^0.5.4` peers); **0.3.3** was the terminal 0.3.x cut; **0.1.7** was the terminal 0.1.x baseline; **1.0** readiness remains operator-gated, not automatic.

This page distills runnable readiness gates into one command-per-gate table.
The **Last evidence** column records the 0.1.0-tree snapshot (plan 012 Tasks
0–7, Node v24.18.0, Linux x86_64) with the 2026-07-26 **0.0.16** values kept
as the historical floor where the baseline predates it. Re-run each gate on
the release tree before cutting 1.0. The decision to cut 1.0 stays with the
operator after operator-gated legs run in a protected environment and Phase
12 demand evidence exists.

Evidence trail: [`docs/_evidence/review-coverage-2026-07-26-phase-11.md`](.././_evidence/review-coverage-2026-07-26-phase-11.md)
(addenda 0–9), [`docs/release-and-install.md`](.././release-and-install.md),
[`docs/migration.md`](.././migration.md), [`docs/performance.md`](.././performance.md),
[`docs/public-contracts.md`](.././public-contracts.md) (frozen 0.1.x contract).
The per-phase review-coverage evidence archive lives in [`docs/_evidence/`](.././_evidence/)
(plans 067–079, releases 0.0.4–0.0.16; tarball-excluded, kept in-repo for audit).
Historical release lines (0.0.16 floor → 0.0.27 Phase 10 ACP interop → 0.1.0)
keep their per-phase evidence in the pages above; this page records the 0.2.6
snapshot (plan 026) with the 0.1.x tables below as the historical record.

## Current line (0.5.4)

| Item | Status |
|---|---|
| Release graph | **56** publishable manifests at exact **0.3.0** (root + 55 workspace packages: 17 provider adapters + 10 `prism-*` family/profile + 28 capability; generated by `node scripts/package-truth.mjs` → `scripts/package-truth.json`; npm publication remains the operator handoff) |
| Current-line cut | The 0.3.x line starts with the final lockstep cut: optional host-owned Linux desktop control, coding/ACP tool closeouts, and independent package publication after the cut; live canaries and delegated agents remain later demand-gated work |
| Upgrade path | `docs/migration.md` `0.2.9 → 0.3.0` (additive; no store migration; rollback = restore 0.2.9 manifests/tag); internal first-party ranges become `^0.3.0` |
| Compat promise | Additive-only vs the frozen 0.2.9 baseline; package peers use Decision B's `^0.3.0` caret window and `scripts/compat-baseline` remains the reviewed declaration gate |
| Security policy | `npm audit --audit-level=moderate` 0 target at 0.3.0; desktop admission remains deny-by-default, mutators require approval + `ExecutionPolicy`, and package tags publish only changed packages |
| Docs freeze | tripwires green including the 56-package truth graph, Decision B range policy, the plan 030 freeze/release tests, coding/ACP tool regressions, and the host-owned desktop wrapper's fail-closed package/docs gates |
| 0.1.x line | **0.1.7** (plan 019) is the terminal 0.1.x baseline; the 0.1.1 table below keeps the plan 013 snapshot; the 0.1.0 table keeps the plan 012 snapshot; the **0.0.16** values remain the historical network-free floor |

## Previous line (0.1.1)

## Previous line (0.1.0)

| Item | Status |
|---|---|
| Published graph | **49** publishable manifests at exact **0.1.0** (root + 48 workspace packages; `docs/release-and-install.md`) |
| Phase 12 RC hardening | Freeze manifest (`scripts/phase12-freeze-manifest.json`): no new packages/exports/migrations/dependencies, additive-only compat promise vs `scripts/compat-baseline`; compatibility/support matrix machine-checked (Node 20+24 measured, PostgreSQL 16, linux-x64, protocol SDK pins) |
| Upgrade path | `docs/migration.md` `0.0.28 → 0.1.0` (no migration) + full `0.0.17 → 0.1.0` upgrade matrix (compatible / tested migration / tested refusal per release line) |
| Packed-install e2e journeys | enterprise + coding journeys install the exact packed 0.1.0 manifest graph into fresh consumers (`scripts/e2e-*-journey.test.mjs`, in `npm test`) |
| Protected restart-recovery evidence | `npm run test:postgres` includes `scripts/phase12-restart-recovery.test.mjs` (multi-replica kill/resume, unknown-outcome window, DB restart during streaming, reconnect/contention p95 vs frozen ceilings) |
| Capacity envelopes | `scripts/benchmark-0.1.0.json` — 24 network-free + 16 protected p95 rows under the frozen 0.1.0 contract, re-gated on every `npm test` |
| Security policy | `npm audit --audit-level=moderate` enforced in workflows; named threat-suites leg (`npm run security:threat-suites`); supply-chain negative fixtures in `scripts/release-gate.test.mjs` |
| Docs freeze | every public page, package README, and changelog consistent with 0.1.0 behavior; tripwires green (121/121) |
| Readiness table below | **0.0.16 measured values** remain the historical network-free floor; 0.1.0 evidence is recorded per row |

## Gate table

| Gate | Command | Last evidence (0.1.0 tree; 0.0.16 floor where noted) | Owner |
|---|---|---|---|
| Full quality gate | `npm run sdk:ready` | RC=0 at 0.1.0: typecheck (+examples), lint 0, format clean, full test, coverage, pack, release:gate (clean-checkout run is part of the operator release checklist). `npm run test:coverage` also prints the combined coverage summary (core + 41 workspace suites, additive reporting; core gate lines≥60 / functions≥70 / branches≥75 is the only hard threshold — plan 013 Task 3) | CI |
| Exact version graph | `node scripts/release.mjs check --version 0.1.0` | pass at 0.1.0: exact versions/ranges/lockfile/access + registry-collision check, **49** manifests | CI + operator |
| Frozen public API surface + compat gate | `node scripts/release.mjs gate` | 0 breaks / 0 errors vs checked-in baselines (`scripts/compat-baseline/`); additive-only delta (empty at the 0.0.28 → 0.1.0 bump) | CI |
| Migration coverage + docs tripwires | `node --test dist/__tests__/docs.test.js` | 121/121 at 0.1.0; `docs/migration.md` sections tripwired per release line | Maintainer |
| Deterministic artifact budget | `node --test dist/__tests__/budget-gate.test.mjs` | root 713.5 kB packed / 2.1 MB unpacked / 295 files within +5% of the regenerated 0.1.0 baseline; startup < 250 ms | CI (in `npm test`) |
| **0.1.0 capacity envelope (frozen performance contract)** | `node --test scripts/benchmark-0.1.0.test.mjs` | **`scripts/benchmark-0.1.0.json`** re-gated on every `npm test`: 24 network-free p95 rows ≤ frozen ceilings, 16 protected PostgreSQL rows ≤ budgets.json ceilings (50/100 ms), startup 41.7 ms < 250 ms, root pack within ±5%; regenerate with `node scripts/benchmark-0.1.0.mjs --out scripts/benchmark-0.1.0.json` (+ `PRISM_TEST_POSTGRES_URL` for protected legs) | CI (in `npm test`) |
| Performance benchmark medians | `node scripts/benchmark-0.1.0.mjs --out scripts/benchmark-0.1.0.json` (+ `PRISM_TEST_POSTGRES_URL` for the 16 protected rows) | envelope re-recorded at 0.1.0 (see capacity-envelope row above); historical phase medians remain in `docs/performance.md` | On-demand release evidence |
| Secret scan | `node scripts/scan-secrets.mjs` | 0.1.0 tree: 0 findings (3,095-file 0.0.16 floor) | CI |
| License / SBOM | `node scripts/verify-sbom.mjs` | 0.1.0 tree: 317 locked packages, allow-listed licenses (227/12 at 0.0.16 floor) | CI |
| Dependency audit | `npm audit --audit-level=moderate` | rc=0 (0 moderate+, 2 moderate at 0.0.16 baseline); 0 vulns at every severity for the 0.1.0 tree | CI |
| Whitespace hygiene | `git diff --check` | clean | CI |
| Publish order + tarball validation | `node scripts/release.mjs publish --version 0.1.0 --dry-run --allow-dirty --allow-untagged` | 49/49 packages `dry-run` twice with byte-identical reports, deterministic dependency order, no failures (Task 7) | Operator (dry-run), CI |
| Node 20 compatibility | CI `node20-compat` (build + public-import smoke) | all 21 root exports import cleanly on Node 20.20.2 | CI |
| PostgreSQL suite | `PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres` | 0.1.0: Phase 7 conformance + Phase 12 restart-recovery + 74 workspace checks green against PostgreSQL 16 (Task 4 recording, re-run green at 0.1.0 on 2026-08-09); operator-gated | Operator |
| Keychain suite | `PRISM_TEST_KEYCHAIN=1 npm test --workspace @arnilo/prism-core/credentials/node` (protected) | 28/28 green incl. native keychain round-trip against the OS secret-service backend (gnome-keyring, 2026-08-09) | Operator host |
| Live-provider suites | `npm run test:live` (protected) | **operator-gated** (requires credentials; `live-canaries.yml` blocked gate, `canary-report.json` retained) | Operator |
| SAST | GitHub CodeQL | **operator-gated** (runs in CI workflow) | CI |
| Signed, provenance publication | `npm run release:publish` (clean tagged tree, OIDC) | **operator-gated** (see "Remaining for 1.0") | Operator |

## Frozen public API surface

The compat gate diffs every package's generated `.d.ts` export surface against
checked-in baselines in `scripts/compat-baseline/` (one file per package,
regenerated at 0.1.0). It fails on any **removed** export or changed
declaration; additive exports are allowed. `scripts/release-gates.mjs` also
enforces a tarball deny list (no reviews/plans/maps/tests/binaries/credential
material in published artifacts) and exact version-range drift. A genuine break
requires `--allow-break` **and** a `docs/migration.md` entry mentioning the
version. The frozen 0.1.x contract (declaration/exports, events, protocol
payloads, migration checksums, patch-release compatibility promise) is
published in [docs/public-contracts.md](../public-contracts.md).

**Baseline maintenance:** `scripts/compat-baseline/` must stay committed.
Regenerate only after review with `node scripts/release.mjs gate --update-baseline`,
having first confirmed zero removed exports (the gate's order-sensitive
signatures can drift on a TypeScript bump without any real API change).

## Migration coverage

`docs/migration.md` carries release migration sections tripwired by
`docs.test.ts` (headings and key phrases). A missing or gutted section fails
the suite. **0.0.19** adds observational-memory lifecycle and nested settings in
`@arnilo/prism-compaction-observational-memory` — see `0.0.18 → 0.0.19 observational memory lifecycle`.
**0.0.18** adds intentional pre-1.0 breaks (`repo_search` literal-only,
`cache_aware` default layout, oldest-first history eviction, atomic write/edit
durability, MCP SDK bump) — see `0.0.17 → 0.0.18 restore integrity`.

## Budget table

Deterministic budgets (CI gate, `scripts/budget-gate.test.mjs`):

| Metric | Baseline | Tolerance | 0.1.0 measured |
|---|---|---|---|
| Root packed bytes | 713,454 (regenerated 0.1.0, dev-001) | +5% | 713.5 kB (within) |
| Root unpacked bytes | 2,388,118 | +5% | within |
| Root file count | 293 (regenerated 0.1.0, dev-001) | +5% | 295 (within) |
| Cold-startup import | 41.7 ms | ceiling 250 ms | within |

Baselines are the 0.1.0 snapshot (`scripts/budgets.json`, amended once by
freeze deviation dev-001 for the Task 1–5 evidence scripts); raise them only
after a deliberate reviewed performance change.

## Live-suite matrix (operator-gated)

| Suite | Command | Environment |
|---|---|---|
| PostgreSQL persistence | `npm run test:postgres` | live PostgreSQL |
| Keychain credentials | protected live suite | OS keychain |
| Provider live-canary (OpenAI/Anthropic/Google/Kimi/Ollama/…) | protected live-canary matrix | vendor credentials |
| RAG / memory / workflows live journeys | protected live-canary matrix | vendor + DB credentials |
| Enterprise adapters live canary (Phase 11: real OIDC IdP/JWKS, real OPA endpoint, real MCP OAuth authorization server, S3-compatible object store) | protected live-canary matrix | IdP / policy / object-store credentials |

These do not run on a contributor machine; their evidence is recorded in the
protected environment, never faked. Phase 11 live-endpoint evidence is a
**blocked release gate, not a passing skip**: `npm test` proves the seams
against network-free fake servers (`scripts/phase11-conformance.test.mjs`),
and the live matrix above stays blocked until the protected environment
records it.

## Packed-install e2e journeys (plan 012 Task 3)

| Journey | Command | Environment |
|---|---|---|
| Enterprise: OIDC identity → OPA policy decision → agent run with durable events → batched approval → OpenAPI side effect with idempotency → artifact upload + signed delivery | `npm test` (scripts/e2e-enterprise-journey.test.mjs) | network-free (memory stores, loopback fake servers); PostgreSQL leg when `PRISM_TEST_POSTGRES_URL` is set |
| Coding: ACP editor session (init capability negotiation, session new + load/resume) → bounded coding tools (git-aware list/search, glob, read-before-write write, delete, move) → sandboxed process session → forge handoff | `npm test` (scripts/e2e-coding-journey.test.mjs) | network-free (fake GitHub + git runner) |

Both install the exact packed manifest graph into a fresh consumer (`npm pack`
tarballs, never workspace paths) and run the journey against only public
exports. Each fixture ends with a success marker (`ENTERPRISE JOURNEY OK` /
`CODING JOURNEY OK`) that the test asserts. Runtime is bounded by
`e2eJourneyFixtureMsCeiling` in `scripts/phase12-freeze-manifest.json` (120 s
per fixture).

## Protected restart-recovery evidence (plan 012 Task 4)

| Leg | Command | Environment |
|---|---|---|
| Multi-replica kill/resume: replica A runs a durable agent (PostgreSQL checkpoints + durable events), suspends on a batched tool approval, and is SIGKILLed; replica B resumes with no event gap/duplicate, exactly-once durable tool effects, partial-approval re-suspend with CAS, and ownership rechecks | `npm run test:postgres` (scripts/phase12-restart-recovery.test.mjs) | live PostgreSQL 16 |
| Tool-effect unknown-outcome window: a dispatched-and-expired claim replays as `ERR_PRISM_TOOL_EFFECT_UNKNOWN` (reconciliation demanded), never a silent double-apply | `npm run test:postgres` (same suite) | live PostgreSQL 16 |
| Database restart during streaming: terminated LISTEN backend recovers by polling (missed event delivered, no gap) | `npm run test:postgres` (Phase 7 + Phase 12 legs) | live PostgreSQL 16 |
| Reconnect p95 + append contention p95 recorded against frozen ceilings (`reconnectP95Ms`, `pointOpP95Ms` in `scripts/phase12-freeze-manifest.json`) | `npm run test:postgres`; evidence in `scripts/phase12-restart-recovery.json` | live PostgreSQL 16 |

Missing `PRISM_TEST_POSTGRES_URL` is a **named, visible blocked gate**: `npm run
test:postgres` fails at `scripts/require-postgres-url.mjs`, and running the
suite directly records a `BLOCKED GATE` failure instead of a passing skip.
Durable ACP session registries and sandbox process sessions stay host-owned
by design (Prism provides the durable agent-run lifecycle underneath); the
coding journey and Phase 9/10 conformance suites cover their in-process
semantics, and the legs above prove the durable restart classes.

## Security matrix

| Control | Command / source | 0.0.16 baseline |
|---|---|---|
| Secret scan | `node scripts/scan-secrets.mjs` | 3095 files / 0 findings |
| License / SBOM | `node scripts/verify-sbom.mjs` | 227 packages / 12 licenses, allow-listed |
| Dependency audit | `npm audit --audit-level=moderate` | 0 high (2 moderate) at 0.0.16; **0 vulnerabilities at every severity for the 0.1.0 tree** (317 locked deps; MCP SDK 1.30.0 fix baseline) |
| SAST | GitHub CodeQL workflow | CI-gated |
| Sandbox / protocol / tenant threat suites | `npm test` (coding-security, MCP, policy, guardrail suites) | green at 0.0.16 |
| **0.1.0 threat-suites leg** | `npm run security:threat-suites` (Phase 8–11 conformance) + `npm run test:postgres` (Phase 7 tenant leg, blocked gate without URL) | 28/28 network-free at 0.1.0 recording |
| **Supply-chain negative fixtures** | `scripts/release-gate.test.mjs` | tampered tarball content, unexpected file types/credential material, and suppressed-provenance-in-CI all detected |
| Signed deterministic publication | `release.mjs publish` on clean tagged tree | operator-gated |

## Remaining for 1.0 (operator / protected environment)

Exact prerequisites that must be satisfied before cutting 1.0 (the 0.1.0
publication itself is the same list minus the 1.0-specific items):

1. **Signed tag + commits:** create and sign `v1.0.0` on a clean tree;
   `release.mjs publish` refuses real publication with `--allow-dirty`
   or `--allow-untagged` (verified: the 0.1.0 dry-run proceeds only with
   both flags, the real run always refuses).
2. **npm authentication + OIDC provenance/attestation:** publish with
   `--provenance` and `--access public` from the protected registry identity
   (the 0.1.0 publication is the first exercise of this operator step;
   `publishArgs` derives `--provenance` from `GITHUB_ACTIONS` and the
   release workflow holds `id-token: write` + `attestations: write`).
3. **Protected live-canary matrix green:** provider/RAG/memory/workflows live
   journeys pass with real credentials (`live-canaries.yml` — blocked gate,
   never a silent skip).
4. **PostgreSQL + keychain protected suites green.**
5. **CodeQL SAST green** on the release commit.
6. **`scripts/compat-baseline/` committed** (frozen 0.1.x baselines are
   already checked in).
7. **Phase 12 demand evidence** (below) recorded for any capability that 1.0
   is expected to anchor.
8. **0.1.0 lifecycle gates green** on the release candidate (docs suite,
   audit at moderate, coding-tool durability, layout/eviction defaults) —
   recorded in this page at 0.1.0.

## Phase 12 demand-evidence entry criteria

Phase 12 (demand-gated 0.1.x) promotes no capability on comparison-table parity
alone. Each candidate must present, before it becomes a numbered plan:

- **Named user** (a concrete person/team who will use it),
- **Concrete integration** (the real system it connects to),
- **Operational owner** (who runs and pages for it),
- **Measurable acceptance criteria** (scale/cost/latency/storage budgets that
  do not expand default core/install/runtime cost),
- then the pipeline: demand evidence → primitive review → threat model →
  optional package/service → conformance → release gate.

The readiness gates above are the stable API/compat/budget/security floor that
Phase 12 capabilities must consume and must not regress.
