@kungfu-tech/buildchain 4.0.2-alpha.9 → 4.0.3-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 +14 -5
- package/CONTRIBUTING.md +58 -0
- package/README.md +3 -3
- package/actions/promote-buildchain-ref/README.md +1 -1
- package/actions/release-candidate-promote/README.md +31 -0
- package/architecture/agent-change-map.md +190 -126
- package/architecture/{v4-architecture-constitution.md → architecture-constitution.md} +33 -30
- package/architecture/{v3-core-mechanism-inventory.md → baseline-core-mechanism-inventory.md} +1 -1
- package/architecture/{v4-bootstrap-authority.json → bootstrap-authority.json} +3 -3
- package/architecture/{v3-v4-capability-closure.md → capability-parity-closure.md} +3 -3
- package/architecture/{v3-v4-live-capability-inventory.json → capability-parity-live-capability-inventory.json} +4 -4
- package/architecture/{v4-capability-state-machine-manifest.json → capability-state-machine-manifest.json} +2 -2
- package/architecture/{v4-capability-state-machine-manifest.schema.json → capability-state-machine-manifest.schema.json} +2 -2
- package/architecture/ci-lane-change-budget.json +384 -0
- package/architecture/{v4-cross-platform-adopter-qualification.json → cross-platform-adopter-qualification.json} +4 -4
- package/architecture/{v4-delivery-authority-parity.json → delivery-authority-parity.json} +17 -17
- package/architecture/{v4-delivery-warrant-shadow-bootstrap-plan.json → delivery-warrant-shadow-bootstrap-plan.json} +4 -4
- package/architecture/{v4-delivery-warrant-shadow-bootstrap-plan.md → delivery-warrant-shadow-bootstrap-plan.md} +7 -7
- package/architecture/{v4-floating-consumer-policy.json → floating-consumer-policy.json} +2 -2
- package/architecture/{v4-floating-consumer-policy.md → floating-consumer-policy.md} +1 -1
- package/architecture/implementation-naming.json +1273 -0
- package/architecture/internal-capabilities.json +201 -154
- package/architecture/maintainability-debt.json +205 -146
- package/architecture/maintainability-policy.json +37 -33
- package/architecture/{v4-next-development-parity.json → next-development-parity.json} +12 -12
- package/architecture/{v4-partial-mutation-recovery-qualification.json → partial-mutation-recovery-qualification.json} +8 -5
- package/architecture/{v4-platform-stage-checkpoints.json → platform-stage-checkpoints.json} +3 -3
- package/architecture/{v4-provider-operation-journal-contract.json → provider-operation-journal-contract.json} +10 -7
- package/architecture/publication-facade-patches.json +64 -0
- package/architecture/{v4-publication-rehearsal-parity.json → publication-rehearsal-parity.json} +4 -4
- package/architecture/{v4-release-activation-shadow-domain.json → release-activation-shadow-domain.json} +9 -6
- package/architecture/release-tail-contract-inventory.json +6 -6
- package/architecture/{v4-release-topology.json → release-topology.json} +163 -72
- package/architecture/{v4-release-train-parity.json → release-train-parity.json} +2 -2
- package/architecture/{v4-runtime-ref-resume-authority.json → runtime-ref-resume-authority.json} +1 -1
- package/architecture/{v4-runtime-semantic-closure.json → runtime-semantic-closure.json} +2 -2
- package/architecture/{v4-rust-libnode-bridge-evaluation.json → rust-libnode-bridge-evaluation.json} +3 -3
- package/architecture/{v4-rust-libnode-bridge-spike.md → rust-libnode-bridge-spike.md} +6 -6
- package/architecture/rust-wasm-production-authority.json +58 -0
- package/architecture/{v4-stable-publication-fence.json → stable-publication-fence.json} +7 -4
- package/architecture/{v4-stage-capsule-contract.json → stage-capsule-contract.json} +1 -1
- package/architecture/{v4-stage-capsule-qualification.json → stage-capsule-qualification.json} +8 -8
- package/architecture/{v4-stage-capsule-resume-planner.json → stage-capsule-resume-planner.json} +2 -2
- package/architecture/{v4-stage-capsule-store-contract.json → stage-capsule-store-contract.json} +4 -4
- package/architecture/{v4-tail-reseal-parity.json → tail-reseal-parity.json} +35 -33
- package/architecture/universal-workflow-bootstrap.json +176 -0
- package/architecture/universal-workflow-fault-campaign.json +72 -0
- package/architecture/universal-workflow-train-admission.json +40 -0
- package/architecture/workflow-taxonomy.json +1462 -0
- package/bin/buildchain.mjs +10 -10
- package/bin/internal/adopter-delivery-cli.mjs +9 -9
- package/contracts/buildchain-v2-residuals-v1.json +57 -48
- package/contracts/dev-delivery-authority-v2.schema.json +16 -2
- package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
- package/contracts/v4-canonical-contracts-v1.schema.json +1 -0
- package/crates/{buildchain-v4-bridge → buildchain-host-bridge}/Cargo.lock +1 -1
- package/crates/{buildchain-v4-bridge → buildchain-host-bridge}/Cargo.toml +1 -1
- package/crates/{buildchain-v4-bridge → buildchain-host-bridge}/src/main.rs +3 -3
- package/dist/site/buildchain-contract.json +98 -53
- package/dist/site/buildchain-site.json +351 -102
- package/dist/site/capability-registry.json +7 -7
- package/dist/site/controller-registry.json +50 -13
- package/dist/site/kfd-claims.json +2773 -1052
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +14 -14
- package/dist/site/node-api-registry.json +13176 -10733
- package/dist/site/page-registry.json +332 -83
- package/dist/site/public-surface-audit.json +3227 -1222
- package/dist/site/publication-authority-registry.json +1135 -363
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +18 -9
- package/dist/site/schemas/dev-delivery-authority-v2.schema.json +16 -2
- package/dist/site/site-manifest.json +18 -18
- package/dist/site/workflow-registry.json +5367 -1931
- package/docs/MAP.md +5 -3
- package/docs/auditable-demo.md +1 -1
- package/docs/cli.md +21 -8
- package/docs/dev-delivery-warrant.md +1 -1
- package/docs/engineering-housekeeper.md +3 -3
- package/docs/kfd-support.md +26 -2
- package/docs/next-development-transition.md +26 -3
- package/docs/node-api-reference.md +618 -358
- package/docs/oci-publication.md +173 -0
- package/docs/publication-authority.md +2 -2
- package/docs/publish-transaction.md +36 -3
- package/docs/release-candidate.md +3 -3
- package/docs/release-flow.md +67 -19
- package/docs/release-governance.md +8 -8
- package/docs/release-passport.md +27 -2
- package/docs/reusable-build-surface.md +17 -1
- package/docs/v4-adopter-delivery.md +4 -4
- package/docs/v4-canonical-contracts.md +7 -7
- package/docs/v4-delivery-warrant-read-candidate.md +3 -3
- package/docs/v4-delivery-warrant-semantic-diff.md +3 -3
- package/docs/v4-production-release.md +77 -8
- package/docs/v4-publication-rehearsal.md +3 -3
- package/docs/v4-runtime-ref-resume-authority.md +2 -2
- package/docs/v4-rust-wasm-production-authority.md +58 -0
- package/docs/v4-stage-capsule.md +9 -9
- package/docs/v4-tail-reseal.md +2 -2
- package/docs/workflow-catalog.md +155 -0
- package/docs/workflow-path-migration.md +109 -0
- package/package.json +39 -24
- package/packages/compatibility/adopter-delivery.js +16 -0
- package/packages/compatibility/cross-platform-adopter-qualification.js +12 -0
- package/packages/compatibility/floating-consumer-policy.js +14 -0
- package/packages/compatibility/publication-qualification.js +11 -0
- package/packages/compatibility/publication-rehearsal.js +18 -0
- package/packages/compatibility/runtime-ref-resume-authority.js +13 -0
- package/packages/compatibility/tail-reseal-receipt.js +7 -0
- package/packages/compatibility/tail-reseal.js +11 -0
- package/packages/core/{v4-adopter-delivery-parity.js → adopter-delivery-parity.js} +12 -12
- package/packages/core/{v4-adopter-delivery.js → adopter-delivery.js} +24 -24
- package/packages/core/artifact-verification-envelope.js +5 -5
- package/packages/core/buildchain-contract.js +6 -6
- package/packages/core/buildchain-domain.wasm +0 -0
- package/packages/core/buildchain-kfd-claims.js +2 -2
- package/packages/core/buildchain-publication-authority.js +43 -26
- package/packages/core/{v4-canonical-contracts.js → canonical-contracts.js} +39 -103
- package/packages/core/ci-lane-change-budget.js +14 -1
- package/packages/core/controller-evidence.js +4 -1
- package/packages/core/{v4-cross-platform-adopter-qualification.js → cross-platform-adopter-qualification.js} +19 -19
- package/packages/core/{v4-delivery-warrant-fixture-runner.js → delivery-warrant-fixture-runner.js} +36 -32
- package/packages/core/{v4-delivery-warrant-read-candidate.js → delivery-warrant-read-candidate.js} +40 -40
- package/packages/core/{v4-delivery-warrant-semantic-diff-gate.js → delivery-warrant-semantic-diff-gate.js} +58 -59
- package/packages/core/{v4-delivery-warrant-shadow-adapter.js → delivery-warrant-shadow-adapter.js} +15 -15
- package/packages/core/dev-delivery-candidate-identity.js +40 -6
- package/packages/core/dev-delivery-execution-transfer.js +6 -6
- package/packages/core/dev-delivery-native-proof.js +12 -8
- package/packages/core/dev-delivery-warrant-legacy-recovery.js +1 -1
- package/packages/core/dev-delivery-warrant-native-compatibility.js +4 -4
- package/packages/core/dev-delivery-warrant-state.js +14 -15
- package/packages/core/dev-delivery-warrant.js +15 -5
- package/packages/core/domain-wasm-artifact.js +7 -0
- package/packages/core/domain-wasm.js +216 -0
- package/packages/core/{v4-floating-consumer-evidence.js → floating-consumer-evidence.js} +14 -14
- package/packages/core/{v4-floating-consumer-policy.js → floating-consumer-policy.js} +28 -30
- package/packages/core/{v4-floating-consumer-release-passport.js → floating-consumer-release-passport.js} +25 -25
- package/packages/core/github-governance-authority.js +4 -4
- package/packages/core/index.js +4 -8
- package/packages/core/kfd-adopter-manifest.js +46 -47
- package/packages/core/next-development-projection.js +26 -3
- package/packages/core/next-development-transition.js +5 -6
- package/packages/core/oci-compose-qualification.js +143 -0
- package/packages/core/oci-publication-bundle.js +281 -0
- package/packages/core/oci-publication-graph.js +206 -0
- package/packages/core/paper-agent-entry.js +30 -4
- package/packages/core/paper-fleet.js +1 -1
- package/packages/core/paper-runtime-channels.js +348 -0
- package/packages/core/paper-scaffold-content.js +10 -0
- package/packages/core/paper.js +37 -71
- package/packages/core/partial-mutation-recovery-qualification.js +18 -0
- package/packages/core/{v4-platform-stage-checkpoints.js → platform-stage-checkpoints.js} +37 -37
- package/packages/core/product-publication.js +59 -0
- package/packages/core/{v4-protected-publication-source.js → protected-publication-source.js} +22 -24
- package/packages/core/provider-operation-journal.js +62 -0
- package/packages/core/{v4-provider-readback-idempotency.js → provider-readback-idempotency.js} +40 -125
- package/packages/core/public-export-compatibility.js +33 -0
- package/packages/core/publication-development.js +72 -0
- package/packages/core/{v4-publication-qualification.js → publication-qualification.js} +17 -17
- package/packages/core/{v4-publication-rehearsal-capsule.js → publication-rehearsal-capsule.js} +23 -23
- package/packages/core/publication-rehearsal-projection.js +2 -2
- package/packages/core/{v4-publication-rehearsal-provider-bindings.js → publication-rehearsal-provider-bindings.js} +4 -4
- package/packages/core/publication-rehearsal-runtime.js +21 -21
- package/packages/core/{v4-publication-rehearsal.js → publication-rehearsal.js} +33 -33
- package/packages/core/publication-sealed-bundle.js +78 -13
- package/packages/core/release-activation-shadow.js +32 -0
- package/packages/core/release-candidate.js +6 -6
- package/packages/core/release-invocation.js +64 -0
- package/packages/core/release-line-dry-run.js +1 -1
- package/packages/core/release-passport-contract.js +5 -5
- package/packages/core/release-passport.js +41 -40
- package/packages/core/release-tail-product-capabilities.js +9 -0
- package/packages/core/release-tail-provider-plane.js +68 -1048
- package/packages/core/{v4-runtime-ref-resume-authority.js → runtime-ref-resume-authority.js} +36 -40
- package/packages/core/{v4-runtime-selector-persistence.js → runtime-selector-persistence.js} +7 -7
- package/packages/core/stable-publication-fence.js +28 -0
- package/packages/core/{v4-stage-capsule-local-store.js → stage-capsule-local-store.js} +56 -54
- package/packages/core/{v4-stage-capsule-qualification-campaign.js → stage-capsule-qualification-campaign.js} +37 -38
- package/packages/core/{v4-stage-capsule-qualification.js → stage-capsule-qualification.js} +28 -29
- package/packages/core/{v4-stage-capsule-resume-planner.js → stage-capsule-resume-planner.js} +29 -29
- package/packages/core/{v4-stage-capsule-store.js → stage-capsule-store.js} +59 -56
- package/packages/core/{v4-stage-capsule.js → stage-capsule.js} +45 -45
- package/packages/core/{v4-tail-reseal-contract.js → tail-reseal-contract.js} +6 -6
- package/packages/core/{v4-tail-reseal-github.js → tail-reseal-github.js} +12 -12
- package/packages/core/{v4-tail-reseal-receipt.js → tail-reseal-receipt.js} +22 -22
- package/packages/core/{v4-tail-reseal.js → tail-reseal.js} +29 -29
- package/packages/core/universal-workflow-bootstrap.js +586 -0
- package/scripts/{v4-architecture.mjs → architecture.mjs} +6 -6
- package/scripts/binary-publication-evidence.mjs +135 -0
- package/scripts/{v4-bridge-bootstrap.mjs → bridge-bootstrap.mjs} +14 -18
- package/scripts/{v4-bridge-evidence.mjs → bridge-evidence.mjs} +8 -8
- package/scripts/build-contract-core.mjs +1 -14
- package/scripts/build-domain-wasm.mjs +177 -0
- package/scripts/{v3-v4-capability-catalog.mjs → capability-parity-catalog.mjs} +19 -19
- package/scripts/check-action-bundles.mjs +12 -2
- package/scripts/{check-v3-v4-capability-inventory.mjs → check-capability-parity-inventory.mjs} +42 -42
- package/scripts/check-ci-lane-change-budget.mjs +4 -1
- package/scripts/check-core-mechanism-inventory.mjs +8 -4
- package/scripts/{check-v4-floating-consumer-policy-contract.mjs → check-floating-consumer-policy-contract.mjs} +10 -10
- package/scripts/check-implementation-naming.mjs +135 -0
- package/scripts/check-inventory.mjs +39 -47
- package/scripts/check-maintainability.mjs +25 -115
- package/scripts/{check-v4-public-dogfood-contract.mjs → check-public-dogfood-contract.mjs} +37 -24
- package/scripts/{check-v4-release-topology.mjs → check-release-topology.mjs} +131 -52
- package/scripts/{check-v4-runtime-semantic-closure.mjs → check-runtime-semantic-closure.mjs} +23 -17
- package/scripts/check-universal-workflow-bootstrap.mjs +266 -0
- package/scripts/check-workflow-taxonomy.mjs +6 -0
- package/scripts/{v4-consumer-policy.mjs → consumer-policy.mjs} +15 -15
- package/scripts/copy-domain-wasm.mjs +14 -0
- package/scripts/{v4-cross-platform-adopter-qualification.mjs → cross-platform-adopter-qualification.mjs} +9 -9
- package/scripts/{v4-declarative-promotion-admission.mjs → declarative-promotion-admission.mjs} +4 -4
- package/scripts/dev-delivery-authority-command-adapters.mjs +1 -1
- package/scripts/dev-delivery-authority.mjs +8 -8
- package/scripts/dev-delivery-source-proof-reuse.mjs +2 -1
- package/scripts/dev-delivery-warrant-options.mjs +15 -10
- package/scripts/dev-delivery-warrant-store.mjs +98 -13
- package/scripts/dev-delivery-warrant-transition.mjs +109 -0
- package/scripts/dev-delivery-warrant.mjs +80 -103
- package/scripts/dev-pr-auto-merge.mjs +15 -15
- package/scripts/dev-pr-delivery-warrant.mjs +1 -1
- package/scripts/generate-channel-build-workflow.mjs +7 -2
- package/scripts/generate-channel-promotion-workflow.mjs +19 -34
- package/scripts/generate-release-candidate-passport.mjs +23 -23
- package/scripts/generate-site-bundle.mjs +28 -28
- package/scripts/generate-universal-workflow-facades.mjs +498 -0
- package/scripts/generate-workflow-taxonomy.mjs +25 -0
- package/scripts/github-output.mjs +31 -0
- package/scripts/{v4-host-adapter.mjs → host-adapter.mjs} +1 -1
- package/scripts/implementation-references.mjs +25 -0
- package/scripts/init-repo.mjs +1 -1
- package/scripts/maintainability-metrics.mjs +16 -5
- package/scripts/maintainability-public-surface.mjs +115 -0
- package/scripts/next-development-review.mjs +313 -0
- package/scripts/oci-compose-preview.mjs +261 -0
- package/scripts/paper-work-fleet-cli.mjs +2 -0
- package/scripts/{v4-platform-stage-checkpoint-rehearsal.mjs → platform-stage-checkpoint-rehearsal.mjs} +17 -17
- package/scripts/{v4-product-publication-intent.mjs → product-publication-intent.mjs} +28 -13
- package/scripts/publication-candidate-kind.mjs +93 -0
- package/scripts/publication-candidate-sealer.mjs +16 -1
- package/scripts/{v4-publication-rehearsal-fixture.mjs → publication-rehearsal-fixture.mjs} +5 -5
- package/scripts/publication-settlement.mjs +211 -0
- package/scripts/release-asset-client.mjs +91 -0
- package/scripts/{v4-release-candidate-adapter.mjs → release-candidate-adapter.mjs} +4 -4
- package/scripts/release-candidate-resolver.mjs +24 -35
- package/scripts/release-tail.mjs +5 -5
- package/scripts/resume-from-candidate-run.mjs +35 -42
- package/scripts/site-capability-metadata.mjs +9 -0
- package/scripts/source-verification-evidence.mjs +344 -0
- package/scripts/stable-candidate-qualification.mjs +1 -1
- package/scripts/{v4-stage-capsule-qualification.mjs → stage-capsule-qualification.mjs} +62 -62
- package/scripts/{v4-stage-capsule-resume-rehearsal.mjs → stage-capsule-resume-rehearsal.mjs} +6 -6
- package/scripts/{v4-tail-reseal-macos-rehearsal.mjs → tail-reseal-macos-rehearsal.mjs} +9 -9
- package/scripts/{v4-tail-reseal.mjs → tail-reseal.mjs} +19 -19
- package/scripts/universal-facade-maintainability.mjs +91 -0
- package/scripts/universal-workflow-backflow.mjs +212 -0
- package/scripts/universal-workflow-engine.mjs +620 -0
- package/scripts/universal-workflow-self-dogfood.mjs +205 -0
- package/scripts/verify-version-state-delta.mjs +175 -0
- package/scripts/{v4-warrant-shadow-plan.mjs → warrant-shadow-plan.mjs} +6 -6
- package/scripts/workflow-taxonomy.mjs +507 -0
- package/templates/native-dev-delivery.yml +4 -7
- package/templates/universal-buildchain-bootstrap-recovery.yml +282 -0
- package/templates/universal-buildchain-bootstrap.yml +28 -0
- package/actions/v4-release-candidate-promote/README.md +0 -3
- package/packages/core/v4-partial-mutation-recovery-qualification.js +0 -395
- package/packages/core/v4-product-publication.js +0 -387
- package/packages/core/v4-provider-operation-journal.js +0 -531
- package/packages/core/v4-release-activation-shadow.js +0 -519
- package/packages/core/v4-release-invocation.js +0 -425
- package/packages/core/v4-stable-publication-fence.js +0 -357
- /package/architecture/{v4-adopter-delivery-parity.json → adopter-delivery-parity.json} +0 -0
- /package/architecture/{v3-core-mechanism-inventory.json → baseline-core-mechanism-inventory.json} +0 -0
- /package/architecture/{v4-canonical-contract-fixtures.json → canonical-contract-fixtures.json} +0 -0
- /package/architecture/{v4-compatibility-facts-parity.json → compatibility-facts-parity.json} +0 -0
- /package/architecture/{v4-delivery-warrant-shadow-bootstrap-plan.schema.json → delivery-warrant-shadow-bootstrap-plan.schema.json} +0 -0
- /package/architecture/{v4-delivery-warrant-shadow-fixtures.json → delivery-warrant-shadow-fixtures.json} +0 -0
- /package/architecture/{v4-delivery-warrant-shadow-fixtures.schema.json → delivery-warrant-shadow-fixtures.schema.json} +0 -0
- /package/architecture/{v4-exception-ledger.json → exception-ledger.json} +0 -0
- /package/architecture/{v4-exception-ledger.schema.json → exception-ledger.schema.json} +0 -0
- /package/architecture/{v4-release-invocation-fixtures.json → release-invocation-fixtures.json} +0 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
import {
|
|
6
|
+
SETTLEMENT_ASSET,
|
|
7
|
+
verifyPublicationSettlement,
|
|
8
|
+
} from "./publication-settlement.mjs";
|
|
9
|
+
import { releaseAssetClient } from "./release-asset-client.mjs";
|
|
10
|
+
|
|
11
|
+
export async function readBinaryPublicationEvidence({
|
|
12
|
+
client,
|
|
13
|
+
repository,
|
|
14
|
+
tag,
|
|
15
|
+
sourceSha,
|
|
16
|
+
attempts = 40,
|
|
17
|
+
wait = () => new Promise((resolve) => setTimeout(resolve, 15000)),
|
|
18
|
+
}) {
|
|
19
|
+
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
20
|
+
let release;
|
|
21
|
+
try {
|
|
22
|
+
release = client.release(tag);
|
|
23
|
+
} catch {
|
|
24
|
+
/* Tag creation can precede Release creation. */
|
|
25
|
+
}
|
|
26
|
+
const assets = release?.assets || [];
|
|
27
|
+
const settlements = assets.filter(({ name }) => name === SETTLEMENT_ASSET);
|
|
28
|
+
const passports = assets.filter(
|
|
29
|
+
({ name }) => name === "buildchain.release.json",
|
|
30
|
+
);
|
|
31
|
+
if (settlements.length > 1 || passports.length > 1)
|
|
32
|
+
throw new Error("ambiguous immutable publication evidence");
|
|
33
|
+
if (settlements.length === 1 && passports.length === 1) {
|
|
34
|
+
const settlement = JSON.parse(client.assetBytes(settlements[0]));
|
|
35
|
+
const publicPassport = JSON.parse(client.assetBytes(passports[0]));
|
|
36
|
+
if (
|
|
37
|
+
settlement.contract !== "buildchain-v4-publication-settlement/v1" ||
|
|
38
|
+
settlement.release.sourceSha !== sourceSha ||
|
|
39
|
+
settlement.release.tag !== tag
|
|
40
|
+
)
|
|
41
|
+
throw new Error("binary publication settlement identity mismatch");
|
|
42
|
+
const tagSha = client.json(
|
|
43
|
+
`repos/${repository}/commits/${encodeURIComponent(tag)}`,
|
|
44
|
+
).sha;
|
|
45
|
+
if (tagSha !== sourceSha)
|
|
46
|
+
throw new Error("binary source does not match the exact release tag");
|
|
47
|
+
verifyPublicationSettlement(settlement.documents, {
|
|
48
|
+
repository,
|
|
49
|
+
tag,
|
|
50
|
+
sourceSha,
|
|
51
|
+
publicPassport,
|
|
52
|
+
});
|
|
53
|
+
return settlement;
|
|
54
|
+
}
|
|
55
|
+
if (attempt + 1 < attempts) await wait();
|
|
56
|
+
}
|
|
57
|
+
throw new Error(
|
|
58
|
+
"completed v4 publication evidence is not available within the bounded wait",
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function prepareBinaryAssetPaths({
|
|
63
|
+
binaryDir,
|
|
64
|
+
passportDir,
|
|
65
|
+
outputDir,
|
|
66
|
+
capabilityPath,
|
|
67
|
+
}) {
|
|
68
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
69
|
+
const files = [];
|
|
70
|
+
for (const directory of [binaryDir, passportDir]) {
|
|
71
|
+
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
72
|
+
if (!entry.isFile()) continue;
|
|
73
|
+
const source = path.join(directory, entry.name);
|
|
74
|
+
if (
|
|
75
|
+
directory === passportDir &&
|
|
76
|
+
entry.name === "buildchain.release.json"
|
|
77
|
+
) {
|
|
78
|
+
const renamed = path.join(outputDir, "buildchain.binary.release.json");
|
|
79
|
+
fs.copyFileSync(source, renamed);
|
|
80
|
+
files.push(renamed);
|
|
81
|
+
} else files.push(source);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (capabilityPath) {
|
|
85
|
+
const bytes = fs.readFileSync(capabilityPath);
|
|
86
|
+
const digest = crypto.createHash("sha256").update(bytes).digest("hex");
|
|
87
|
+
const retained = path.join(
|
|
88
|
+
outputDir,
|
|
89
|
+
`buildchain.binary.capability-${digest}.json`,
|
|
90
|
+
);
|
|
91
|
+
fs.writeFileSync(retained, bytes);
|
|
92
|
+
files.push(retained);
|
|
93
|
+
}
|
|
94
|
+
return files;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function main(mode) {
|
|
98
|
+
const repository = process.env.GITHUB_REPOSITORY;
|
|
99
|
+
const tag = process.env.RELEASE_TAG;
|
|
100
|
+
const client = releaseAssetClient(repository);
|
|
101
|
+
if (mode === "read") {
|
|
102
|
+
const settlement = await readBinaryPublicationEvidence({
|
|
103
|
+
client,
|
|
104
|
+
repository,
|
|
105
|
+
tag,
|
|
106
|
+
sourceSha: process.env.SOURCE_SHA,
|
|
107
|
+
});
|
|
108
|
+
const directory = ".buildchain/publication-evidence";
|
|
109
|
+
client.write(`${directory}/${SETTLEMENT_ASSET}`, settlement);
|
|
110
|
+
client.write(`${directory}/release.json`, {
|
|
111
|
+
channel: settlement.release.channel,
|
|
112
|
+
});
|
|
113
|
+
} else if (mode === "publish") {
|
|
114
|
+
const release = client.release(tag);
|
|
115
|
+
const files = prepareBinaryAssetPaths({
|
|
116
|
+
binaryDir: "dist/binary",
|
|
117
|
+
passportDir: ".buildchain/release-passport",
|
|
118
|
+
outputDir: ".buildchain/binary-publication",
|
|
119
|
+
capabilityPath: ".buildchain/publication-authority/capability.json",
|
|
120
|
+
});
|
|
121
|
+
const results = await client.publish(release, files);
|
|
122
|
+
client.write(".buildchain/binary-publication/readback.json", {
|
|
123
|
+
repository,
|
|
124
|
+
tag,
|
|
125
|
+
assets: results,
|
|
126
|
+
});
|
|
127
|
+
console.log(JSON.stringify({ published: results.length, repository, tag }));
|
|
128
|
+
} else throw new Error(`unknown binary publication mode: ${mode}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href)
|
|
132
|
+
main(process.argv[2]).catch((error) => {
|
|
133
|
+
console.error(error.message);
|
|
134
|
+
process.exitCode = 1;
|
|
135
|
+
});
|
|
@@ -10,7 +10,7 @@ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
|
10
10
|
const manifestPath = path.join(
|
|
11
11
|
root,
|
|
12
12
|
"crates",
|
|
13
|
-
"buildchain-
|
|
13
|
+
"buildchain-host-bridge",
|
|
14
14
|
"Cargo.toml",
|
|
15
15
|
);
|
|
16
16
|
|
|
@@ -18,14 +18,14 @@ function bridgeBinary(profile = "debug", platform = process.platform) {
|
|
|
18
18
|
return path.join(
|
|
19
19
|
root,
|
|
20
20
|
"crates",
|
|
21
|
-
"buildchain-
|
|
21
|
+
"buildchain-host-bridge",
|
|
22
22
|
"target",
|
|
23
23
|
profile,
|
|
24
|
-
`buildchain-
|
|
24
|
+
`buildchain-host-bridge${platform === "win32" ? ".exe" : ""}`,
|
|
25
25
|
);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
function
|
|
28
|
+
function createHostRequest({
|
|
29
29
|
command,
|
|
30
30
|
args = [],
|
|
31
31
|
input = Buffer.alloc(0),
|
|
@@ -45,7 +45,7 @@ function createV4HostRequest({
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
function
|
|
48
|
+
function buildBridge({ release = false } = {}) {
|
|
49
49
|
return spawnSync(
|
|
50
50
|
"cargo",
|
|
51
51
|
[
|
|
@@ -59,14 +59,14 @@ function buildV4Bridge({ release = false } = {}) {
|
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
function
|
|
62
|
+
function runBridge(
|
|
63
63
|
request,
|
|
64
64
|
{ mode = "exchange", profile = "debug", env = {}, encoding = null } = {},
|
|
65
65
|
) {
|
|
66
66
|
const binary = bridgeBinary(profile);
|
|
67
67
|
if (!fs.existsSync(binary)) {
|
|
68
68
|
throw new Error(
|
|
69
|
-
`Buildchain v4 bridge is not built: ${path.relative(root, binary)}; run pnpm bridge:
|
|
69
|
+
`Buildchain v4 bridge is not built: ${path.relative(root, binary)}; run pnpm bridge:build`,
|
|
70
70
|
);
|
|
71
71
|
}
|
|
72
72
|
return spawnSync(binary, [mode], {
|
|
@@ -74,11 +74,7 @@ function runV4Bridge(
|
|
|
74
74
|
env: {
|
|
75
75
|
...process.env,
|
|
76
76
|
BUILDCHAIN_V4_HOST_COMMAND: process.execPath,
|
|
77
|
-
BUILDCHAIN_V4_HOST_SCRIPT: path.join(
|
|
78
|
-
root,
|
|
79
|
-
"scripts",
|
|
80
|
-
"v4-host-adapter.mjs",
|
|
81
|
-
),
|
|
77
|
+
BUILDCHAIN_V4_HOST_SCRIPT: path.join(root, "scripts", "host-adapter.mjs"),
|
|
82
78
|
...env,
|
|
83
79
|
},
|
|
84
80
|
input: JSON.stringify(request),
|
|
@@ -94,7 +90,7 @@ function parseRunArgs(args) {
|
|
|
94
90
|
const command = bridgeArgs[0];
|
|
95
91
|
if (!command) {
|
|
96
92
|
throw new Error(
|
|
97
|
-
"usage: node scripts/
|
|
93
|
+
"usage: node scripts/bridge-bootstrap.mjs <run|exchange> <command-id> -- [command-args...]",
|
|
98
94
|
);
|
|
99
95
|
}
|
|
100
96
|
return { command, commandArgs };
|
|
@@ -103,7 +99,7 @@ function parseRunArgs(args) {
|
|
|
103
99
|
function main(args = process.argv.slice(2)) {
|
|
104
100
|
const [mode = "", ...rest] = args;
|
|
105
101
|
if (mode === "build") {
|
|
106
|
-
const result =
|
|
102
|
+
const result = buildBridge({ release: rest.includes("--release") });
|
|
107
103
|
process.stdout.write(result.stdout || "");
|
|
108
104
|
process.stderr.write(result.stderr || "");
|
|
109
105
|
process.exitCode = result.status ?? 1;
|
|
@@ -111,13 +107,13 @@ function main(args = process.argv.slice(2)) {
|
|
|
111
107
|
}
|
|
112
108
|
if (!["run", "exchange"].includes(mode)) {
|
|
113
109
|
throw new Error(
|
|
114
|
-
"usage: node scripts/
|
|
110
|
+
"usage: node scripts/bridge-bootstrap.mjs <build|run|exchange> ...",
|
|
115
111
|
);
|
|
116
112
|
}
|
|
117
113
|
const { command, commandArgs } = parseRunArgs(rest);
|
|
118
114
|
const input = fs.readFileSync(0);
|
|
119
|
-
const request =
|
|
120
|
-
const result =
|
|
115
|
+
const request = createHostRequest({ command, args: commandArgs, input });
|
|
116
|
+
const result = runBridge(request, {
|
|
121
117
|
mode: mode === "run" ? "compat" : "exchange",
|
|
122
118
|
});
|
|
123
119
|
if (result.error) throw result.error;
|
|
@@ -138,4 +134,4 @@ if (
|
|
|
138
134
|
}
|
|
139
135
|
}
|
|
140
136
|
|
|
141
|
-
export { bridgeBinary,
|
|
137
|
+
export { bridgeBinary, buildBridge, createHostRequest, main, runBridge };
|
|
@@ -7,13 +7,13 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
bridgeBinary,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "./
|
|
10
|
+
buildBridge,
|
|
11
|
+
createHostRequest,
|
|
12
|
+
runBridge,
|
|
13
|
+
} from "./bridge-bootstrap.mjs";
|
|
14
14
|
|
|
15
15
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
16
|
-
const hostScript = path.join(root, "scripts", "
|
|
16
|
+
const hostScript = path.join(root, "scripts", "host-adapter.mjs");
|
|
17
17
|
|
|
18
18
|
function flag(args, name, fallback = "") {
|
|
19
19
|
const index = args.indexOf(`--${name}`);
|
|
@@ -51,10 +51,10 @@ function collectEvidence(args = process.argv.slice(2)) {
|
|
|
51
51
|
if (!Number.isInteger(iterations) || iterations < 3 || iterations > 50) {
|
|
52
52
|
throw new Error("--iterations must be between 3 and 50");
|
|
53
53
|
}
|
|
54
|
-
const build =
|
|
54
|
+
const build = buildBridge({ release: true });
|
|
55
55
|
if (build.status !== 0) throw new Error(build.stderr || build.stdout);
|
|
56
56
|
const binary = bridgeBinary("release");
|
|
57
|
-
const request =
|
|
57
|
+
const request = createHostRequest({
|
|
58
58
|
command: "architecture.list",
|
|
59
59
|
args: ["--json"],
|
|
60
60
|
});
|
|
@@ -71,7 +71,7 @@ function collectEvidence(args = process.argv.slice(2)) {
|
|
|
71
71
|
);
|
|
72
72
|
const bridge = timed(
|
|
73
73
|
() =>
|
|
74
|
-
|
|
74
|
+
runBridge(request, {
|
|
75
75
|
mode: "exchange",
|
|
76
76
|
profile: "release",
|
|
77
77
|
encoding: "utf8",
|
|
@@ -3,6 +3,7 @@ import fs from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { macosJitRunnerLabel } from "./aws-macos-jit-core.mjs";
|
|
5
5
|
import { windowsJitRunnerLabel } from "./aws-windows-jit-core.mjs";
|
|
6
|
+
export { writeGitHubOutputs } from "./github-output.mjs";
|
|
6
7
|
export const RUNNER_PRESETS = Object.freeze({
|
|
7
8
|
"github-hosted": [
|
|
8
9
|
{ id: "linux-x64", name: "Linux x64", platform: "linux", runner: '["ubuntu-24.04"]', capabilities: ["node"] },
|
|
@@ -1201,20 +1202,6 @@ export function validateExpectedArtifacts({ expected, files, summary }) {
|
|
|
1201
1202
|
return { ok: true, source: "expected-artifacts-json", checks };
|
|
1202
1203
|
}
|
|
1203
1204
|
|
|
1204
|
-
export function writeGitHubOutputs(outputs) {
|
|
1205
|
-
const outputPath = process.env.GITHUB_OUTPUT;
|
|
1206
|
-
if (!outputPath) {
|
|
1207
|
-
for (const [key, value] of Object.entries(outputs)) {
|
|
1208
|
-
console.log(`${key}=${value}`);
|
|
1209
|
-
}
|
|
1210
|
-
return;
|
|
1211
|
-
}
|
|
1212
|
-
const lines = Object.entries(outputs).map(
|
|
1213
|
-
([key, value]) => `${key}=${value}`,
|
|
1214
|
-
);
|
|
1215
|
-
fs.appendFileSync(outputPath, `${lines.join("\n")}\n`);
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
1205
|
export function findJsonFiles(root) {
|
|
1219
1206
|
if (!fs.existsSync(root)) {
|
|
1220
1207
|
return [];
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
import { spawnSyncCommand } from "../packages/core/spawn-command.js";
|
|
8
|
+
|
|
9
|
+
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
10
|
+
const crate = path.join(root, "crates", "buildchain-domain-contracts");
|
|
11
|
+
const artifact = path.join(root, "packages", "core", "buildchain-domain.wasm");
|
|
12
|
+
const metadata = path.join(root, "packages", "core", "domain-wasm-artifact.js");
|
|
13
|
+
const check = process.argv.includes("--check");
|
|
14
|
+
const toolchain = process.env.BUILDCHAIN_RUST_WASM_TOOLCHAIN || "1.96.0";
|
|
15
|
+
const expectedRustc = "rustc 1.96.0 (ac68faa20 2026-05-25)";
|
|
16
|
+
const canonicalBuildHost =
|
|
17
|
+
process.platform === "linux" && process.arch === "x64";
|
|
18
|
+
|
|
19
|
+
const sha256 = (bytes) =>
|
|
20
|
+
crypto.createHash("sha256").update(bytes).digest("hex");
|
|
21
|
+
const normalize = (value) => value.split(path.sep).join("/");
|
|
22
|
+
|
|
23
|
+
function rustBuildEnvironment() {
|
|
24
|
+
const environment = {
|
|
25
|
+
...process.env,
|
|
26
|
+
RUSTUP_TOOLCHAIN: toolchain,
|
|
27
|
+
CARGO_INCREMENTAL: "0",
|
|
28
|
+
SOURCE_DATE_EPOCH: "0",
|
|
29
|
+
};
|
|
30
|
+
delete environment.RUSTFLAGS;
|
|
31
|
+
delete environment.CARGO_ENCODED_RUSTFLAGS;
|
|
32
|
+
|
|
33
|
+
const metadata = spawnSyncCommand(
|
|
34
|
+
"cargo",
|
|
35
|
+
[
|
|
36
|
+
"metadata",
|
|
37
|
+
"--format-version",
|
|
38
|
+
"1",
|
|
39
|
+
"--locked",
|
|
40
|
+
"--manifest-path",
|
|
41
|
+
path.join(crate, "Cargo.toml"),
|
|
42
|
+
],
|
|
43
|
+
{ cwd: root, encoding: "utf8", env: environment },
|
|
44
|
+
);
|
|
45
|
+
if (metadata.error) throw metadata.error;
|
|
46
|
+
if (metadata.status !== 0) process.exit(metadata.status ?? 1);
|
|
47
|
+
const dependencyRemaps = JSON.parse(metadata.stdout)
|
|
48
|
+
.packages.filter((entry) => entry.source)
|
|
49
|
+
.map((entry) => [
|
|
50
|
+
path.dirname(entry.manifest_path),
|
|
51
|
+
`/buildchain/dependencies/${entry.name}-${entry.version}`,
|
|
52
|
+
])
|
|
53
|
+
.sort(([left], [right]) => right.length - left.length);
|
|
54
|
+
const remaps = [[root, "/buildchain/source"], ...dependencyRemaps].map(
|
|
55
|
+
([from, to]) => `--remap-path-prefix=${from}=${to}`,
|
|
56
|
+
);
|
|
57
|
+
environment.CARGO_ENCODED_RUSTFLAGS = remaps.join("\x1f");
|
|
58
|
+
return environment;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function sourceFiles(directory) {
|
|
62
|
+
return fs.readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
|
|
63
|
+
const absolute = path.join(directory, entry.name);
|
|
64
|
+
return entry.isDirectory() ? sourceFiles(absolute) : [absolute];
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const rustc = spawnSyncCommand("rustc", ["--version"], {
|
|
69
|
+
cwd: root,
|
|
70
|
+
encoding: "utf8",
|
|
71
|
+
env: { ...process.env, RUSTUP_TOOLCHAIN: toolchain },
|
|
72
|
+
});
|
|
73
|
+
if (rustc.error) throw rustc.error;
|
|
74
|
+
if (rustc.status !== 0) process.exit(rustc.status ?? 1);
|
|
75
|
+
if (rustc.stdout.trim() !== expectedRustc) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
`Rust/WASM authority requires ${expectedRustc}; observed ${rustc.stdout.trim()}`,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const sourceInputs = [
|
|
82
|
+
path.join(crate, "Cargo.toml"),
|
|
83
|
+
path.join(crate, "Cargo.lock"),
|
|
84
|
+
path.join(crate, "rust-toolchain.toml"),
|
|
85
|
+
...sourceFiles(path.join(crate, "src")),
|
|
86
|
+
].sort();
|
|
87
|
+
const sourceHash = crypto.createHash("sha256");
|
|
88
|
+
for (const file of sourceInputs) {
|
|
89
|
+
sourceHash.update(normalize(path.relative(root, file)));
|
|
90
|
+
sourceHash.update("\0");
|
|
91
|
+
sourceHash.update(fs.readFileSync(file));
|
|
92
|
+
sourceHash.update("\0");
|
|
93
|
+
}
|
|
94
|
+
const sourceSha256 = sourceHash.digest("hex");
|
|
95
|
+
const generatedMetadata = (artifactSha256) =>
|
|
96
|
+
`// Generated by scripts/build-domain-wasm.mjs.\nexport const DOMAIN_WASM_ABI_VERSION = 1;\nexport const DOMAIN_WASM_RUSTC = ${JSON.stringify(expectedRustc)};\nexport const DOMAIN_WASM_SOURCE_SHA256 =\n ${JSON.stringify(sourceSha256)};\nexport const DOMAIN_WASM_SHA256 =\n ${JSON.stringify(artifactSha256)};\n`;
|
|
97
|
+
|
|
98
|
+
if (!canonicalBuildHost && !check) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
"Buildchain v4 Rust/WASM generation requires the canonical linux-x64 host",
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!canonicalBuildHost) {
|
|
105
|
+
if (!fs.existsSync(artifact)) {
|
|
106
|
+
throw new Error("tracked Buildchain v4 Rust/WASM artifact is missing");
|
|
107
|
+
}
|
|
108
|
+
const artifactSha256 = sha256(fs.readFileSync(artifact));
|
|
109
|
+
if (
|
|
110
|
+
!fs.existsSync(metadata) ||
|
|
111
|
+
fs.readFileSync(metadata, "utf8") !== generatedMetadata(artifactSha256)
|
|
112
|
+
) {
|
|
113
|
+
throw new Error("tracked Buildchain v4 Rust/WASM metadata is stale");
|
|
114
|
+
}
|
|
115
|
+
console.log(
|
|
116
|
+
`Buildchain v4 Rust/WASM portable artifact verified: sha256:${artifactSha256}`,
|
|
117
|
+
);
|
|
118
|
+
} else {
|
|
119
|
+
const buildEnvironment = rustBuildEnvironment();
|
|
120
|
+
|
|
121
|
+
const temporary = fs.mkdtempSync(path.join(os.tmpdir(), "buildchain-wasm-"));
|
|
122
|
+
try {
|
|
123
|
+
const build = spawnSyncCommand(
|
|
124
|
+
"cargo",
|
|
125
|
+
[
|
|
126
|
+
"build",
|
|
127
|
+
"--locked",
|
|
128
|
+
"--release",
|
|
129
|
+
"--manifest-path",
|
|
130
|
+
path.join(crate, "Cargo.toml"),
|
|
131
|
+
"--target",
|
|
132
|
+
"wasm32-unknown-unknown",
|
|
133
|
+
"--target-dir",
|
|
134
|
+
temporary,
|
|
135
|
+
"--lib",
|
|
136
|
+
],
|
|
137
|
+
{
|
|
138
|
+
cwd: root,
|
|
139
|
+
stdio: "inherit",
|
|
140
|
+
env: buildEnvironment,
|
|
141
|
+
},
|
|
142
|
+
);
|
|
143
|
+
if (build.error) throw build.error;
|
|
144
|
+
if (build.status !== 0) process.exit(build.status ?? 1);
|
|
145
|
+
const builtPath = path.join(
|
|
146
|
+
temporary,
|
|
147
|
+
"wasm32-unknown-unknown",
|
|
148
|
+
"release",
|
|
149
|
+
"buildchain_domain_contracts.wasm",
|
|
150
|
+
);
|
|
151
|
+
const built = fs.readFileSync(builtPath);
|
|
152
|
+
const artifactSha256 = sha256(built);
|
|
153
|
+
const generated = generatedMetadata(artifactSha256);
|
|
154
|
+
if (check) {
|
|
155
|
+
if (
|
|
156
|
+
!fs.existsSync(artifact) ||
|
|
157
|
+
!fs.readFileSync(artifact).equals(built)
|
|
158
|
+
) {
|
|
159
|
+
throw new Error("tracked Buildchain v4 Rust/WASM artifact is stale");
|
|
160
|
+
}
|
|
161
|
+
if (
|
|
162
|
+
!fs.existsSync(metadata) ||
|
|
163
|
+
fs.readFileSync(metadata, "utf8") !== generated
|
|
164
|
+
) {
|
|
165
|
+
throw new Error("tracked Buildchain v4 Rust/WASM metadata is stale");
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
fs.copyFileSync(builtPath, artifact);
|
|
169
|
+
fs.writeFileSync(metadata, generated);
|
|
170
|
+
}
|
|
171
|
+
console.log(
|
|
172
|
+
`Buildchain v4 Rust/WASM ${check ? "verified" : "built"}: sha256:${artifactSha256}`,
|
|
173
|
+
);
|
|
174
|
+
} finally {
|
|
175
|
+
fs.rmSync(temporary, { recursive: true, force: true });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -23,8 +23,8 @@ const PLATFORM_MARKERS = Object.freeze({
|
|
|
23
23
|
"self-hosted": /\bself-hosted\b/iu,
|
|
24
24
|
windows: /\bwindows\b/iu,
|
|
25
25
|
});
|
|
26
|
-
const
|
|
27
|
-
const
|
|
26
|
+
const LIVE_PROTECTED_BRANCH = "refs/heads/dev/v4/v4.0";
|
|
27
|
+
const LIVE_PROTECTED_LINEAGE_REF = "refs/remotes/origin/dev/v4/v4.0";
|
|
28
28
|
const PROTECTED_LINEAGE_DEPTH = 256;
|
|
29
29
|
|
|
30
30
|
export function sha256(value) {
|
|
@@ -85,7 +85,7 @@ export function ensureCapabilityCutAncestor({
|
|
|
85
85
|
try {
|
|
86
86
|
execFileSync(
|
|
87
87
|
"git",
|
|
88
|
-
["fetch", "--no-tags", "--depth=
|
|
88
|
+
["fetch", "--no-tags", "--depth=256", "origin", descendantCommit],
|
|
89
89
|
{ cwd: root, stdio: "ignore" },
|
|
90
90
|
);
|
|
91
91
|
} catch {
|
|
@@ -96,7 +96,7 @@ export function ensureCapabilityCutAncestor({
|
|
|
96
96
|
assertCapabilityCutAncestor({ root, revision, descendant, label });
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
function
|
|
99
|
+
function protectedTreeWitness(root, descendant) {
|
|
100
100
|
try {
|
|
101
101
|
execFileSync(
|
|
102
102
|
"git",
|
|
@@ -105,13 +105,13 @@ function protectedV4TreeWitness(root, descendant) {
|
|
|
105
105
|
"--no-tags",
|
|
106
106
|
`--depth=${PROTECTED_LINEAGE_DEPTH}`,
|
|
107
107
|
"origin",
|
|
108
|
-
`${
|
|
108
|
+
`${LIVE_PROTECTED_BRANCH}:${LIVE_PROTECTED_LINEAGE_REF}`,
|
|
109
109
|
],
|
|
110
110
|
{ cwd: root, stdio: "ignore" },
|
|
111
111
|
);
|
|
112
112
|
} catch {
|
|
113
113
|
throw new Error(
|
|
114
|
-
`protected v4 lineage ${
|
|
114
|
+
`protected v4 lineage ${LIVE_PROTECTED_BRANCH} could not be hydrated through a bounded origin fetch`,
|
|
115
115
|
);
|
|
116
116
|
}
|
|
117
117
|
const tree = git(root, ["rev-parse", `${descendant}^{tree}`]);
|
|
@@ -120,7 +120,7 @@ function protectedV4TreeWitness(root, descendant) {
|
|
|
120
120
|
"log",
|
|
121
121
|
`--max-count=${PROTECTED_LINEAGE_DEPTH}`,
|
|
122
122
|
"--format=%H %T",
|
|
123
|
-
|
|
123
|
+
LIVE_PROTECTED_LINEAGE_REF,
|
|
124
124
|
])
|
|
125
125
|
.split("\n")
|
|
126
126
|
.map((row) => row.split(" "))
|
|
@@ -138,7 +138,7 @@ export function ensureCapabilityCutLineage({
|
|
|
138
138
|
ensureCapabilityCutAncestor({ root, revision, descendant, label });
|
|
139
139
|
return { mode: "direct-ancestry", witness: descendant };
|
|
140
140
|
} catch (directError) {
|
|
141
|
-
const witness =
|
|
141
|
+
const witness = protectedTreeWitness(root, descendant);
|
|
142
142
|
if (!witness)
|
|
143
143
|
throw new Error(
|
|
144
144
|
`${label} ${revision} is not an ancestor of ${descendant}, and ${descendant} has no tree-equivalent commit in the bounded protected v4 lineage`,
|
|
@@ -394,12 +394,12 @@ function addMechanismCatalog(
|
|
|
394
394
|
catalog,
|
|
395
395
|
mechanismInventory,
|
|
396
396
|
runtimeSemanticClosure,
|
|
397
|
-
|
|
397
|
+
isLiveBaseline,
|
|
398
398
|
) {
|
|
399
|
-
const mechanisms =
|
|
399
|
+
const mechanisms = isLiveBaseline
|
|
400
400
|
? mechanismInventory.mechanisms || []
|
|
401
401
|
: runtimeSemanticClosure.capabilities || [];
|
|
402
|
-
const relPath =
|
|
402
|
+
const relPath = isLiveBaseline
|
|
403
403
|
? "architecture/v3-core-mechanism-inventory.json"
|
|
404
404
|
: "architecture/v4-runtime-semantic-closure.json";
|
|
405
405
|
for (const mechanism of mechanisms) {
|
|
@@ -439,7 +439,7 @@ function addPlatformCatalog(catalog, root, revision, paths) {
|
|
|
439
439
|
}
|
|
440
440
|
}
|
|
441
441
|
|
|
442
|
-
export function collectRevisionCatalog({ root, revision, liveV3Revision }) {
|
|
442
|
+
export function collectRevisionCatalog({ root, revision, liveV3Revision: liveBaselineRevision }) {
|
|
443
443
|
const catalog = new Map();
|
|
444
444
|
const paths = gitPaths(root, revision);
|
|
445
445
|
const pathSet = new Set(paths);
|
|
@@ -461,7 +461,7 @@ export function collectRevisionCatalog({ root, revision, liveV3Revision }) {
|
|
|
461
461
|
"architecture/v3-core-mechanism-inventory.json",
|
|
462
462
|
);
|
|
463
463
|
const runtimeSemanticClosure =
|
|
464
|
-
revision ===
|
|
464
|
+
revision === liveBaselineRevision
|
|
465
465
|
? null
|
|
466
466
|
: gitJson(
|
|
467
467
|
root,
|
|
@@ -476,7 +476,7 @@ export function collectRevisionCatalog({ root, revision, liveV3Revision }) {
|
|
|
476
476
|
catalog,
|
|
477
477
|
mechanismInventory,
|
|
478
478
|
runtimeSemanticClosure,
|
|
479
|
-
revision ===
|
|
479
|
+
revision === liveBaselineRevision,
|
|
480
480
|
);
|
|
481
481
|
addPlatformCatalog(catalog, root, revision, paths);
|
|
482
482
|
return { catalog, paths: pathSet };
|
|
@@ -485,8 +485,8 @@ export function collectRevisionCatalog({ root, revision, liveV3Revision }) {
|
|
|
485
485
|
export function collectHistoryRows({
|
|
486
486
|
root,
|
|
487
487
|
priorRevision,
|
|
488
|
-
liveV3Revision,
|
|
489
|
-
v4Paths,
|
|
488
|
+
liveV3Revision: liveBaselineRevision,
|
|
489
|
+
v4Paths: domainPaths,
|
|
490
490
|
migrationPaths,
|
|
491
491
|
ownerAssignment,
|
|
492
492
|
}) {
|
|
@@ -494,7 +494,7 @@ export function collectHistoryRows({
|
|
|
494
494
|
"diff",
|
|
495
495
|
"--name-status",
|
|
496
496
|
priorRevision,
|
|
497
|
-
|
|
497
|
+
liveBaselineRevision,
|
|
498
498
|
]);
|
|
499
499
|
return output
|
|
500
500
|
.split("\n")
|
|
@@ -503,11 +503,11 @@ export function collectHistoryRows({
|
|
|
503
503
|
const fields = line.split("\t");
|
|
504
504
|
const sourcePath = fields.at(-1);
|
|
505
505
|
const migrationPath = migrationPaths.get(sourcePath);
|
|
506
|
-
if (!
|
|
506
|
+
if (!domainPaths.has(sourcePath) && !migrationPath)
|
|
507
507
|
throw new Error(
|
|
508
508
|
`unclassified post-family v3 history path: ${sourcePath}`,
|
|
509
509
|
);
|
|
510
|
-
if (migrationPath && !
|
|
510
|
+
if (migrationPath && !domainPaths.has(migrationPath))
|
|
511
511
|
throw new Error(
|
|
512
512
|
`history migration route is absent from the exact v4 cut: ${migrationPath}`,
|
|
513
513
|
);
|
|
@@ -5,7 +5,7 @@ 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");
|
|
8
|
-
const
|
|
8
|
+
const javascriptBundlePaths = readdirSync(actionsRoot, { withFileTypes: true })
|
|
9
9
|
.filter((entry) => entry.isDirectory())
|
|
10
10
|
.map((entry) => path.join(actionsRoot, entry.name, "dist", "index.js"))
|
|
11
11
|
.filter((bundlePath) => {
|
|
@@ -17,6 +17,14 @@ const bundlePaths = readdirSync(actionsRoot, { withFileTypes: true })
|
|
|
17
17
|
}
|
|
18
18
|
})
|
|
19
19
|
.sort();
|
|
20
|
+
const wasmBundlePaths = [
|
|
21
|
+
"promote-buildchain-ref",
|
|
22
|
+
"release-tail",
|
|
23
|
+
"release-candidate-promote",
|
|
24
|
+
].map((name) =>
|
|
25
|
+
path.join(actionsRoot, name, "dist", "buildchain-domain.wasm"),
|
|
26
|
+
);
|
|
27
|
+
const bundlePaths = [...javascriptBundlePaths, ...wasmBundlePaths];
|
|
20
28
|
|
|
21
29
|
const before = new Map(
|
|
22
30
|
bundlePaths.map((bundlePath) => [bundlePath, readFileSync(bundlePath)]),
|
|
@@ -46,4 +54,6 @@ if (changed.length > 0) {
|
|
|
46
54
|
process.exit(1);
|
|
47
55
|
}
|
|
48
56
|
|
|
49
|
-
console.log(
|
|
57
|
+
console.log(
|
|
58
|
+
`action bundle integrity check passed (${bundlePaths.length} bundles)`,
|
|
59
|
+
);
|