Files
clean-architecture-frontend…/docs/superpowers/plans/2026-08-01-release-evidence-remediation.md
T

8.0 KiB

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.