# Build and supply-chain gate ## Local blocking controls - `pnpm install --frozen-lockfile` and a real manifest/lock mismatch fixture - all direct and transitive lockfile rows with package SHA-512 integrity - production/development, direct/transitive and platform-optional classification - package-manifest license allow/deny policy - approved inventory baseline digest and actual add/remove/change/upgrade diff - independent review for new direct production dependencies - CycloneDX 1.6 SBOM and inventory component/edge coherence - source/lock/SBOM/dist-linked local provenance statement - source, opt-in recipes, scripts, tests, tracked config/schema, public, built asset and generated release metadata secret scan - two-build `SOURCE_DATE_EPOCH` reproducibility check The canonical commands are: ```bash corepack pnpm verify:lockfile corepack pnpm verify:reproducible-build corepack pnpm build:release-candidate corepack pnpm verify:local-evidence corepack pnpm check:supply-chain:fixtures ``` `config/security/dependency-baseline.json` is the approved local baseline. Changing it requires `DEPENDENCY_BASELINE_OWNER` and `DEPENDENCY_BASELINE_REASON`; editing the digest or hardcoding an empty diff is rejected. ## External promotion controls Promotion reads the provider files named by `VULNERABILITY_REPORT_PATH` and `PROVENANCE_ATTESTATION_PATH`. The vulnerability report must bind both the exact lockfile digest and candidate `distSha256`; the provenance attestation must name `dist` with that same digest. Both documents use strict schemas and Ed25519 signatures verified with separately configured trusted public keys and key IDs (`VULNERABILITY_PUBLIC_KEY_PATH`, `VULNERABILITY_KEY_ID`, `PROVENANCE_PUBLIC_KEY_PATH`, and `PROVENANCE_KEY_ID`). Keys of another curve, including Ed448, are rejected even if a document labels its algorithm `Ed25519`. `immutable_build` archives the raw `pnpm-lock.yaml`, `dist` (including hidden `.vite` files), the build manifest, module inventory, release verification, secret-scan result, and local supply-chain evidence once. The candidate manifest hashes the raw lockfile bytes and requires that digest to equal the dependency inventory's `lockfileSha256`. The two provider jobs download this same archive separately and receive `CANDIDATE_LOCKFILE_PATH` and `CANDIDATE_DIST_SHA256`; configured `VULNERABILITY_PROVIDER_COMMAND` and `PROVENANCE_PROVIDER_COMMAND` must emit the signed reports. If either provider input is absent, local verification remains meaningful but `artifacts/security/supply-chain-verification.json` records `promotionStatus: FAIL_UNVERIFIED`. `verify:provider-evidence` and `verify:promotion` then exit non-zero. Promotion recomputes the candidate file set and digests, then read-only revalidates the archived executable schemas, raw lockfile, module inventory, build outputs, release coherence, SBOM, provenance, security scan and supply-chain coherence. It never rebuilds or rewrites candidate evidence. Scanner or signing outages are not converted to an empty PASS. Approved vulnerability exceptions require vulnerability/package identity, owner, a different reviewer, reason and expiry. Expired or self-approved exceptions are blocking.