Files
tech-log-frontend/docs/superpowers/plans/2026-08-02-frontend-platform-consumer-migration.md
T

31 KiB
Raw Blame History

Frontend Thin Platform Consumer Migration 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. Use superpowers:using-git-worktrees before editing.

Goal: Convert clean-architecture-frontend-template into a thin consumer of test-assurance-platform and cicd-platform while preserving product source, tests, fixtures, raw product artifact codecs, and all origin-unknown worktree changes.

Architecture: Product manifests declare risks, obligations, suites, components, outputs, and platform capabilities. Product scripts execute one bounded product purpose and emit raw artifacts. Test assurance owns selection through assessment; CI/CD owns workflow through promotion. Shadow mode has one candidate writer—the platform—and legacy release/promotion code is read-only until removed. The central required workflow is installed by the platform and is never copied into this repository.

Tech Stack: TypeScript 7.0.2, Node.js 24.14.0, pnpm 11.17.0, Vitest 4.1.10, Playwright 1.62.0, YAML/JSON Schema, testctl v3, cicdctl.

Global Constraints

  • Repository: /home/donghyeon/workspace/desktop-server-git/clean-architecture-frontend-template; every command runs from its isolated migration worktree root unless it is explicitly marked read-only against the original dirty worktree.

  • Begin only from a clean worktree whose HEAD contains the approved spec amendment and all three 2026-08-02 plans in one immutable planning commit; never modify or clean the original dirty worktree.

  • Consume the immutable Test Assurance Task 10 release and CI/CD Task 11 P1/shadow release from the two companion plans.

  • Resolve CICDCTL_BIN and TESTCTL_BIN to absolute executable paths from the signed CICD catalog, and resolve CICDCTL_DIGEST and TESTCTL_DIGEST from the same catalog. Before every plan/manifest command, sha256sum must equal the signed value; PATH fallback is forbidden.

  • Do not claim P2/active or delete the legacy path until actual Gitea/runner/scanner/signer/provider evidence and required-status installation are observed.

  • Use only the exact capability IDs approved in the design.

  • Keep production code, product tests/assertions, mocks, scenarios, fixtures, Vitest/Playwright config, V8 instrumentation inputs, and runtime/release artifact codecs.

  • Remove local workflow compilation, risk selection, waiver/normalization/assessment, test scheduling, provider invocation, signing, retention, candidate publication, and promotion engines after cutover.

  • check:types remains a CI Node responsibility. check:architecture alone maps to architecture-typescript.

  • Artifact browser suites consume the platform candidate; their Playwright webServer must never rebuild it.

  • The product does not add .gitea/workflows/required-delivery-guard.yaml or any equivalent copied central workflow.

  • Rollback changes only the signed platform catalog/version pin and promotes a previous immutable subject through release-control; it never re-enables a legacy writer.


Task 1: Preserve and classify the existing dirty Task 3 work

Files:

  • Create in the clean migration worktree: docs/migration/task3-wip-provenance.json
  • Create: docs/migration/task3-wip-disposition.md
  • Read only: original dirty worktree tracked diff and untracked files

Ledger contract: Each entry records path, workingBlobSha256, and an ordered hunks array. Every hunk records oldRange, newRange, diffSha256, owner (product, test-assurance, cicd, unrelated-or-unknown), provenance, and disposition (preserve-in-original, reimplement-in-platform, retain-product-codec, remove-after-cutover). Mixed-responsibility files therefore have multiple hunk owners. The ledger does not copy source content or create a patch archive.

  • Verify the migration worktree entry commit before inspecting WIP:
git show HEAD:docs/superpowers/specs/2026-08-02-platform-owned-frontend-assurance-delivery-design.md
git show HEAD:docs/superpowers/plans/2026-08-02-frontend-platform-consumer-migration.md
git show HEAD:docs/superpowers/plans/2026-08-02-test-assurance-frontend-capabilities.md
git show HEAD:docs/superpowers/plans/2026-08-02-cicd-frontend-assurance-delivery.md
git status --short

Expected: all four documents exist and migration-worktree status is empty.

  • Capture git status --short, git diff --name-status, git diff --numstat, git diff | sha256sum, per-hunk unified diffs, and git hash-object for each present untracked/modified file without writing to the original worktree.
  • Add a failing migration test in tests/unit/platform-migration-provenance.test.ts that requires every hunk to have one owner/provenance/disposition, permits mixed owners per file, and rejects a blanket frontend/keep-all classification.
  • Run:
corepack pnpm exec vitest run tests/unit/platform-migration-provenance.test.ts

Expected: RED because the ledger does not exist.

  • Create the ledger and disposition document with apply_patch. Explicitly classify workflow/gate/test-normalization/provider/promotion WIP to its platform owner and origin-unknown files as preserved in the original worktree.
  • Recompute every original working-blob and hunk digest, re-run the test, and compare original status plus digests with the capture; expected PASS with no drift.
  • Commit only the ledger, disposition, and test:
git add docs/migration/task3-wip-provenance.json docs/migration/task3-wip-disposition.md tests/unit/platform-migration-provenance.test.ts
git commit -m "docs: preserve Task 3 migration provenance"

Task 2: Declare the CI/CD platform consumer

Files:

  • Create: delivery-platform.yaml
  • Create: tests/unit/delivery-platform-manifest.test.ts

Selected capabilities:

ci-standard-core
ci-node-typescript
ci-frontend
ci-test-assurance
ci-dependency-vulnerability
ci-sbom
ci-provenance
ci-artifact-signing
ci-static-artifact-supply-chain
ci-static-site-publish
delivery-release-control

The manifest declares one frontend component rooted at ., one static-site output rooted at dist, pnpm frozen install, lint, check:types, build, the size/environment/determinism policy, and a signed platformVersion that exists in the released CI/CD catalog. It does not contain a workflow DAG, provider command, test command, or mutable tool image.

  • Add RED tests that invoke $CICDCTL_BIN manifest compile after digest verification and reject missing capabilities, a floating platform version, product-owned test stages, arbitrary shell/provider commands, or a second candidate output.
  • Run:
corepack pnpm exec vitest run tests/unit/delivery-platform-manifest.test.ts

Expected: RED because delivery-platform.yaml is absent.

  • Add the manifest only; do not add a package script that could resolve an arbitrary PATH binary or local compilation logic.
  • Compile the manifest with "$CICDCTL_BIN" manifest compile --manifest delivery-platform.yaml --source-revision "$PLATFORM_SOURCE_REVISION" --output artifacts/platform/effective-project.json; expected PASS at shadow activation.
  • Commit:
git add delivery-platform.yaml tests/unit/delivery-platform-manifest.test.ts
git commit -m "chore(platform): declare frontend delivery capabilities"

Task 3: Declare risks, obligations, change surfaces, and source suites

Files:

  • Create: test-assurance.yaml
  • Create generated: test-assurance.lock.json
  • Create: config/test-assurance/risks/frontend.json
  • Create: config/test-assurance/obligations/frontend.json
  • Create: config/test-assurance/suites/source.json
  • Create: config/test-assurance/suites/artifact-templates.json
  • Create: config/test-assurance/change-surfaces/frontend.json
  • Create: config/test-assurance/legacy-command-disposition.json
  • Create: scripts/run-contract-negative-fixtures.ts
  • Create: scripts/reporters/vitest-discovery-reporter.ts
  • Create: scripts/write-production-module-inventory.ts
  • Modify: scripts/check-architecture.ts
  • Modify: vitest.config.ts
  • Create: tests/unit/test-assurance-source-manifest.test.ts
  • Create: tests/unit/raw-source-reporters.test.ts
  • Create: tests/unit/legacy-command-migration-completeness.test.ts
  • Modify: package.json

Source suite mapping:

Suite ID Product argv Capability
runtime-schema corepack pnpm test:runtime-schema unit-typescript-vitest
unit corepack pnpm test:unit unit-typescript-vitest
reference-feature corepack pnpm test:reference-feature unit-typescript-vitest
optional-recipes corepack pnpm test:recipes unit-typescript-vitest
component corepack pnpm test:component component-react-vitest
integration corepack pnpm test:integration integration-http-msw
http-scenarios corepack pnpm test:http-scenario-evidence integration-http-msw
architecture corepack pnpm check:architecture architecture-typescript
coverage corepack pnpm test:coverage coverage-v8
contract-negative-fixtures corepack pnpm test:contract-negative-fixtures unit-typescript-vitest

Every source suite declares executionPhase: SOURCE, an empty requiredInputArtifacts, a bounded argv array, timeouts, environment allowlist, and exact raw artifacts. check:types is absent because CI owns it. test-assurance.yaml references artifact-templates.json through artifactSuiteTemplateFiles; those templates are completed in Task 4.

  • Add RED tests for exact capability IDs, one purpose per suite, no aggregate test:all, no check:types, no shell string, no --passWithNoTests on required suites, exact report paths, and source phase with zero input artifacts.
  • Parse every unique command and argument tuple in legacy config/ci/gates.json and require exactly one disposition: ci-node, test-assurance-suite, cicd-release-or-security, product-dev-only, or retired-with-platform-evidence. Missing or duplicate classification fails.
  • Add test:contract-negative-fixtures as one bounded product harness: it runs every expected-fail type/coverage/design-system/i18n/diagnostics/registry/route fixture, asserts the exact expected exit code and diagnostic identity from the disposition file, and exits 0 only when all negative contracts fail for the intended reason.
  • Classify test:browser-capabilities into the three artifact browser suites, test:storybook as a retained source test harness until an explicit platform disposition is proven, and playwright.dev.config.ts as product-dev-only; no legacy gate command disappears without platform evidence.
  • Add RED reporter tests requiring Vitest discovery IDs/counts alongside JUnit, a canonical production-module inventory alongside V8 coverage, an architecture graph/violations report, and typed HTTP receipts. These are raw observations only and contain no PASS/waiver/threshold decision.
  • Run the focused test; expected RED.
  • Add declarations. Remove --passWithNoTests from required source suite scripts while retaining optional behavior only for suites whose obligation explicitly permits no applicable tests. Wire the Vitest reporter into each required Vitest suite, make check:architecture emit the typed graph/violation JSON, and rewrite test:coverage to emit V8 summary plus production inventory without calling the local risk/threshold assessor.
  • Use released testctl validate, lock, and compile to generate the lock; never type toolchain digests by hand.
  • Re-run the focused test and:
"$TESTCTL_BIN" validate --repository . --out artifacts/platform/source-validation.json
"$TESTCTL_BIN" lock --repository . --out test-assurance.lock.json
"$TESTCTL_BIN" compile --repository . --lock test-assurance.lock.json --out artifacts/platform/compiled-policy.json

Expected: PASS with v3 and exact Node/pnpm/TypeScript/Vitest/Playwright pins.

  • Commit:
git add test-assurance.yaml test-assurance.lock.json config/test-assurance scripts/reporters/vitest-discovery-reporter.ts scripts/write-production-module-inventory.ts scripts/check-architecture.ts scripts/run-contract-negative-fixtures.ts vitest.config.ts tests/unit/test-assurance-source-manifest.test.ts tests/unit/raw-source-reporters.test.ts tests/unit/legacy-command-migration-completeness.test.ts package.json
git commit -m "chore(test-assurance): declare frontend source suites"

Task 4: Make browser suites consume the immutable candidate

Files:

  • Modify: playwright.config.ts
  • Modify: playwright.capabilities.config.ts
  • Modify: playwright.visual.config.ts
  • Modify: playwright.storybook.config.ts only if it remains a required artifact suite
  • Create: scripts/serve-test-candidate.ts
  • Create: scripts/reporters/playwright-evidence-reporter.ts
  • Create: tests/support/browser/mutation-evidence.ts
  • Modify: tests/e2e/reference-form.spec.ts
  • Modify: package.json
  • Modify: config/test-assurance/suites/artifact-templates.json
  • Modify: config/test-assurance/obligations/frontend.json
  • Create: tests/unit/artifact-suite-contract.test.ts

Artifact suite mapping:

Suite ID Product argv Capability
e2e-chromium corepack pnpm test:e2e:chromium e2e-playwright-chromium
e2e-firefox corepack pnpm test:e2e:firefox e2e-playwright-firefox
e2e-webkit corepack pnpm test:e2e:webkit e2e-playwright-webkit
accessibility corepack pnpm test:a11y accessibility-web
visual-regression corepack pnpm test:visual visual-regression-web

All five repository templates declare executionPhase: ARTIFACT and one input declaration containing artifactId: frontend-site and mediaType: application/vnd.delivery.static-site.v1+tar. Templates contain no sha256 field. After the platform builds the candidate, CI creates an artifact ExecutionRequest containing the actual candidate SHA-256; testctl materializes executable v3 SuiteDefinition and WorkItem documents with that exact digest.

  • Add RED tests requiring separate Chromium/Firefox/WebKit commands and artifacts, rejecting a SHA/digest placeholder in committed templates, rejecting build commands in Playwright webServer, requiring candidate-root environment input, and checking typed Playwright JSON/JUnit, trace/screenshot/console/network indexes, browser provider identity, write mutation receipts, accessibility/manual-review identity, and visual baseline/diff identity.
  • Run the focused test; expected RED because browser configuration currently rebuilds the site.
  • Implement serve-test-candidate.ts as a bounded read-only static server over the executor-verified candidate directory. It reads the candidate root from the allowlisted environment and never verifies or substitutes the platform digest itself.
  • Change playwright.config.ts and playwright.capabilities.config.ts to call that server and add per-browser package scripts using --project; each browser suite includes both tests/e2e/ and tests/browser-capabilities/. Add the product-owned Playwright reporter and mutation-evidence helper so tests emit traces, screenshots, console/network indexes, response/mutation/reload receipts, accessibility findings/manual records, and visual baselines/diffs without assessing them. Extend reference-form.spec.ts with the existing production-shaped create handler: observe the successful HTTP response, read the created resource, reload, read it again, and write one typed receipt keyed by the test/scenario ID.
  • Validate/lock/compile with testctl and run each product suite against a local candidate materialized by the platform fixture.
  • Commit:
git add playwright.config.ts playwright.capabilities.config.ts playwright.visual.config.ts playwright.storybook.config.ts scripts/serve-test-candidate.ts scripts/reporters/playwright-evidence-reporter.ts tests/support/browser/mutation-evidence.ts tests/e2e/reference-form.spec.ts package.json config/test-assurance tests/unit/artifact-suite-contract.test.ts
git commit -m "refactor(browser): test the immutable platform candidate"

Task 5: Separate raw reporters and freeze legacy assurance as read-only

Files:

  • Retain/refactor: scripts/run-http-scenario-evidence.ts
  • Retain/refactor: scripts/lib/http-scenario-evidence.ts
  • Retain/refactor: scripts/write-a11y-report.ts
  • Create: scripts/lib/manual-a11y-record.ts
  • Retain: product V8 instrumentation and module-inventory code in vite.config.ts, vitest.config.ts, and product codecs
  • Retain read-only until Task 8: scripts/check-test-evidence.ts, scripts/verify-browser-capability-evidence.ts, scripts/check-risk-coverage.ts, scripts/lib/risk-coverage.ts, scripts/lib/local-policy-evidence.ts, scripts/lib/manual-a11y-evidence.ts, scripts/verify-a11y-manual.ts
  • Create: scripts/run-legacy-assurance-probe.ts
  • Modify: package.json
  • Create: tests/unit/raw-product-evidence-contract.test.ts
  • Create: tests/unit/legacy-assurance-readonly.test.ts

Boundary: Product emitters may validate their own artifact schema and cross-fields, but the new manifests may not invoke local obligation satisfaction, waiver, quarantine, retry/flaky, coverage threshold, scenario completeness, browser matrix completeness, or evidence freshness logic. Legacy assessors remain callable only through run-legacy-assurance-probe.ts, which writes comparison output to a dedicated read-only shadow namespace and has no candidate/provider/promotion operation.

  • Add RED boundary tests proving raw emitters contain no verdict semantics, new manifests never invoke a legacy assessor, and every legacy assessor is reachable only from the comparison probe.
  • Run corepack pnpm exec vitest run tests/unit/raw-product-evidence-contract.test.ts tests/unit/legacy-assurance-readonly.test.ts; expected RED before the boundary is enforced.
  • Move any reusable false-green fixture to the Test Assurance platform implementation commit; in this repository keep only the product input fixture needed to reproduce the report.
  • Extract production-module inventory generation from check-risk-coverage.ts and raw manual-review codecs from manual-a11y-evidence.ts; keep threshold/completeness logic unchanged solely for the read-only probe until parity.
  • Update suite declarations to point directly at raw artifacts and ensure no automated workflow invokes the legacy probe.
  • Re-run corepack pnpm exec vitest run tests/unit/raw-product-evidence-contract.test.ts tests/unit/legacy-assurance-readonly.test.ts tests/unit/test-assurance-source-manifest.test.ts tests/unit/artifact-suite-contract.test.ts; expected PASS.
  • Commit:
git add scripts/run-http-scenario-evidence.ts scripts/lib/http-scenario-evidence.ts scripts/write-a11y-report.ts scripts/lib/manual-a11y-record.ts scripts/write-production-module-inventory.ts scripts/run-legacy-assurance-probe.ts package.json tests/unit/raw-product-evidence-contract.test.ts tests/unit/legacy-assurance-readonly.test.ts config/test-assurance
git commit -m "refactor(testing): isolate raw and legacy assurance paths"

Task 6: Run one-writer shadow parity

Files:

  • Create: docs/operations/platform-shadow-parity.md
  • Create: docs/operations/evidence/platform-shadow-readiness.json only from an actual platform run
  • Create: tests/unit/platform-shadow-contract.test.ts
  • Modify: delivery-platform.yaml and test-assurance.lock.json only to pin the released shadow versions

Parity identity: source revision, delivery manifest/catalog digests, test manifest/lock/policy digests, selected suite IDs, discovered/executed counts, terminal classifications, coverage production-module universe, HTTP declared/executed IDs, three browser results, candidate/member digests, source and artifact plan/evidence/assessment digests, supply-chain/provider digests, and promotion readiness. Exclude timestamp, duration, temp path, and runner identity.

  • Add RED tests proving there is no product-local central workflow, the platform is the only command allowed to build/freeze a candidate in shadow, legacy release/promotion commands are read-only probes, and no product script invokes a provider or mutates desired state.
  • Before shadow execution, query actual Gitea registration/status state and require: legacy quality-gates.yml registration disabled; legacy required status detached; central workflow installed externally with activation shadow; no product required-delivery-guard.yaml; legacy candidate/provider/promotion invocation count 0; platform candidate writer count exactly 1. Record actual workflow/status IDs and writer identity.
  • Run the released platform fixture against this exact source revision for a passing run and deliberate failures: zero discovery, missing report, retry-only pass, missing browser, changed candidate, wrong provider digest, and response loss.
  • Have the platform runner invoke run-legacy-assurance-probe.ts read-only and compare its test classifications with platform assessment. Do not register/run the legacy workflow and do not run legacy candidate creation, publication, or promotion.
  • Record the actual signed parity report digest and environment identities only after the run exists. If the required external environment is unavailable, leave this task incomplete and retain shadow activation.
  • Re-run focused contract tests; expected PASS for repository constraints even if P2 evidence remains blocked.
  • Commit the shadow contract and runbook before external evidence:
git add docs/operations/platform-shadow-parity.md tests/unit/platform-shadow-contract.test.ts delivery-platform.yaml test-assurance.lock.json
git commit -m "test(shadow): define parity and one-writer contract"
  • Only after the real run creates docs/operations/evidence/platform-shadow-readiness.json, verify its digest/signature and commit that file alone as test(shadow): record platform parity evidence. If the environment is unavailable, do not create or stage the file and leave Task 6 incomplete.

Task 7: Activate the platform and prove platform-only rollback

Files:

  • Modify: delivery-platform.yaml only to select the signed active catalog version
  • Modify: test-assurance.lock.json only through the verified testctl binary
  • Modify: docs/operations/release-cache-rollback.md
  • Modify: docs/operations/platform-shadow-parity.md
  • Create: tests/unit/platform-rollback-contract.test.ts
  • Create from a real drill only: docs/operations/evidence/platform-cutover-rollback.json

Cutover gate: all ten frontend test capabilities are R1 or higher; every selected CI/CD capability is P1/shadow or higher; source revision and manifest/catalog/lock digests match; the passing run and every named fault fixture have zero parity mismatch; legacy writer count is zero and platform writer count is one; named P2 Gitea/runner/scanner/signer/provider evidence exists; central status platform/delivery-pipeline is installed; the previous signed platform pin rollback drill verifies served-content digest; and the WIP ledger has zero unclassified hunks.

Rollback sequence: pause new promotions → reconcile every indeterminate operation ID → pin the previous signed platform catalog/version → verify and use the previous CICDCTL_BIN/TESTCTL_BIN digests → compile both manifests → promote the previous stable immutable subject through release-control → verify served-content digest → resume. No product workflow, legacy writer, rebuild, repackage, or mutable tag is permitted.

  • Add RED tests rejecting rollback text/code that restores quality-gates.yml, invokes ci:gate, enables a legacy writer, rebuilds a candidate, or omits signed catalog, executable, and subject digest checks.
  • Activate the externally installed central workflow/status only after every cutover-gate predicate is machine-verified; do not delete repository files in this task.
  • Run a staging rollback to the previous signed platform pin and previous immutable subject, then roll forward again. Record operation IDs, catalog/executable/release/served-content digests, Gitea status ID, writer identity, and reconciliation outcome.
  • Run corepack pnpm exec vitest run tests/unit/platform-shadow-contract.test.ts tests/unit/platform-rollback-contract.test.ts; expected PASS.
  • Commit runbook/test first. Commit platform-cutover-rollback.json separately only after a real signed drill exists; otherwise leave Task 7 incomplete.

Task 8: Remove local assurance and delivery engines after rollback evidence

Entry gate: Task 7 has a signed evidence digest and served-content equality; removing local engines is forbidden before it.

Files:

  • Delete: .gitea/workflows/quality-gates.yml

  • Delete: config/ci/gates.json

  • Delete: scripts/generate-ci-workflow.ts, scripts/check-ci-contract.ts, scripts/run-ci-gate.ts, scripts/contracts/ci-gates.ts

  • Delete: scripts/lib/ci-contract-report.ts, scripts/lib/ci-gate-log.ts, scripts/lib/ci-step-result.ts, scripts/lib/ci-artifact-validator.ts, scripts/lib/ci-candidate-archive-cli.ts, scripts/lib/ci-candidate-archive.ts, scripts/lib/package-script-graph.ts

  • Delete: scripts/check-test-evidence.ts, scripts/verify-browser-capability-evidence.ts, scripts/check-risk-coverage.ts, scripts/lib/risk-coverage.ts, scripts/lib/local-policy-evidence.ts, scripts/verify-a11y-manual.ts, scripts/run-legacy-assurance-probe.ts

  • Delete after raw codec extraction: scripts/lib/manual-a11y-evidence.ts

  • Delete: scripts/create-release-candidate.ts, scripts/verify-reproducible-build.ts, scripts/verify-ci-candidate-archive.ts, scripts/verify-release-candidate.ts, scripts/run-and-validate-provider.ts, scripts/stage-verified-promotion.ts, scripts/verify-provider-evidence.ts, scripts/verify-supply-chain-promotion.ts, scripts/lib/release-candidate.ts, scripts/lib/promotion-stager.ts, scripts/lib/promotion-verifier.ts, scripts/lib/provider-evidence.ts, scripts/lib/provider-upload-validator.ts

  • Delete: scripts/security-scan.ts, scripts/generate-supply-chain.ts, scripts/verify-supply-chain-artifacts.ts, scripts/verify-archived-local-evidence.ts, scripts/check-supply-chain-provider-fixtures.ts, scripts/lib/local-release-evidence.ts, scripts/lib/release-input-evidence.ts, scripts/lib/supply-chain.ts

  • Delete: tests/unit/ci-workflow-generation.test.ts, tests/unit/__snapshots__/ci-workflow-generation.test.ts.snap, tests/unit/ci-step-result.test.ts, and tests/fixtures/ci-contract/

  • Preserve/refactor: scripts/contracts/release-artifacts.ts, scripts/generate-build-manifest.ts, scripts/generate-artifact-schemas.ts, scripts/lib/build-manifest-outputs.ts, scripts/lib/release-runtime-coherence.ts, scripts/lib/manual-a11y-record.ts, and their product-schema tests

  • Modify: package.json

  • Modify: docs/operations/ci-quality-gates.md

  • Modify: docs/security/supply-chain.md

  • Create: tests/unit/platform-engine-removal.test.ts

  • Recompute original dirty-worktree blob/hunk digests and stop on drift. Compare the current migration diff to the exact allowed path/hunk set in the ledger before deleting anything.

  • Add a RED removal test that rejects workflow-DAG types, Gitea expressions, artifact upload/download orchestration, test normalizers/assessors, provider/promotion mutation, exact job counts, ci:gate, and workflow generator/checker scripts in product paths.

  • Extract the raw manual accessibility record codec to scripts/lib/manual-a11y-record.ts, then delete only the assessment/expiry-completeness engine. Delete all other listed platform-owned files hunk-by-hunk; preserve product behavior, assertions, fixtures, and raw artifact codecs.

  • Remove generate:ci-workflow, check:ci-workflow, ci:gate, local check:ci, legacy assessor, provider/promotion, supply-chain, and candidate orchestration scripts from package.json. Keep build, lint/typecheck, one-purpose suites, raw reporters, and developer-only commands.

  • Run corepack pnpm exec vitest run tests/unit/platform-engine-removal.test.ts tests/unit/delivery-platform-manifest.test.ts tests/unit/test-assurance-source-manifest.test.ts tests/unit/artifact-suite-contract.test.ts, then corepack pnpm check:types and corepack pnpm lint; expected PASS.

  • Verify git diff --name-status exactly matches the ledger's Task 8 allowlist. Stage only the explicit files listed in this task; never use git add scripts, git add tests, or git add -A.

  • Commit as refactor(platform): remove copied assurance and delivery engines.


Task 9: Finalize documentation, provenance, and consumer verification

Files:

  • Modify: docs/operations/release-cache-rollback.md

  • Modify: docs/operations/platform-shadow-parity.md

  • Modify: docs/security/supply-chain.md

  • Modify: README.md

  • Modify and close: docs/migration/task3-wip-provenance.json

  • Modify: docs/migration/task3-wip-disposition.md

  • Mark every WIP hunk retained, reimplemented-in-platform, removed-after-cutover, or preserved-in-original; require zero open disposition and reverify original dirty-worktree hashes.

  • Verify both binaries before invoking them:

printf '%s  %s\n' "$CICDCTL_DIGEST" "$CICDCTL_BIN" | sha256sum --check
printf '%s  %s\n' "$TESTCTL_DIGEST" "$TESTCTL_BIN" | sha256sum --check
  • Run final repository verification:
corepack pnpm install --frozen-lockfile
corepack pnpm check:types
corepack pnpm lint
corepack pnpm test:all
corepack pnpm exec vitest run tests/unit/delivery-platform-manifest.test.ts tests/unit/test-assurance-source-manifest.test.ts tests/unit/artifact-suite-contract.test.ts tests/unit/platform-engine-removal.test.ts tests/unit/platform-rollback-contract.test.ts
"$TESTCTL_BIN" validate --repository . --out artifacts/platform/final-validation.json
"$CICDCTL_BIN" manifest compile --manifest delivery-platform.yaml --source-revision "$PLATFORM_SOURCE_REVISION" --output artifacts/platform/effective-project.json
git diff --check

Expected: PASS. PLATFORM_SOURCE_REVISION is the exact 40-hex revision recorded by the platform run, not a branch or mutable lookup. Product tree contains manifests and product tests, not copied platform engines.

  • Commit the two migration ledger files and exact modified docs/README as docs(platform): finalize consumer cutover.

Cross-repository execution order

  1. Complete and release the Test Assurance plan through R1/v3 conformance.
  2. Complete and release the CI/CD plan through P1/shadow vertical conformance.
  3. Execute frontend Tasks 15 and validate both manifests locally.
  4. Execute Task 6 only with external one-writer state verified.
  5. Execute Task 7 only after every named P2 gate exists and prove rollback before deletion.
  6. Execute Tasks 89 only after signed rollback evidence. Until then, the correct state is shadow with legacy comparison code retained and no false active claim.