Files
tech-log-frontend/docs/superpowers/plans/2026-08-02-security-finalizer.md

5.2 KiB

Security Finalizer 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: Finalize a captured immutable candidate into one private random exact-five staging directory with strict v3 verification records and deterministic cleanup.

Architecture: finalizeVerifiedPromotion captures the archive, provider reports, and public keys before validation, evaluates only those captured bytes against archived local evidence, generates both v3 records in memory, and publishes five read-only files under a descriptor-relative runner-temp directory. The generated workflow consumes the returned staging path immediately and always invokes the token-bound cleanup CLI.

Tech Stack: Node.js 24, TypeScript, Zod, Vitest, bubblewrap-independent filesystem primitives, generated Gitea Actions YAML.

Global Constraints

  • Never accept pre-existing provider- or promotion-verification JSON as an input.
  • Stage exactly archive, vulnerability report, provenance attestation, provider verification v3, and promotion verification v3.
  • Use injected time and randomness for deterministic tests.
  • Use a random runner-temp directory at mode 0700, files at 0400, and O_EXCL | O_NOFOLLOW creation.
  • Do not claim that TypeScript closes the Gitea upload action pathname-reopen issue or guarantees renameat2 semantics.

Task 1: Exact-five finalizer contract

Files:

  • Modify: tests/unit/ci-artifact-contract.test.ts
  • Modify: scripts/lib/promotion-stager.ts
  • Modify: scripts/contracts/promotion-artifacts.ts

Interfaces:

  • Consumes: finalizeVerifiedPromotion(input, dependencies) with captured archive/report/key inputs.

  • Produces: { stagingRoot, cleanupToken, files } where files is the canonical exact-five name/digest list.

  • Step 1: Write failing tests for no pre-existing records, strict distinct v3 roles, exact provider-record and local-assessment hashes, full run/source/candidate/nonces/key/trust bindings, key rotation, captured-source mutation, and no output on failures.

  • Step 2: Run RED: corepack pnpm exec vitest run tests/unit/ci-artifact-contract.test.ts -t "verified promotion finalizer" --maxWorkers=1 and retain the first contract failure.

  • Step 3: Implement minimal finalizer changes so all validation and record generation consume captured bytes and both PASS records are created only after local/provider PASS.

  • Step 4: Run GREEN: rerun the focused Vitest command and require zero failures.

Task 2: Private staging and cleanup

Files:

  • Modify: tests/unit/ci-artifact-contract.test.ts
  • Modify: scripts/lib/promotion-stager.ts
  • Modify: scripts/cleanup-verified-promotion.ts

Interfaces:

  • Consumes: injected randomBytes, runner-temp root, cleanup token.

  • Produces: descriptor-relative random staging at 0700, exact files at 0400, and token-bound cleanup.

  • Step 1: Write failing tests for deterministic naming, modes, stable-path absence, exclusive no-follow creation, parent/leaf substitution, success cleanup, and failure cleanup.

  • Step 2: Run RED: use the Task 1 focused Vitest command and retain the first filesystem-boundary failure.

  • Step 3: Implement minimal private publication and cleanup changes using /proc/self/fd where available, bounded writes, identity rechecks, and removal of owned partial roots.

  • Step 4: Run GREEN: rerun the focused Vitest command and require zero failures.

Task 3: Workflow handoff

Files:

  • Modify: config/ci/gates.json
  • Modify: scripts/contracts/ci-gates.ts
  • Modify: scripts/stage-verified-promotion.ts
  • Modify: .gitea/workflows/quality-gates.yml
  • Modify: tests/unit/ci-workflow-generation.test.ts

Interfaces:

  • Consumes: finalizer step outputs staging_root and cleanup_token.

  • Produces: setup, three downloads, finalizer, immediate non-always() exact-five upload, and always() cleanup ordering.

  • Step 1: Write/update failing workflow assertions that reject standalone extraction, stable staging paths, missing --ignore-scripts, upload indirection, or cleanup ordering drift.

  • Step 2: Run RED: node scripts/generate-ci-workflow.ts --check and the workflow snapshot test.

  • Step 3: Update the CI contract/config and regenerate YAML with the finalizer output path and cleanup environment.

  • Step 4: Run GREEN: require workflow byte check and snapshot test PASS.

Task 4: Full verification and durable report

Files:

  • Modify: .superpowers/sdd/2026-08-01-quality-architecture-remediation/task-3-report.md

Interfaces:

  • Consumes: focused finalizer, provider, workflow, type, and lint evidence.

  • Produces: durable RED/GREEN evidence and a commit-ready report without overclaiming platform handoff guarantees.

  • Step 1: Run verification: focused finalizer/provider tests, check:supply-chain:provider-fixtures, workflow --check, check:types, and lint.

  • Step 2: Append exact RED/GREEN commands and outcomes to the task report, including the remaining Gitea upload and renameat2 limitations.

  • Step 3: Inspect diff/status and report completion before committing.