111 lines
8.0 KiB
Markdown
111 lines
8.0 KiB
Markdown
# Release Evidence Remediation Implementation Plan
|
|
|
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
|
|
**Goal:** Build one immutable release bundle and fail promotion unless every artifact, provider report, schema, and digest proves it describes those exact bytes.
|
|
|
|
**Architecture:** Executable Zod contracts validate artifacts at every writer boundary. One fail-closed tracked-file inventory feeds security and provenance. CI creates the candidate once, scans that candidate, then promotes it without rebuilding.
|
|
|
|
**Tech Stack:** TypeScript 7, Node.js 24, Zod 4, Vite 8, Gitea Actions, Vitest 4.
|
|
|
|
## Global Constraints
|
|
|
|
- Repository code validates but never fabricates external vulnerability or signed provenance evidence.
|
|
- Missing evidence, unreadable required roots, tool crashes, signals, timeouts, and digest mismatch fail closed.
|
|
- V2 release identity is its exact contract package set and recomputed set digest; no scalar version is synthesized.
|
|
- Promotion consumes the same archived `dist` and `distSha256` produced by `immutable_build`.
|
|
- All production changes start with a failing fixture or unit test.
|
|
|
|
---
|
|
|
|
### Task 1: One V1/V2 runtime coherence verifier
|
|
|
|
**Files:**
|
|
- Create: `scripts/lib/release-runtime-coherence.ts`
|
|
- Modify: `scripts/verify-release.ts`
|
|
- Modify: `scripts/drill-runbook.ts`
|
|
- Modify: `src/contracts/release-tokens.ts`
|
|
- Modify: `tests/unit/release-coherence.test.ts`
|
|
- Modify: `tests/unit/release-artifacts.test.ts`
|
|
|
|
- [ ] Add a shared matrix covering V1 scalar success/mismatch and V2 package add/remove/version/digest tampering. Assert verifier and rollback drill return identical verdicts.
|
|
- [ ] Run `corepack pnpm exec vitest run tests/unit/release-coherence.test.ts tests/unit/release-artifacts.test.ts` and confirm RED because the drill compares only scalar release tokens.
|
|
- [ ] Implement async `verifyReleaseRuntimeCoherence({ release, runtime, contractPackages })`; V1 delegates to legacy scalar policy, V2 checks exact sorted package tuples then recomputes `contractSet.setDigest`.
|
|
- [ ] Remove V2 synthetic `0`/legacy scalar projection from `release-tokens.ts`; call the shared verifier from both scripts.
|
|
- [ ] Re-run the focused tests and commit with `git commit -m "fix: unify release runtime coherence verification"`.
|
|
|
|
### Task 2: Validated artifact writers and generated JSON schemas
|
|
|
|
**Files:**
|
|
- Create: `scripts/lib/validated-json-artifact.ts`
|
|
- Create: `scripts/generate-artifact-schemas.ts`
|
|
- Modify: `scripts/contracts/release-artifacts.ts`
|
|
- Modify: `scripts/generate-build-manifest.ts`
|
|
- Modify: `scripts/generate-supply-chain.ts`
|
|
- Modify: `scripts/collect-web-vitals-evidence.ts`
|
|
- Modify: `scripts/test-performance.ts`
|
|
- Modify: `scripts/verify-release.ts`
|
|
- Modify: `scripts/drill-runbook.ts`
|
|
- Modify: `schemas/artifacts/build-manifest.schema.json`
|
|
- Modify: `schemas/artifacts/dependency-inventory.schema.json`
|
|
- Modify: `schemas/artifacts/registry-snapshot.schema.json`
|
|
- Modify: `schemas/artifacts/supply-chain-verification.schema.json`
|
|
- Create: `tests/unit/validated-json-artifact.test.ts`
|
|
- Modify: `tests/unit/release-artifacts.test.ts`
|
|
- Modify: `tests/unit/json-schema.test.ts`
|
|
|
|
- [ ] Add tests proving invalid values do not touch the destination, a valid write is atomic, and `generate-artifact-schemas.ts --check` reports checked-in drift.
|
|
- [ ] Run focused tests and confirm RED because writers call `writeFile` directly and schemas are hand-maintained.
|
|
- [ ] Implement `writeValidatedJsonArtifact({ path, schema, value })`: parse first, write a sibling temporary file, rename atomically, and clean only its explicit temp file on failure.
|
|
- [ ] Route every listed writer through the helper. Generate draft-2020-12 schemas deterministically with `additionalProperties: false` and stable final newline.
|
|
- [ ] Add `generate:artifact-schemas` and `check:artifact-schemas` scripts; run generation then check mode.
|
|
- [ ] Run `corepack pnpm exec vitest run tests/unit/validated-json-artifact.test.ts tests/unit/release-artifacts.test.ts tests/unit/json-schema.test.ts` and commit with `git commit -m "refactor: validate generated evidence artifacts"`.
|
|
|
|
### Task 3: Manifest outputs and fail-closed repository inventory
|
|
|
|
**Files:**
|
|
- Create: `scripts/lib/repository-file-inventory.ts`
|
|
- Create: `scripts/lib/build-manifest-outputs.ts`
|
|
- Modify: `scripts/generate-supply-chain.ts`
|
|
- Modify: `scripts/security-scan.ts`
|
|
- Modify: `scripts/verify-release.ts`
|
|
- Modify: `config/security/secret-scan-policy.json`
|
|
- Modify: `tests/unit/supply-chain.test.ts`
|
|
- Create: `tests/unit/repository-file-inventory.test.ts`
|
|
- Modify: `tests/unit/release-artifacts.test.ts`
|
|
|
|
- [ ] Add fixtures for missing required root, optional `ENOENT`, unreadable file, untracked omission, path traversal, module-inventory tamper, and hash mismatch.
|
|
- [ ] Run focused tests and confirm current discovery skips read failures and verification accepts a stale `moduleInventoryHash`.
|
|
- [ ] Build inventory from `git ls-files -z` plus explicitly generated inputs; normalize and confine every path under repository root. Only configured optional roots may ignore exact `ENOENT`.
|
|
- [ ] Make provenance and secret scan consume the same inventory. Add `index.html`, Vite configs, all TS configs, `.nvmrc`, package/lock files, scripts, schemas, configs, and `.gitea/workflows/quality-gates.yml` to mandatory policy coverage.
|
|
- [ ] Implement `verifyBuildManifestOutputs` to confine declared output paths, read module inventory bytes, and compare raw SHA-256 to `moduleInventoryHash`.
|
|
- [ ] Re-run focused tests and commit with `git commit -m "fix: fail closed on release input discovery"`.
|
|
|
|
### Task 4: Immutable candidate, provider evidence, and promotion
|
|
|
|
**Files:**
|
|
- Modify: `package.json`
|
|
- Modify: `scripts/generate-supply-chain.ts`
|
|
- Modify: `scripts/verify-supply-chain-artifacts.ts`
|
|
- Modify: `scripts/verify-supply-chain-promotion.ts`
|
|
- Modify: `scripts/check-supply-chain-provider-fixtures.ts`
|
|
- Modify: `tests/unit/supply-chain.test.ts`
|
|
- Modify: `.gitea/workflows/quality-gates.yml`
|
|
|
|
- [ ] Add fixtures for absent provider evidence, valid matching digest, wrong digest, and post-attestation byte change. Assert only the valid immutable fixture passes promotion.
|
|
- [ ] Run `corepack pnpm exec vitest run tests/unit/supply-chain.test.ts && corepack pnpm check:supply-chain:provider-fixtures` and confirm RED for promotion wiring.
|
|
- [ ] Split scripts into `build:release-candidate`, `verify:local-evidence`, `verify:provider-evidence`, and `verify:promotion`; remove any build command from promotion.
|
|
- [ ] `immutable_build` archives `dist`, build manifest, module inventory, and local evidence together and publishes `distSha256`. Provider jobs download that archive and emit reports bound to the digest.
|
|
- [ ] Promotion downloads the same archive plus provider reports, exports `VULNERABILITY_REPORT_PATH` and `PROVENANCE_ATTESTATION_PATH`, verifies all schemas/signatures/digests, and uploads/deploys the unchanged bundle.
|
|
- [ ] Verify missing external evidence remains `FAIL_UNVERIFIED`; do not add a repository-generated passing provider fixture to production flow.
|
|
- [ ] Re-run fixtures and the workflow contract check, then commit with `git commit -m "fix: promote immutable verified release bundles"`.
|
|
|
|
### Task 5: Release/evidence verification
|
|
|
|
- [ ] Run `corepack pnpm check:artifact-schemas`.
|
|
- [ ] Run `corepack pnpm exec vitest run tests/unit/release-artifacts.test.ts tests/unit/release-coherence.test.ts tests/unit/validated-json-artifact.test.ts tests/unit/repository-file-inventory.test.ts tests/unit/supply-chain.test.ts tests/unit/json-schema.test.ts`.
|
|
- [ ] Run `corepack pnpm check:supply-chain:fixtures` and `corepack pnpm check:supply-chain:provider-fixtures`.
|
|
- [ ] Run the candidate build and local release verification with deterministic local environment values.
|
|
- [ ] Confirm promotion fails specifically with `FAIL_UNVERIFIED` when real external evidence paths are absent.
|
|
- [ ] Run `corepack pnpm check:types`, `corepack pnpm lint`, and `git diff --check`.
|