7.3 KiB
Portfolio release checklist
This checklist separates deterministic local evidence from changes that require Luca's explicit production authorization. A green local build is not permission to connect to a server, change DNS, deploy, or submit anything to a search engine.
Release inputs blocked on Luca
Do not create config/site.production.json and do not start production work until Luca supplies and approves all of the following:
- Canonical root HTTPS URL.
- Immutable production build ID.
- Target server and fixed release root/path.
- Deployment credentials through an external secret mechanism.
- Exact release activation approval after reviewing the signed digest and predecessor.
- Search Console account/property access and separate approval for submission.
config/site.production.json remains ignored. When authorized, it may contain exactly environment, canonicalUrl, and buildId; it must never contain credentials or private server paths.
Local, credentialless evidence
Run collection in a disposable, credentialless sandbox whose network access is limited to the configured package registry. The explicit network flag is an operator acknowledgement; it is intentionally not part of the normal verification command.
node scripts/supply-chain-check.mjs collect \
--project . \
--evidence /external/write-once/release-evidence/supply-chain \
--triage APPROVED_COMMITTED_MEDIUM_TRIAGE.json \
--execution-security SIGNED_EXECUTION_SECURITY_ENVELOPE.json \
--allow-registry-network yes
The collector runs npm ci --ignore-scripts, production and full development audits, the pinned license checker, and the pinned CycloneDX generator. It strips the environment to a minimal credential-free set. It also requires a separately signed execution-security envelope: all four privacy image roles must be digest-pinned with verified provenance and zero Critical/High findings; native tools must be integrity/signature verified and clean; repository secret/history scans, pinned CI actions, and distribution notices must all pass. The verifier checks that envelope against the fixed protected authority checkpoint described below. Until Luca supplies and approves that protected authority and the signed evidence, the supply-chain gate intentionally fails closed.
The verifier reads the fixed protected authority checkpoint at /etc/portfolio-release-authority/.control: execution-trust.json and the exact-JSON supply-chain-authority.json binding whose SHA-256 digest covers the trust-policy bytes. The authority root and control directory must be real, activation-service-owned, and not group/world writable. Verification uses system time and independently resolves Git HEAD; the signed repository commit must match that current HEAD exactly. It fails when package metadata or the lockfile changes, evidence digests do not match, a license is not allowlisted, an SBOM is malformed, or a Critical/High finding exists. Every Medium finding must have one current, exact, committed triage entry; stale extras also fail.
npm run verify:supply-chainpasses against the selected immutable evidence directory.npm auditevidence covers production dependencies and the complete development tree.- Critical findings: 0. High findings: 0.
- Every Medium finding has a current committed owner, rationale, and review date.
- CycloneDX SBOM is bound by the evidence manifest and packaged with the release.
- License inventory contains no unknown, copyleft, or unapproved expression.
- Fixed protected authority checkpoint and signed current-
HEADcommit binding pass. - Signed execution image/native-tool evidence is current, complete, digest-pinned, and has zero Critical/High findings.
- Repository secret/history, CI action pinning, and distribution notice checks pass.
npm run build:previewpasses.- Complete production build, unit/browser/accessibility/performance gates pass using the approved production config.
- Privacy reconciliation and signed-release admission pass against external trust state.
- Deterministic release package extracts and verifies in a temporary root.
- Local Nginx config check, security headers, MIME, compression, and byte range checks pass.
- No source maps, original/private assets, private product names, credentials, scanner payloads, or private server paths appear in the release closure.
Record for Luca's release checkpoint:
- Signed manifest digest:
- Immutable release/build ID:
- Package SHA-256 and byte size:
- Approval/provenance root:
- Supply-chain evidence digest:
- Privacy evidence digest:
- Manifest expiry:
- Expected current predecessor digest and fence:
- Planned canonical host:
- Planned target release root (share privately, not in Git):
- Exact prepare and activation commands:
- Exact signed rollback target/command:
- Local verification summary:
Explicit remote authorization checkpoint
- Luca reviewed the values above and explicitly authorized this exact signed release.
- The authorization has not expired and still names the current predecessor/fence.
Without both checks, stop. Do not connect to the server.
Authorized staging and activation
- Transfer only the immutable verified package to the approved target.
- Run server-side preparation; confirm it changes no
currentpointer. - Verify the readiness receipt digest, expiry, predecessor, and expected fence.
- Activate with the fenced atomic pointer switch.
- Preserve the previous immutable release and receipt for rollback.
- Run the public smoke command with the approved canonical URL, alternate hosts, and signed manifest digest:
npm run smoke:production -- \
--canonical-url https://APPROVED-HOST/ \
--manifest-digest LOWERCASE_SHA256 \
--alternate-url http://APPROVED-ALTERNATE/
Add --video-path /assets/APPROVED-HASHED.webm when the deployed public closure contains video. A deployed response must expose the signed digest through X-Portfolio-Manifest-Digest. The smoke gate checks the canonical 200 response, one-hop 308 redirects, security/cache/compression/MIME/range behavior, canonical/OG/JSON-LD/robots/sitemap agreement, substantive server-rendered content without JavaScript, and absence of source maps/private product identifiers.
- Public smoke report digest equals the locally approved signed manifest digest.
- If any activation or public smoke check fails, stop traffic changes and follow the signed rollback procedure.
Post-launch SEO (separate external action)
- Confirm the canonical page and sitemap are publicly indexable and alternate hosts still redirect in one hop.
- After Luca authorizes Search Console access, add/verify the exact canonical property.
- Submit the exact canonical sitemap and request indexing for the canonical home page.
- Record the property, sitemap URL, submission timestamp, operator, and result outside secrets.
- Monitor branded-name indexing and crawl issues. Do not promise a ranking position; SEO gates establish correctness and discoverability, not ranking guarantees.
Completion record
Phase 4 is remotely complete only when the deployed digest equals the locally approved signed digest, public smoke checks pass, the previous release remains recoverable, the Search Console action is recorded, and no private source, private identifier, or credential entered the public closure.