@kungfu-tech/buildchain 3.0.9-alpha.9 → 4.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +39 -0
- package/README.md +17 -13
- package/actions/promote-buildchain-ref/README.md +0 -10
- package/actions/release-tail/README.md +6 -10
- package/architecture/internal-capabilities.json +502 -0
- package/architecture/maintainability-baseline.json +59 -0
- package/architecture/maintainability-policy.json +1384 -0
- package/architecture/release-tail-contract-inventory.json +587 -0
- package/architecture/v3-core-mechanism-inventory.json +1043 -0
- package/architecture/v3-core-mechanism-inventory.md +67 -0
- package/architecture/v4-adopter-delivery-parity.json +47 -0
- package/architecture/v4-architecture-constitution.md +210 -0
- package/architecture/v4-bootstrap-authority.json +56 -0
- package/architecture/v4-canonical-contract-fixtures.json +105 -0
- package/architecture/v4-capability-state-machine-manifest.json +480 -0
- package/architecture/v4-capability-state-machine-manifest.schema.json +202 -0
- package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.json +830 -0
- package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.md +223 -0
- package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.schema.json +318 -0
- package/architecture/v4-delivery-warrant-shadow-fixtures.json +227 -0
- package/architecture/v4-delivery-warrant-shadow-fixtures.schema.json +67 -0
- package/architecture/v4-exception-ledger.json +5 -0
- package/architecture/v4-exception-ledger.schema.json +56 -0
- package/architecture/v4-partial-mutation-recovery-qualification.json +65 -0
- package/architecture/v4-platform-stage-checkpoints.json +97 -0
- package/architecture/v4-provider-operation-journal-contract.json +113 -0
- package/architecture/v4-release-activation-shadow-domain.json +61 -0
- package/architecture/v4-release-train-parity.json +68 -0
- package/architecture/v4-rust-libnode-bridge-evaluation.json +107 -0
- package/architecture/v4-rust-libnode-bridge-spike.md +85 -0
- package/architecture/v4-stable-publication-fence.json +66 -0
- package/architecture/v4-stage-capsule-contract.json +90 -0
- package/architecture/v4-stage-capsule-qualification.json +99 -0
- package/architecture/v4-stage-capsule-resume-planner.json +52 -0
- package/architecture/v4-stage-capsule-store-contract.json +72 -0
- package/bin/buildchain.mjs +15 -10
- package/contracts/auditable-demo-scenario-v1.schema.json +1 -1
- package/contracts/buildchain-v2-residuals-v1.json +2 -2
- package/contracts/fixtures/v4-delivery-warrant-trace-v1/golden.json +158 -0
- package/contracts/fixtures/v4-delivery-warrant-trace-v1/property.json +380 -0
- package/contracts/fixtures/v4-delivery-warrant-trace-v1/replay.json +163 -0
- package/contracts/fixtures/v4-partial-mutation-recovery-v1/shared.json +155 -0
- package/contracts/fixtures/v4-provider-operation-journal-v1/shared.json +457 -0
- package/contracts/fixtures/v4-provider-readback-idempotency-v1/shared.json +682 -0
- package/contracts/fixtures/v4-release-activation-shadow-v1/shared.json +53 -0
- package/contracts/fixtures/v4-stable-publication-fence-v1/shared.json +56 -0
- package/contracts/fixtures/v4-stage-capsule-resume-v1/late-platform-failure.json +176 -0
- package/contracts/fixtures/v4-stage-capsule-store-v1/shared.json +132 -0
- package/contracts/fixtures/v4-stage-capsule-v1/shared.json +111 -0
- package/contracts/v4-canonical-contracts-v1.schema.json +182 -0
- package/contracts/v4-delivery-warrant-semantic-diff-report-v1.schema.json +284 -0
- package/contracts/v4-delivery-warrant-trace-v1.schema.json +215 -0
- package/contracts/v4-host-contract-v1.schema.json +135 -0
- package/contracts/v4-partial-mutation-recovery-v1.schema.json +168 -0
- package/contracts/v4-provider-operation-journal-v1.schema.json +381 -0
- package/contracts/v4-release-activation-shadow-v1.schema.json +186 -0
- package/contracts/v4-stable-publication-fence-v1.schema.json +125 -0
- package/contracts/v4-stage-capsule-resume-v1.schema.json +225 -0
- package/contracts/v4-stage-capsule-store-v1.schema.json +154 -0
- package/contracts/v4-stage-capsule-v1.schema.json +178 -0
- package/crates/buildchain-v4-bridge/Cargo.lock +213 -0
- package/crates/buildchain-v4-bridge/Cargo.toml +12 -0
- package/crates/buildchain-v4-bridge/src/main.rs +495 -0
- package/dist/site/agent-index.json +0 -4
- package/dist/site/artifact-schemas.json +0 -8
- package/dist/site/buildchain-contract.json +103 -397
- package/dist/site/buildchain-site.json +302 -386
- package/dist/site/capability-registry.json +9 -11
- package/dist/site/cli-registry.json +8 -53
- package/dist/site/controller-registry.json +48 -8
- package/dist/site/kfd-claims.json +129 -167
- package/dist/site/kfd-upstream-aggregate.json +9 -9
- package/dist/site/manual-registry.json +18 -49
- package/dist/site/node-api-registry.json +4345 -7345
- package/dist/site/page-registry.json +278 -346
- package/dist/site/public-surface-audit.json +85 -404
- package/dist/site/publication-authority-registry.json +11 -1
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +3 -9
- package/dist/site/schemas/kfd-support-projection-v1.schema.json +106 -0
- package/dist/site/site-manifest.json +22 -38
- package/dist/site/workflow-registry.json +78 -35
- package/docs/MAP.md +8 -5
- package/docs/auditable-demo.md +2 -2
- package/docs/aws-us-elastic-runner-burst-plane.md +7 -59
- package/docs/cli-reference.md +15 -213
- package/docs/cli.md +14 -14
- package/docs/dev-alpha-candidate-patrol.md +3 -11
- package/docs/dev-delivery-warrant.md +29 -194
- package/docs/engineering-housekeeper.md +12 -4
- package/docs/getting-started.md +1 -1
- package/docs/install.md +5 -5
- package/docs/kfd-support.md +2 -7
- package/docs/lifecycle-protocol.md +2 -4
- package/docs/node-api-reference.md +414 -554
- package/docs/release-flow.md +31 -31
- package/docs/release-governance.md +16 -28
- package/docs/release-passport.md +2 -15
- package/docs/release-tail-contract.md +13 -6
- package/docs/release-tail-provider-plane.md +13 -19
- package/docs/release-train.md +4 -4
- package/docs/reusable-build-surface.md +14 -27
- package/docs/site-bundle-contract.md +1 -5
- package/docs/stable-candidate-patrol.md +7 -7
- package/docs/v4-canonical-contracts.md +92 -0
- package/docs/v4-delivery-warrant-read-candidate.md +73 -0
- package/docs/v4-delivery-warrant-semantic-diff.md +75 -0
- package/docs/v4-production-release.md +63 -0
- package/docs/v4-stage-capsule.md +193 -0
- package/docs/versioning.md +3 -5
- package/package.json +19 -19
- package/packages/core/adopter-delivery-gate.js +576 -0
- package/packages/core/adopter-delivery-json.js +66 -0
- package/packages/core/artifact-signing.js +0 -61
- package/packages/core/artifact-verification-envelope.js +5 -5
- package/packages/core/build-facts.js +12 -4
- package/packages/core/buildchain-agent-manuals.js +0 -2
- package/packages/core/buildchain-channel-identity.js +3 -2
- package/packages/core/buildchain-config.js +4 -69
- package/packages/core/buildchain-contract.js +232 -46
- package/packages/core/buildchain-kfd-claims.js +1 -1
- package/packages/core/channel-candidate.js +0 -8
- package/packages/core/channel-promotion-baseline.js +0 -52
- package/packages/core/controller-evidence.js +3 -4
- package/packages/core/dev-alpha-candidate-selection.js +2 -10
- package/packages/core/dev-delivery-warrant-cancellation.js +0 -1
- package/packages/core/dev-delivery-warrant-settlement.js +20 -67
- package/packages/core/dev-delivery-warrant.js +50 -138
- package/packages/core/diagnostics.js +3 -8
- package/packages/core/github-governance-authority.js +3 -1
- package/packages/core/kfd-adopter-category-driver.js +167 -0
- package/packages/core/kfd-adopter-manifest.js +47 -46
- package/packages/core/kfd-gate.js +15 -45
- package/packages/core/paper-agent-entry.js +7 -16
- package/packages/core/paper-fleet.js +2 -2
- package/packages/core/paper-repository.js +2 -3
- package/packages/core/paper-scaffold-content.js +2 -23
- package/packages/core/paper.js +11 -43
- package/packages/core/publication-reproducibility.js +4 -4
- package/packages/core/release-line-bootstrap.js +21 -8
- package/packages/core/release-passport-contract.js +5 -5
- package/packages/core/release-passport.js +20 -131
- package/packages/core/self-dogfood-version.js +48 -35
- package/packages/core/spawn-command.js +232 -8
- package/packages/core/v4-adopter-delivery-parity.js +219 -0
- package/packages/core/v4-canonical-contracts.js +284 -0
- package/packages/core/v4-delivery-warrant-fixture-runner.js +371 -0
- package/packages/core/v4-delivery-warrant-read-candidate.js +279 -0
- package/packages/core/v4-delivery-warrant-semantic-diff-gate.js +352 -0
- package/packages/core/v4-delivery-warrant-shadow-adapter.js +447 -0
- package/packages/core/v4-partial-mutation-recovery-qualification.js +395 -0
- package/packages/core/v4-platform-stage-checkpoints.js +471 -0
- package/packages/core/v4-provider-operation-journal.js +531 -0
- package/packages/core/v4-provider-readback-idempotency.js +394 -0
- package/packages/core/v4-release-activation-shadow.js +519 -0
- package/packages/core/v4-stable-publication-fence.js +357 -0
- package/packages/core/v4-stage-capsule-local-store.js +426 -0
- package/packages/core/v4-stage-capsule-qualification-campaign.js +512 -0
- package/packages/core/v4-stage-capsule-qualification.js +456 -0
- package/packages/core/v4-stage-capsule-resume-planner.js +397 -0
- package/packages/core/v4-stage-capsule-store.js +401 -0
- package/packages/core/v4-stage-capsule.js +319 -0
- package/scripts/assemble-self-publication-admission.mjs +1 -1
- package/scripts/audit-publication-control-plane.mjs +5 -5
- package/scripts/auditable-demo-bundle-verification.mjs +3 -2
- package/scripts/auditable-demo-platform.mjs +2 -2
- package/scripts/auditable-demo-renditions.mjs +1 -1
- package/scripts/auditable-demo.mjs +2 -2
- package/scripts/aws-macos-jit-controller-core.mjs +13 -346
- package/scripts/aws-macos-jit-controller-runtime.mjs +2 -210
- package/scripts/aws-macos-jit-controller.mjs +37 -275
- package/scripts/aws-macos-jit-core.mjs +3 -41
- package/scripts/aws-macos-jit.mjs +0 -12
- package/scripts/aws-windows-jit-campaign.mjs +2 -2
- package/scripts/aws-windows-jit-controller-core.mjs +1 -1
- package/scripts/aws-windows-jit-controller.mjs +3 -3
- package/scripts/build-contract-core.mjs +3 -8
- package/scripts/build-standalone-binary.mjs +3 -14
- package/scripts/buildchain-channel-router.mjs +4 -0
- package/scripts/buildchain-cli-help.mjs +7 -16
- package/scripts/buildchain-contract-lock.mjs +0 -6
- package/scripts/check-action-bundles.mjs +3 -4
- package/scripts/check-internal-architecture.mjs +7 -6
- package/scripts/check-inventory.mjs +30 -25
- package/scripts/check-v4-public-dogfood-contract.mjs +270 -0
- package/scripts/create-release-bundle.mjs +8 -4
- package/scripts/dev-alpha-candidate-patrol.mjs +1 -22
- package/scripts/dev-delivery-proof.mjs +2 -64
- package/scripts/dev-delivery-warrant.mjs +61 -86
- package/scripts/dev-pr-auto-merge.mjs +4 -30
- package/scripts/dev-pr-delivery-warrant.mjs +0 -55
- package/scripts/dispatch-artifact-signing-authority.mjs +7 -4
- package/scripts/generate-buildchain-kfd-witnesses.mjs +94 -88
- package/scripts/generate-channel-build-workflow.mjs +54 -24
- package/scripts/generate-channel-promotion-workflow.mjs +15 -6
- package/scripts/generate-site-bundle.mjs +8 -27
- package/scripts/git-fetch-process-tree.mjs +34 -1
- package/scripts/init-repo.mjs +64 -159
- package/scripts/inspect-artifact-signing-requests.mjs +0 -6
- package/scripts/locked-source-checkout.mjs +3 -4
- package/scripts/maintainability-metrics.mjs +8 -2
- package/scripts/npm-publish-dry-run.mjs +2 -2
- package/scripts/npm-publish-transaction.mjs +2 -2
- package/scripts/publication-commit-evidence.mjs +23 -69
- package/scripts/release-candidate-resolver.mjs +11 -17
- package/scripts/release-tail.mjs +3 -49
- package/scripts/resume-from-candidate-run.mjs +9 -123
- package/scripts/run-lifecycle-core.mjs +12 -13
- package/scripts/seal-artifact-signing-requests.mjs +17 -21
- package/scripts/site-capability-metadata.mjs +3 -20
- package/scripts/stable-candidate-qualification.mjs +10 -10
- package/scripts/v4-architecture.mjs +12 -2
- package/scripts/v4-bridge-bootstrap.mjs +141 -0
- package/scripts/v4-bridge-evidence.mjs +141 -0
- package/scripts/v4-host-adapter.mjs +182 -0
- package/scripts/v4-platform-stage-checkpoint-rehearsal.mjs +207 -0
- package/scripts/v4-stage-capsule-qualification.mjs +528 -0
- package/scripts/v4-stage-capsule-resume-rehearsal.mjs +57 -0
- package/scripts/v4-warrant-shadow-plan.mjs +601 -0
- package/scripts/verify-golden-path.mjs +5 -5
- package/scripts/web-surface-cloudfront-rewrite.mjs +15 -15
- package/scripts/web-surface-core.mjs +2 -8
- package/scripts/workflow-call-contract.mjs +5 -184
- package/contracts/dev-delivery-authority-v2.schema.json +0 -253
- package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-perspective.json +0 -16
- package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-replay.json +0 -57
- package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +0 -47
- package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +0 -47
- package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +0 -40
- package/contracts/next-development-request-v1.schema.json +0 -66
- package/contracts/next-development-transition-v1.schema.json +0 -292
- package/contracts/publication-rehearsal-capsule-v1.schema.json +0 -173
- package/dist/site/schemas/dev-delivery-authority-v2.schema.json +0 -442
- package/dist/site/schemas/publication-rehearsal-capsule-v1.schema.json +0 -269
- package/dist/site/schemas/release-tail-capabilities-v1.schema.json +0 -353
- package/dist/site/schemas/release-tail-provider-bindings-v1.schema.json +0 -94
- package/docs/dev-delivery-qualification-landing-adr.md +0 -137
- package/docs/next-development-transition.md +0 -119
- package/docs/publication-rehearsal.md +0 -94
- package/packages/core/buildchain-compatibility-proof.js +0 -631
- package/packages/core/dev-delivery-authority.js +0 -996
- package/packages/core/dev-delivery-native-proof.js +0 -418
- package/packages/core/dev-delivery-warrant-shadow.js +0 -502
- package/packages/core/next-development-candidate-reservation.js +0 -186
- package/packages/core/next-development-controller.js +0 -726
- package/packages/core/next-development-projection.js +0 -288
- package/packages/core/next-development-transition.js +0 -738
- package/packages/core/publication-rehearsal-projection.js +0 -173
- package/packages/core/publication-rehearsal-runtime.js +0 -921
- package/scripts/aws-macos-jit-instance-rehydrate.mjs +0 -260
- package/scripts/aws-macos-jit-source-rebind.mjs +0 -724
- package/scripts/dev-delivery-authority.mjs +0 -368
- package/scripts/dev-delivery-native-run.mjs +0 -235
- package/scripts/dev-delivery-two-phase-resume.mjs +0 -90
- package/scripts/dev-delivery-two-phase.mjs +0 -577
- package/scripts/generate-next-development-guidance.mjs +0 -49
- package/scripts/materialize-self-release-candidate-version.mjs +0 -137
- package/scripts/next-development-self-dogfood-harness.mjs +0 -409
- package/scripts/next-development-self-dogfood.mjs +0 -532
- package/scripts/next-development-transition.mjs +0 -47
- package/scripts/release-candidate-tail-reseal.mjs +0 -426
- package/templates/native-dev-delivery.yml +0 -86
|
@@ -24,6 +24,7 @@ export const BUILDCHAIN_USAGE = `Usage:
|
|
|
24
24
|
[--require-lifecycle-stages <comma-list>]
|
|
25
25
|
buildchain lifecycle run <stage> [--cwd <dir>] [--required]
|
|
26
26
|
[--artifact-name <name>] [--artifact-path <path>]...
|
|
27
|
+
[--platform-id <id>] [--platform-name <name>]
|
|
27
28
|
[--manifest-path <path>] [--summary-path <path>]
|
|
28
29
|
[--process-summary <json>]
|
|
29
30
|
buildchain npm dry-run [--cwd <dir>] [--expected-tag <tag>] [--registry <url>]
|
|
@@ -43,9 +44,6 @@ export const BUILDCHAIN_USAGE = `Usage:
|
|
|
43
44
|
buildchain release-tail init --declaration <json-or-path> [--state <path>]
|
|
44
45
|
buildchain release-tail <status|verify> [--state <path>] [--output <path>]
|
|
45
46
|
buildchain release-tail compat --hooks-json <json-or-path> [--output <path>]
|
|
46
|
-
buildchain release-tail rehearse --capsule <path> --capsule-root <absolute-path>
|
|
47
|
-
--mode <simulate|replay> --state <path>
|
|
48
|
-
--evidence <path> [--environment-json <json-or-path>]
|
|
49
47
|
buildchain github-governance <plan|apply|rollback|protection-policy-plan|ruleset-policy-plan> ...
|
|
50
48
|
buildchain release <inspect|recover|finalize|abort> ...
|
|
51
49
|
buildchain transaction inspect ...
|
|
@@ -129,18 +127,11 @@ export const BUILDCHAIN_USAGE = `Usage:
|
|
|
129
127
|
[--from-config | --workflow <required-workflow.yml>...] [--cwd <dir>]
|
|
130
128
|
[--check-response-timeout-minutes <n>]
|
|
131
129
|
[--max-entries-to-build <n>] [--apply]
|
|
132
|
-
buildchain dev warrant <submit|select|heartbeat|
|
|
130
|
+
buildchain dev warrant <submit|select|heartbeat|recover|close|cancel-queued|observe>
|
|
133
131
|
--repository <owner/repo> --branch <dev/vN/vN.M>
|
|
134
132
|
[--execute] [--output <file>] [--json]
|
|
135
|
-
buildchain dev
|
|
136
|
-
--repository <owner/repo> --branch <dev/vN/vN.M>
|
|
137
|
-
[--execute] [--output <file>] [--json]
|
|
138
|
-
buildchain dev proof <source|verify-source|classify|native|verify-native|classify-native|verify-native-reuse|replay|integration|verify-integration>
|
|
133
|
+
buildchain dev proof <source|verify-source|classify|replay|integration|verify-integration>
|
|
139
134
|
[--output <file>] [--json]
|
|
140
|
-
buildchain dev two-phase --repository <owner/repo> --branch <dev/vN/vN.M>
|
|
141
|
-
--pull-request <n> --expected-head <sha>
|
|
142
|
-
--warrant-result <file> [--native-proof <file>]
|
|
143
|
-
[--native-command <command>]
|
|
144
135
|
buildchain log <info|warn|error> --event <name> [--phase <phase>]
|
|
145
136
|
[--component <name>] [--source <name>] [--attribute key=value]...
|
|
146
137
|
[--path <jsonl>] [--json]
|
|
@@ -251,15 +242,15 @@ Examples:
|
|
|
251
242
|
buildchain validate --require-version-state --require-lifecycle-stages build,verify
|
|
252
243
|
buildchain lifecycle run build --artifact-path dist --artifact-name "{repo}-{version}-{platform}"
|
|
253
244
|
buildchain npm dry-run --json
|
|
254
|
-
buildchain release --dry-run --target-ref alpha/
|
|
255
|
-
buildchain release line open --major
|
|
245
|
+
buildchain release --dry-run --target-ref alpha/v4/v4.0
|
|
246
|
+
buildchain release line open --major 4 --minor 1 --source-ref release/v4/v4.0 --json
|
|
256
247
|
buildchain span --event native.build -- cmake --build build
|
|
257
|
-
buildchain collect github-release --tag
|
|
248
|
+
buildchain collect github-release --tag v4.0.0 --assets-dir dist --output-dir .buildchain/release-passport
|
|
258
249
|
buildchain create publication-admission --input-json admission-input.json --output admission.json
|
|
259
250
|
buildchain create runner-provenance --input-json runner-input.json --output runner.json
|
|
260
251
|
buildchain verify release-passport .buildchain/release-passport/buildchain.release.json
|
|
261
252
|
buildchain verify publication-admission admission.json --registry-json publication-authority-registry.json --runner-json runner.json --control-plane-audit-json control-plane.json --expected-json expected.json --json
|
|
262
|
-
buildchain audit publication-control-plane --repository kungfu-systems/buildchain --branch release/
|
|
253
|
+
buildchain audit publication-control-plane --repository kungfu-systems/buildchain --branch release/v4/v4.0
|
|
263
254
|
buildchain verify artifact ./dist/buildchain-x86_64-unknown-linux-gnu.tar.gz --passport .buildchain/release-passport/buildchain.release.json
|
|
264
255
|
buildchain verify artifact-envelope .buildchain/kfx/artifact-verification-envelope.json --json
|
|
265
256
|
buildchain project kfx-admission .buildchain/kfx/artifact-verification-envelope.json --json
|
|
@@ -116,9 +116,6 @@ export function checkBuildchainContractLock({
|
|
|
116
116
|
evaluation.channelBinding ? `- Bound channel: \`${evaluation.channelBinding.channel || "(unknown)"}\`` : "",
|
|
117
117
|
`- Contract digest: \`${current.contractDigest}\``,
|
|
118
118
|
`- Compatibility digest: \`${current.compatibilityDigest}\``,
|
|
119
|
-
`- Compatibility proof registry: \`${current.compatibilityProofRegistryRoot || "(legacy)"}\``,
|
|
120
|
-
`- Verification receipt: \`${evaluation.receiptRoot || "(not-required)"}\``,
|
|
121
|
-
evaluation.usedProofRoots?.length ? `- Used compatibility proofs: ${evaluation.usedProofRoots.map((root) => `\`${root}\``).join(", ")}` : "",
|
|
122
119
|
evaluation.reasons?.length ? `- Reasons: ${evaluation.reasons.join("; ")}` : "",
|
|
123
120
|
shouldIssue ? `- Drift issue body: \`${issueBodyPath}\`` : "",
|
|
124
121
|
].filter(Boolean).join("\n"));
|
|
@@ -130,9 +127,6 @@ export function checkBuildchainContractLock({
|
|
|
130
127
|
"contract-lock-issue-body-file": shouldIssue ? issueBodyPath : "",
|
|
131
128
|
"contract-digest": current.contractDigest,
|
|
132
129
|
"contract-compatibility-digest": current.compatibilityDigest,
|
|
133
|
-
"contract-compatibility-proof-registry-root": current.compatibilityProofRegistryRoot || "",
|
|
134
|
-
"contract-compatibility-verification-receipt-root": evaluation.receiptRoot || "",
|
|
135
|
-
"contract-compatibility-proof-roots": (evaluation.usedProofRoots || []).join(","),
|
|
136
130
|
"accepted-contract-digest": evaluation.accepted?.contractDigest || "",
|
|
137
131
|
"accepted-buildchain-sha": evaluation.accepted?.resolvedSha || "",
|
|
138
132
|
"current-buildchain-sha": runtimeSha || "",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
-
import { spawnSync } from "node:child_process";
|
|
3
2
|
import path from "node:path";
|
|
4
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { spawnSyncCommand } from "../packages/core/spawn-command.js";
|
|
5
5
|
|
|
6
6
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
7
7
|
const actionsRoot = path.join(root, "actions");
|
|
@@ -21,9 +21,8 @@ const bundlePaths = readdirSync(actionsRoot, { withFileTypes: true })
|
|
|
21
21
|
const before = new Map(
|
|
22
22
|
bundlePaths.map((bundlePath) => [bundlePath, readFileSync(bundlePath)]),
|
|
23
23
|
);
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
pnpm,
|
|
24
|
+
const build = spawnSyncCommand(
|
|
25
|
+
"pnpm",
|
|
27
26
|
["-r", "--filter", "./actions/**", "build"],
|
|
28
27
|
{ cwd: root, stdio: "inherit" },
|
|
29
28
|
);
|
|
@@ -5,7 +5,8 @@ import path from "node:path";
|
|
|
5
5
|
import { execFileSync } from "node:child_process";
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
7
7
|
|
|
8
|
-
const implementationExtensions = new Set([".js", ".mjs", ".cjs", ".sh"]);
|
|
8
|
+
const implementationExtensions = new Set([".js", ".mjs", ".cjs", ".rs", ".sh"]);
|
|
9
|
+
const repositorySourceExtensions = new Set([".js", ".mjs", ".cjs", ".rs"]);
|
|
9
10
|
const importPattern =
|
|
10
11
|
/(?:\bimport\s*(?:\([^)]*?\)|[^"'\n]*?\s+from\s+)?|\bexport\s+[^"'\n]*?\s+from\s+)(["'])([^"'\n]+)\1/g;
|
|
11
12
|
|
|
@@ -116,7 +117,7 @@ function assertIndexShape(index) {
|
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
|
|
119
|
-
function
|
|
120
|
+
function repositorySourceFiles(root) {
|
|
120
121
|
return execFileSync(
|
|
121
122
|
"git",
|
|
122
123
|
["ls-files", "-z", "--cached", "--others", "--exclude-standard"],
|
|
@@ -128,10 +129,10 @@ function repositoryJavaScriptFiles(root) {
|
|
|
128
129
|
.split("\0")
|
|
129
130
|
.filter(Boolean)
|
|
130
131
|
.filter((file) => fs.existsSync(path.resolve(root, file)))
|
|
131
|
-
.filter((file) =>
|
|
132
|
+
.filter((file) => repositorySourceExtensions.has(path.extname(file)))
|
|
133
|
+
.filter((file) => !file.startsWith(".tmp-"))
|
|
132
134
|
.filter((file) => !file.startsWith("tests/"))
|
|
133
135
|
.filter((file) => !/(?:^|\/)tests?\//u.test(file))
|
|
134
|
-
.filter((file) => !file.startsWith(".buildchain/"))
|
|
135
136
|
.filter((file) => !/^actions\/[^/]+\/dist\//u.test(file))
|
|
136
137
|
.sort();
|
|
137
138
|
}
|
|
@@ -307,7 +308,7 @@ function checkInternalArchitecture({
|
|
|
307
308
|
} = {}) {
|
|
308
309
|
assertIndexShape(index);
|
|
309
310
|
const issues = [];
|
|
310
|
-
const repositorySources =
|
|
311
|
+
const repositorySources = repositorySourceFiles(root);
|
|
311
312
|
const ownership = evaluateSourceOwnership(index, repositorySources);
|
|
312
313
|
const capabilities = evaluateCapabilities(root, index);
|
|
313
314
|
issues.push(...ownership.issues, ...capabilities.issues);
|
|
@@ -361,5 +362,5 @@ export {
|
|
|
361
362
|
checkInternalArchitecture,
|
|
362
363
|
dependencyCycles,
|
|
363
364
|
relativeImports,
|
|
364
|
-
|
|
365
|
+
repositorySourceFiles,
|
|
365
366
|
};
|
|
@@ -8,6 +8,7 @@ import { evaluateBuildchainContractLock } from "../packages/core/buildchain-cont
|
|
|
8
8
|
import {
|
|
9
9
|
canAdmitSelfDogfoodLockEvaluation,
|
|
10
10
|
contractForSelfDogfoodEvaluation,
|
|
11
|
+
hasQualifiedSelfDogfoodBootstrapAuthority,
|
|
11
12
|
resolveSelfDogfoodMajor,
|
|
12
13
|
} from "../packages/core/self-dogfood-version.js";
|
|
13
14
|
import { generateChannelBuildWorkflow } from "./generate-channel-build-workflow.mjs";
|
|
@@ -53,10 +54,6 @@ const requiredPaths = [
|
|
|
53
54
|
"packages/core/homebrew.js",
|
|
54
55
|
"packages/core/artifact-verification-envelope.js",
|
|
55
56
|
"packages/core/anchored-version-material.js",
|
|
56
|
-
"packages/core/next-development-transition.js",
|
|
57
|
-
"packages/core/next-development-controller.js",
|
|
58
|
-
"packages/core/next-development-candidate-reservation.js",
|
|
59
|
-
"packages/core/next-development-projection.js",
|
|
60
57
|
"packages/core/build-facts.js",
|
|
61
58
|
"packages/core/publication-package.js",
|
|
62
59
|
"packages/core/publication-reproducibility.js",
|
|
@@ -79,8 +76,6 @@ const requiredPaths = [
|
|
|
79
76
|
"docs/auditable-demo.md",
|
|
80
77
|
"contracts/auditable-demo-scenario-v1.schema.json",
|
|
81
78
|
"contracts/release-candidate-recovery-v1.schema.json",
|
|
82
|
-
"contracts/next-development-request-v1.schema.json",
|
|
83
|
-
"contracts/next-development-transition-v1.schema.json",
|
|
84
79
|
"contracts/auditable-demo-media-profiles-v1.json",
|
|
85
80
|
"contracts/evidence/auditable-demo-web-delivery-v1.json",
|
|
86
81
|
"contracts/evidence/auditable-demo-responsive-web-delivery-v1.json",
|
|
@@ -92,15 +87,10 @@ const requiredPaths = [
|
|
|
92
87
|
"contracts/fixtures/auditable-demo-responsive-web-delivery-v1/public-projection.json",
|
|
93
88
|
"contracts/fixtures/auditable-demo-responsive-web-delivery-v1/scene.json",
|
|
94
89
|
"docs/release-propagation.md",
|
|
95
|
-
"docs/next-development-transition.md",
|
|
96
90
|
"docs/site-bundle-contract.md",
|
|
97
91
|
"docs/toolkit-observability.md",
|
|
98
92
|
"docs/versioning.md",
|
|
99
93
|
"scripts/release-line-dry-run.mjs",
|
|
100
|
-
"scripts/next-development-transition.mjs",
|
|
101
|
-
"scripts/next-development-self-dogfood.mjs",
|
|
102
|
-
"scripts/next-development-self-dogfood-harness.mjs",
|
|
103
|
-
"scripts/generate-next-development-guidance.mjs",
|
|
104
94
|
"scripts/reconcile-release-governance.mjs",
|
|
105
95
|
"scripts/buildchain-channel-router.mjs",
|
|
106
96
|
"scripts/generate-channel-build-workflow.mjs",
|
|
@@ -206,10 +196,19 @@ const selfDogfoodAlphaLock = JSON.parse(
|
|
|
206
196
|
const currentBuildchainContract = JSON.parse(
|
|
207
197
|
fs.readFileSync(path.join(root, "dist/site/buildchain-contract.json"), "utf8"),
|
|
208
198
|
);
|
|
199
|
+
const selfDogfoodBootstrapAuthority = JSON.parse(
|
|
200
|
+
fs.readFileSync(path.join(root, "architecture/v4-bootstrap-authority.json"), "utf8"),
|
|
201
|
+
);
|
|
209
202
|
const selfDogfoodMajorResolution = resolveSelfDogfoodMajor({
|
|
210
203
|
packageVersion: rootPackage.version,
|
|
211
204
|
alphaRef: selfDogfoodAlphaLock.buildchain?.ref,
|
|
212
|
-
majorBootstrap:
|
|
205
|
+
majorBootstrap:
|
|
206
|
+
process.env.BUILDCHAIN_MAJOR_VERSION_BOOTSTRAP === "true" ||
|
|
207
|
+
hasQualifiedSelfDogfoodBootstrapAuthority({
|
|
208
|
+
packageVersion: rootPackage.version,
|
|
209
|
+
alphaRef: selfDogfoodAlphaLock.buildchain?.ref,
|
|
210
|
+
authority: selfDogfoodBootstrapAuthority,
|
|
211
|
+
}),
|
|
213
212
|
});
|
|
214
213
|
const selfDogfoodMajor = String(selfDogfoodMajorResolution.workflowMajor);
|
|
215
214
|
if (!/^[0-9a-f]{40}$/.test(selfDogfoodAlphaLock.buildchain?.resolvedSha || "")) {
|
|
@@ -294,7 +293,7 @@ for (const requiredSnippet of [
|
|
|
294
293
|
"authorize-promotion-runtime-override.cjs",
|
|
295
294
|
"BUILDCHAIN_ROUTER_REPOSITORY: ${{ inputs.buildchain-repository }}",
|
|
296
295
|
"BUILDCHAIN_RESUME_RUNTIME_SHA: ${{ inputs.resume-buildchain-runtime-sha }}",
|
|
297
|
-
"
|
|
296
|
+
"git ls-remote",
|
|
298
297
|
"Recovery router ref does not match resume-buildchain-runtime-sha",
|
|
299
298
|
]) {
|
|
300
299
|
if (!channelPromotionWorkflow.includes(requiredSnippet)) {
|
|
@@ -315,7 +314,9 @@ if (!promotionOverrideAuthorization.includes("promotion runtime override is only
|
|
|
315
314
|
}
|
|
316
315
|
for (const requiredSnippet of [
|
|
317
316
|
"buildchain-channel:",
|
|
318
|
-
"uses:
|
|
317
|
+
"uses: ./.github/workflows/.build.yml",
|
|
318
|
+
"needs.resolve-channel.outputs.runtime-override != 'true' && needs.resolve-channel.outputs.channel == 'alpha'",
|
|
319
|
+
"needs.resolve-channel.outputs.runtime-override != 'true' && needs.resolve-channel.outputs.channel == 'stable'",
|
|
319
320
|
"needs.resolve-channel.outputs.buildchain-ref",
|
|
320
321
|
"needs.resolve-channel.outputs.contract-lock-path",
|
|
321
322
|
]) {
|
|
@@ -323,6 +324,12 @@ for (const requiredSnippet of [
|
|
|
323
324
|
throw new Error(`channel build workflow missing routing contract: ${requiredSnippet}`);
|
|
324
325
|
}
|
|
325
326
|
}
|
|
327
|
+
if ((channelBuildWorkflow.match(/uses: \.\/\.github\/workflows\/\.build\.yml/g) || []).length !== 3) {
|
|
328
|
+
throw new Error("channel build workflow must bind override, alpha, and stable to the exact caller workflow shell");
|
|
329
|
+
}
|
|
330
|
+
if (channelBuildWorkflow.includes("uses: kungfu-systems/buildchain/.github/workflows/.build.yml@")) {
|
|
331
|
+
throw new Error("channel build workflow must not statically fetch another channel shell before its ref exists");
|
|
332
|
+
}
|
|
326
333
|
for (const requiredSnippet of [
|
|
327
334
|
"group: buildchain-release-promotion-${{ github.repository }}",
|
|
328
335
|
"cancel-in-progress: false",
|
|
@@ -904,7 +911,7 @@ for (const requiredSnippet of [
|
|
|
904
911
|
for (const [docName, docSource] of Object.entries({ "docs/cli.md": cliDoc, "docs/install.md": installDoc })) {
|
|
905
912
|
for (const requiredSnippet of [
|
|
906
913
|
"minimumReleaseAgeExclude",
|
|
907
|
-
"@kungfu-tech/buildchain@
|
|
914
|
+
"@kungfu-tech/buildchain@4.0.0",
|
|
908
915
|
"package/version-specific",
|
|
909
916
|
]) {
|
|
910
917
|
if (!docSource.includes(requiredSnippet)) {
|
|
@@ -1003,7 +1010,7 @@ for (const forbiddenSnippet of [
|
|
|
1003
1010
|
for (const requiredSnippet of [
|
|
1004
1011
|
"id-token: write",
|
|
1005
1012
|
"actions: write",
|
|
1006
|
-
"uses:
|
|
1013
|
+
"uses: ./.github/workflows/.release-candidate-promote.yml",
|
|
1007
1014
|
"github.event.workflow_run.event == 'push'",
|
|
1008
1015
|
"!startsWith(github.event.workflow_run.display_title, 'chore(release): prepare v')",
|
|
1009
1016
|
"!startsWith(github.event.workflow_run.display_title, 'chore(release): release v')",
|
|
@@ -1049,11 +1056,9 @@ for (const requiredSnippet of [
|
|
|
1049
1056
|
"github-release-notes: ${{ inputs.github-release-notes }}",
|
|
1050
1057
|
"publication-commit-command:",
|
|
1051
1058
|
"BUILDCHAIN_PUBLICATION_COMMIT_SIGNING_KEY:",
|
|
1052
|
-
"BUILDCHAIN_PUBLICATION_COMMIT_CANDIDATE_SOURCE_SHA: ${{ steps.rc.outputs.release-candidate-source-sha || needs.preflight.outputs.requested-sha }}",
|
|
1053
1059
|
"KUNGFU_GOVERNANCE_AUDITOR_APP_PRIVATE_KEY:",
|
|
1054
1060
|
"Commit consumer publication authority last",
|
|
1055
1061
|
"node .buildchain/runtime/scripts/publication-commit-evidence.mjs",
|
|
1056
|
-
'--candidate-source-sha "${BUILDCHAIN_PUBLICATION_COMMIT_CANDIDATE_SOURCE_SHA}"',
|
|
1057
1062
|
"require-publish-source-lock: \"true\"",
|
|
1058
1063
|
"publish-source-ref: ${{ steps.publish-gate.outputs.ref }}",
|
|
1059
1064
|
"publish-source-sha: ${{ steps.publish-gate.outputs.sha }}",
|
|
@@ -1153,8 +1158,8 @@ for (const requiredSnippet of [
|
|
|
1153
1158
|
}
|
|
1154
1159
|
}
|
|
1155
1160
|
for (const forbiddenSnippet of [
|
|
1156
|
-
"
|
|
1157
|
-
"uses:
|
|
1161
|
+
"run: node scripts/release-candidate-resolver.mjs",
|
|
1162
|
+
"uses: ./actions/promote-buildchain-ref",
|
|
1158
1163
|
]) {
|
|
1159
1164
|
if (buildchainRefPromotionWorkflow.includes(forbiddenSnippet)) {
|
|
1160
1165
|
throw new Error(`buildchain ref promotion workflow must use the declarative wrapper, found manual snippet: ${forbiddenSnippet}`);
|
|
@@ -1256,12 +1261,12 @@ if (inventory.release !== "buildchain-v2") {
|
|
|
1256
1261
|
throw new Error("inventory release must be buildchain-v2");
|
|
1257
1262
|
}
|
|
1258
1263
|
|
|
1259
|
-
if (inventory.stableRefs?.actions !== "kungfu-systems/buildchain/actions/<name>@
|
|
1260
|
-
throw new Error("inventory stable action ref must point at @
|
|
1264
|
+
if (inventory.stableRefs?.actions !== "kungfu-systems/buildchain/actions/<name>@v4") {
|
|
1265
|
+
throw new Error("inventory stable action ref must point at @v4");
|
|
1261
1266
|
}
|
|
1262
1267
|
|
|
1263
|
-
if (inventory.stableRefs?.workflows !== "kungfu-systems/buildchain/.github/workflows/<workflow>.yml@
|
|
1264
|
-
throw new Error("inventory stable workflow ref must point at @
|
|
1268
|
+
if (inventory.stableRefs?.workflows !== "kungfu-systems/buildchain/.github/workflows/<workflow>.yml@v4") {
|
|
1269
|
+
throw new Error("inventory stable workflow ref must point at @v4");
|
|
1265
1270
|
}
|
|
1266
1271
|
if (inventory.safety?.releasePassport?.line !== "v2.2") {
|
|
1267
1272
|
throw new Error("release passport inventory must be registered as a v2.2 surface");
|
|
@@ -1297,7 +1302,7 @@ if (!badgeEndpointRegistry.badges?.some((entry) => entry.id === "buildchain-rele
|
|
|
1297
1302
|
throw new Error("badge endpoint registry must include Buildchain Release Passport badge");
|
|
1298
1303
|
}
|
|
1299
1304
|
|
|
1300
|
-
for (const siteFile of ["buildchain-site.json", "site-manifest.json", "badge-endpoint-registry.json", "publication-registry.json", "page-registry.json", "capability-registry.json", "cli-registry.json", "manual-registry.json", "node-api-registry.json", "workflow-registry.json", "controller-registry.json", "public-surface-audit.json", "release-model.json", "release-passport-check-manifest.json", "schemas/release-passport-v1.schema.json", "
|
|
1305
|
+
for (const siteFile of ["buildchain-site.json", "site-manifest.json", "badge-endpoint-registry.json", "publication-registry.json", "page-registry.json", "capability-registry.json", "cli-registry.json", "manual-registry.json", "node-api-registry.json", "workflow-registry.json", "controller-registry.json", "public-surface-audit.json", "release-model.json", "release-passport-check-manifest.json", "schemas/release-passport-v1.schema.json", "buildchain-contract.json"]) {
|
|
1301
1306
|
if (!fs.existsSync(path.join(root, "dist", "site", siteFile))) {
|
|
1302
1307
|
throw new Error(`site bundle missing ${siteFile}`);
|
|
1303
1308
|
}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const DEFAULT_ROOT = path.resolve(
|
|
8
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
9
|
+
"..",
|
|
10
|
+
);
|
|
11
|
+
const CALLER_PATH = ".github/workflows/v4-public-consumer-dogfood.yml";
|
|
12
|
+
const REUSABLE_PATH = ".github/workflows/v4-stage-capsule-canary.yml";
|
|
13
|
+
export const V4_PUBLIC_DOGFOOD_TRAIN_REF =
|
|
14
|
+
"train/v4/v4.0/public-consumer-self-dogfood";
|
|
15
|
+
const EXACT_SHA = /^[0-9a-f]{40}$/u;
|
|
16
|
+
const PRIVATE_CONSUMER = ["buildchain", "self", "dogfood"].join("-");
|
|
17
|
+
const PRIVATE_SHADOW = ["kungfu", "shadow"].join("-");
|
|
18
|
+
|
|
19
|
+
export function expectedV4PublicDogfoodWorkflow(validationRef) {
|
|
20
|
+
return `name: V4 Public Consumer Dogfood
|
|
21
|
+
|
|
22
|
+
on:
|
|
23
|
+
pull_request:
|
|
24
|
+
workflow_dispatch:
|
|
25
|
+
|
|
26
|
+
permissions:
|
|
27
|
+
contents: read
|
|
28
|
+
|
|
29
|
+
jobs:
|
|
30
|
+
dogfood:
|
|
31
|
+
uses: kungfu-systems/buildchain/.github/workflows/v4-stage-capsule-canary.yml@${validationRef}
|
|
32
|
+
with:
|
|
33
|
+
consumer: buildchain
|
|
34
|
+
node-version: "24"
|
|
35
|
+
go-version: "1.25.x"
|
|
36
|
+
install-artifact-path: node_modules/.modules.yaml
|
|
37
|
+
build-artifact-path: actions/run-lifecycle/dist/index.js
|
|
38
|
+
verify-artifact-path: dist/site
|
|
39
|
+
`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function fail(message) {
|
|
43
|
+
throw new Error(`v4-public-dogfood-contract: ${message}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function read(root, relative) {
|
|
47
|
+
const file = path.join(root, relative);
|
|
48
|
+
if (!fs.existsSync(file)) fail(`${relative} is missing`);
|
|
49
|
+
return fs.readFileSync(file, "utf8");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function exactJson(root, relative) {
|
|
53
|
+
try {
|
|
54
|
+
return JSON.parse(read(root, relative));
|
|
55
|
+
} catch (error) {
|
|
56
|
+
fail(`${relative} is not valid JSON: ${error.message}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function assertNoPrivateMarkers(relative, text) {
|
|
61
|
+
for (const marker of [
|
|
62
|
+
PRIVATE_CONSUMER,
|
|
63
|
+
PRIVATE_SHADOW,
|
|
64
|
+
"selfDogfood",
|
|
65
|
+
"kungfuShadow",
|
|
66
|
+
])
|
|
67
|
+
if (text.includes(marker))
|
|
68
|
+
fail(`${relative} retains private marker ${marker}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function assertReusableWorkflow(root) {
|
|
72
|
+
const reusable = read(root, REUSABLE_PATH);
|
|
73
|
+
for (const binding of [
|
|
74
|
+
"workflow_call:",
|
|
75
|
+
"BUILDCHAIN_WORKFLOW_SHA: ${{ job.workflow_sha }}",
|
|
76
|
+
"CONSUMER_SOURCE_SHA: ${{ github.sha }}",
|
|
77
|
+
"- uses: actions/setup-go@v6.5.0",
|
|
78
|
+
"if: inputs.go-version != ''",
|
|
79
|
+
])
|
|
80
|
+
if (!reusable.includes(binding))
|
|
81
|
+
fail(`${REUSABLE_PATH} is missing exact binding ${binding}`);
|
|
82
|
+
for (const stage of ["install", "build", "verify"])
|
|
83
|
+
if (!reusable.includes(`lifecycle run ${stage}`))
|
|
84
|
+
fail(`${REUSABLE_PATH} does not execute lifecycle.${stage}`);
|
|
85
|
+
for (const forbidden of [
|
|
86
|
+
"lifecycle run publish",
|
|
87
|
+
"self-hosted",
|
|
88
|
+
"secrets: inherit",
|
|
89
|
+
])
|
|
90
|
+
if (reusable.toLowerCase().includes(forbidden))
|
|
91
|
+
fail(`${REUSABLE_PATH} contains forbidden authority ${forbidden}`);
|
|
92
|
+
if (/\baws\b/iu.test(reusable))
|
|
93
|
+
fail(`${REUSABLE_PATH} contains forbidden AWS authority`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function assertWorkflowInventory(root) {
|
|
97
|
+
const workflowRoot = path.join(root, ".github/workflows");
|
|
98
|
+
for (const entry of fs.readdirSync(workflowRoot, { withFileTypes: true })) {
|
|
99
|
+
if (!entry.isFile() || !/\.ya?ml$/u.test(entry.name)) continue;
|
|
100
|
+
const relative = `.github/workflows/${entry.name}`;
|
|
101
|
+
const text = read(root, relative);
|
|
102
|
+
if (
|
|
103
|
+
relative !== REUSABLE_PATH &&
|
|
104
|
+
text.includes("scripts/v4-stage-capsule-qualification.mjs")
|
|
105
|
+
)
|
|
106
|
+
fail(`${relative} invokes the private qualification script directly`);
|
|
107
|
+
if (
|
|
108
|
+
relative !== CALLER_PATH &&
|
|
109
|
+
text.includes(".github/workflows/v4-stage-capsule-canary.yml@")
|
|
110
|
+
)
|
|
111
|
+
fail(`${relative} creates a second v4 dogfood caller`);
|
|
112
|
+
if (relative !== REUSABLE_PATH && relative !== CALLER_PATH)
|
|
113
|
+
assertNoPrivateMarkers(relative, text);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function assertProtectedVerify(root) {
|
|
118
|
+
const verify = read(root, ".github/workflows/verify.yml");
|
|
119
|
+
for (const required of [
|
|
120
|
+
"needs: stage-capsule-checkpoints",
|
|
121
|
+
"name: Enforce public consumer-only v4 dogfood",
|
|
122
|
+
"run: node scripts/check-v4-public-dogfood-contract.mjs",
|
|
123
|
+
])
|
|
124
|
+
if (!verify.includes(required))
|
|
125
|
+
fail(`Verify is missing protected gate ${required}`);
|
|
126
|
+
for (const forbidden of [
|
|
127
|
+
"stage-capsule-qualification:",
|
|
128
|
+
"stage-capsule-qualification-reconciliation:",
|
|
129
|
+
"scripts/v4-stage-capsule-qualification.mjs",
|
|
130
|
+
])
|
|
131
|
+
if (verify.includes(forbidden))
|
|
132
|
+
fail(`Verify retains private dogfood path ${forbidden}`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function assertArchitecture(root) {
|
|
136
|
+
const architecture = exactJson(
|
|
137
|
+
root,
|
|
138
|
+
"architecture/v4-stage-capsule-qualification.json",
|
|
139
|
+
);
|
|
140
|
+
const dogfood = architecture.publicConsumerDogfood;
|
|
141
|
+
const validationRef = dogfood?.validationRef;
|
|
142
|
+
if (
|
|
143
|
+
validationRef !== V4_PUBLIC_DOGFOOD_TRAIN_REF &&
|
|
144
|
+
!EXACT_SHA.test(String(validationRef))
|
|
145
|
+
)
|
|
146
|
+
fail(
|
|
147
|
+
"architecture validationRef must be the exact public train or a protected commit SHA",
|
|
148
|
+
);
|
|
149
|
+
const caller = read(root, CALLER_PATH);
|
|
150
|
+
if (caller !== expectedV4PublicDogfoodWorkflow(validationRef))
|
|
151
|
+
fail(`${CALLER_PATH} must remain the exact thin public consumer caller`);
|
|
152
|
+
if (JSON.stringify(architecture.campaign?.consumers) !== '["buildchain"]')
|
|
153
|
+
fail(
|
|
154
|
+
"architecture must qualify only the public Buildchain consumer identity",
|
|
155
|
+
);
|
|
156
|
+
if (
|
|
157
|
+
!dogfood ||
|
|
158
|
+
dogfood.callerWorkflow !== CALLER_PATH ||
|
|
159
|
+
dogfood.reusableWorkflow !==
|
|
160
|
+
"kungfu-systems/buildchain/.github/workflows/v4-stage-capsule-canary.yml" ||
|
|
161
|
+
dogfood.runtimeBinding !== "job.workflow_sha" ||
|
|
162
|
+
dogfood.consumerSourceBinding !== "github.sha" ||
|
|
163
|
+
JSON.stringify(dogfood.executableStages) !==
|
|
164
|
+
'["install","build","verify"]' ||
|
|
165
|
+
JSON.stringify(dogfood.excludedStages) !==
|
|
166
|
+
'{"version-state":"source-mutation","publish":"provider-mutation"}' ||
|
|
167
|
+
dogfood.consumerOrchestrationCopied !== false ||
|
|
168
|
+
dogfood.relativeOrSelfInvocationAllowed !== false ||
|
|
169
|
+
dogfood.directQualificationInvocationAllowed !== false ||
|
|
170
|
+
dogfood.candidateBranchOverrideAllowed !== false ||
|
|
171
|
+
dogfood.recursionRecovery !== "public-train-ref-only"
|
|
172
|
+
)
|
|
173
|
+
fail(
|
|
174
|
+
"architecture publicConsumerDogfood contract is incomplete or widened",
|
|
175
|
+
);
|
|
176
|
+
for (const key of ["selfDogfood", "kungfuShadow", "externalConsumerCanary"])
|
|
177
|
+
if (Object.hasOwn(architecture, key))
|
|
178
|
+
fail(`architecture retains duplicate ${key}`);
|
|
179
|
+
if (
|
|
180
|
+
architecture.mode !== "shadow-only" ||
|
|
181
|
+
architecture.productionAuthority !== "v3" ||
|
|
182
|
+
[
|
|
183
|
+
"providerEffects",
|
|
184
|
+
"productionWrites",
|
|
185
|
+
"productionReuse",
|
|
186
|
+
"releaseEffects",
|
|
187
|
+
"credentials",
|
|
188
|
+
"aws",
|
|
189
|
+
"selfHostedRunners",
|
|
190
|
+
"v3BehaviorChange",
|
|
191
|
+
].some((key) => architecture.authority?.[key] !== false)
|
|
192
|
+
)
|
|
193
|
+
fail("architecture authority ceiling changed");
|
|
194
|
+
return validationRef;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function assertConsumerLifecycle(root) {
|
|
198
|
+
const lifecycle = read(root, ".buildchain/buildchain.toml");
|
|
199
|
+
for (const declaration of [
|
|
200
|
+
'[lifecycle.install]\ncommand = "corepack enable pnpm && corepack pnpm@11.7.0 install --frozen-lockfile"',
|
|
201
|
+
'[lifecycle.build]\ncommand = "corepack pnpm@11.7.0 run build && corepack pnpm@11.7.0 run generate:site"',
|
|
202
|
+
"[lifecycle.verify]\ncommands = [",
|
|
203
|
+
])
|
|
204
|
+
if (!lifecycle.includes(declaration))
|
|
205
|
+
fail(
|
|
206
|
+
`tracked consumer lifecycle is missing ${declaration.split("\n")[0]}`,
|
|
207
|
+
);
|
|
208
|
+
const attributes = read(root, ".gitattributes");
|
|
209
|
+
if (!attributes.split("\n").includes("* text=auto eol=lf"))
|
|
210
|
+
fail("consumer checkout is missing the cross-platform LF contract");
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function assertPolicySources(root) {
|
|
214
|
+
for (const relative of [
|
|
215
|
+
"packages/core/v4-stage-capsule-qualification.js",
|
|
216
|
+
"packages/core/v4-stage-capsule-qualification-campaign.js",
|
|
217
|
+
"scripts/v4-stage-capsule-qualification.mjs",
|
|
218
|
+
"architecture/v4-stage-capsule-qualification.json",
|
|
219
|
+
"docs/v4-stage-capsule.md",
|
|
220
|
+
])
|
|
221
|
+
assertNoPrivateMarkers(relative, read(root, relative));
|
|
222
|
+
|
|
223
|
+
const agents = read(root, "AGENTS.md");
|
|
224
|
+
for (const invariant of [
|
|
225
|
+
"same public reusable-workflow contract as every other consumer",
|
|
226
|
+
"No agent may add or restore a relative/self reusable-workflow call",
|
|
227
|
+
"never solve recursion with an internal exception",
|
|
228
|
+
"scripts/check-v4-public-dogfood-contract.mjs",
|
|
229
|
+
])
|
|
230
|
+
if (!agents.includes(invariant))
|
|
231
|
+
fail(`AGENTS.md is missing invariant: ${invariant}`);
|
|
232
|
+
|
|
233
|
+
const packageJson = exactJson(root, "package.json");
|
|
234
|
+
if (
|
|
235
|
+
!String(packageJson.scripts?.check || "").includes(
|
|
236
|
+
"node scripts/check-v4-public-dogfood-contract.mjs",
|
|
237
|
+
)
|
|
238
|
+
)
|
|
239
|
+
fail("pnpm run check does not include the public dogfood gate");
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function checkV4PublicDogfoodContract(root = DEFAULT_ROOT) {
|
|
243
|
+
assertReusableWorkflow(root);
|
|
244
|
+
assertWorkflowInventory(root);
|
|
245
|
+
assertProtectedVerify(root);
|
|
246
|
+
const validationRef = assertArchitecture(root);
|
|
247
|
+
assertConsumerLifecycle(root);
|
|
248
|
+
assertPolicySources(root);
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
schema: "buildchain-v4-public-dogfood-contract-check/v1",
|
|
252
|
+
ok: true,
|
|
253
|
+
caller: CALLER_PATH,
|
|
254
|
+
reusable: REUSABLE_PATH,
|
|
255
|
+
validationRef,
|
|
256
|
+
productionAuthority: "v3",
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (
|
|
261
|
+
process.argv[1] &&
|
|
262
|
+
path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)
|
|
263
|
+
) {
|
|
264
|
+
try {
|
|
265
|
+
process.stdout.write(`${JSON.stringify(checkV4PublicDogfoodContract())}\n`);
|
|
266
|
+
} catch (error) {
|
|
267
|
+
process.stderr.write(`${error.message}\n`);
|
|
268
|
+
process.exitCode = 1;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
@@ -112,10 +112,14 @@ export function createReleaseEvidenceBundle({
|
|
|
112
112
|
|
|
113
113
|
fs.mkdirSync(resolvedOutputDir, { recursive: true });
|
|
114
114
|
const archivePath = path.join(resolvedOutputDir, `${BUNDLE_BASE}.tar.gz`);
|
|
115
|
-
const tar = spawnSync(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
const tar = spawnSync(
|
|
116
|
+
"tar",
|
|
117
|
+
["-czf", path.basename(archivePath), "-C", tempDir, BUNDLE_BASE],
|
|
118
|
+
{
|
|
119
|
+
cwd: resolvedOutputDir,
|
|
120
|
+
stdio: "inherit",
|
|
121
|
+
},
|
|
122
|
+
);
|
|
119
123
|
if (tar.error) {
|
|
120
124
|
throw tar.error;
|
|
121
125
|
}
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
candidateFromDecision,
|
|
21
21
|
selectLatestQualifiedSource,
|
|
22
22
|
} from "../packages/core/dev-alpha-candidate-selection.js";
|
|
23
|
-
import { readGitHubNextDevelopmentVersionReservation } from "../packages/core/next-development-candidate-reservation.js";
|
|
24
23
|
|
|
25
24
|
export { reconcileActiveReleaseTrain, selectLatestQualifiedSource };
|
|
26
25
|
|
|
@@ -618,7 +617,6 @@ export async function runDevAlphaCandidatePatrol(
|
|
|
618
617
|
comparison,
|
|
619
618
|
workflowEvidence,
|
|
620
619
|
skippedNewerCommitCount,
|
|
621
|
-
versionReservation,
|
|
622
620
|
qualificationError,
|
|
623
621
|
} = await resolvePatrolSourceInputs({
|
|
624
622
|
client,
|
|
@@ -648,7 +646,6 @@ export async function runDevAlphaCandidatePatrol(
|
|
|
648
646
|
observedSourceHeadSha,
|
|
649
647
|
skippedNewerCommitCount,
|
|
650
648
|
...(targetBaseline ? { targetBaseline } : {}),
|
|
651
|
-
...(versionReservation ? { versionReservation } : {}),
|
|
652
649
|
},
|
|
653
650
|
workflowEvidence,
|
|
654
651
|
requiredWorkflowPaths,
|
|
@@ -995,20 +992,6 @@ export function createGitHubChannelCandidateClient({
|
|
|
995
992
|
targetBranch,
|
|
996
993
|
parseCandidate: managedCandidateFromPullRequest,
|
|
997
994
|
}),
|
|
998
|
-
async readNextDevelopmentVersionReservation({
|
|
999
|
-
reservationSha,
|
|
1000
|
-
candidateSha,
|
|
1001
|
-
targetVersion,
|
|
1002
|
-
}) {
|
|
1003
|
-
return readGitHubNextDevelopmentVersionReservation({
|
|
1004
|
-
api,
|
|
1005
|
-
owner,
|
|
1006
|
-
repo,
|
|
1007
|
-
reservationSha,
|
|
1008
|
-
candidateSha,
|
|
1009
|
-
targetVersion,
|
|
1010
|
-
});
|
|
1011
|
-
},
|
|
1012
995
|
async listCompletedWorkflowRuns(workflowPathValue, sourceBranch) {
|
|
1013
996
|
const runs = [];
|
|
1014
997
|
for (let page = 1; page <= 10; page += 1) {
|
|
@@ -1032,11 +1015,7 @@ export function createGitHubChannelCandidateClient({
|
|
|
1032
1015
|
for (const commit of rows) {
|
|
1033
1016
|
const commitSha = text(commit.sha);
|
|
1034
1017
|
if (commitSha === targetSha) return commits;
|
|
1035
|
-
commits.push(
|
|
1036
|
-
sha: commitSha,
|
|
1037
|
-
message: text(commit.commit?.message),
|
|
1038
|
-
parents: (commit.parents || []).map((parent) => text(parent.sha)),
|
|
1039
|
-
});
|
|
1018
|
+
commits.push(commitSha);
|
|
1040
1019
|
}
|
|
1041
1020
|
if (rows.length < 100) return commits;
|
|
1042
1021
|
}
|