@kungfu-tech/buildchain 4.1.0-alpha.0 → 4.1.0-alpha.2
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 +30 -41
- package/CONTRIBUTING.md +6 -7
- package/architecture/action-taxonomy.json +5 -21
- package/architecture/agent-change-map.md +74 -56
- package/architecture/build-orchestration.json +8 -1
- package/architecture/ci-lane-change-budget.json +179 -69
- package/architecture/floating-consumer-policy.json +7 -17
- package/architecture/internal-capabilities.json +58 -72
- package/architecture/maintainability-debt.json +138 -52
- package/architecture/maintainability-policy.json +6 -15
- package/architecture/promotion-job-topology.json +39 -20
- package/architecture/release-topology.json +26 -37
- package/architecture/runtime-entry.json +26 -0
- package/architecture/runtime-resume-lineage.json +23 -0
- package/architecture/stage-capsule-qualification.json +2 -2
- package/architecture/universal-workflow-bootstrap.json +10 -25
- package/architecture/universal-workflow-capability-policy.json +61 -0
- package/architecture/universal-workflow-fault-campaign.json +18 -24
- package/architecture/workflow-taxonomy.json +0 -11
- package/contracts/fixtures/{v4-runtime-ref-resume-authority-v1 → runtime-resume-lineage-v2}/scenario.json +2 -3
- package/contracts/fixtures/v4-floating-consumer-policy-v1/cases.json +2 -2
- package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
- package/contracts/promotion-invocation-v1.schema.json +0 -44
- package/contracts/promotion-request-v1.schema.json +0 -39
- package/contracts/runtime-resume-lineage-v2.schema.json +182 -0
- package/dist/site/buildchain-contract.json +472 -361
- package/dist/site/buildchain-site.json +99 -99
- package/dist/site/capability-registry.json +3 -3
- package/dist/site/cli-registry.json +4 -4
- package/dist/site/controller-registry.json +94 -78
- package/dist/site/kfd-claims.json +224 -343
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +15 -15
- package/dist/site/node-api-registry.json +239 -354
- package/dist/site/page-registry.json +80 -80
- package/dist/site/public-surface-audit.json +203 -254
- package/dist/site/publication-authority-registry.json +1 -24
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +1 -1
- package/dist/site/site-manifest.json +19 -19
- package/dist/site/workflow-registry.json +197 -357
- package/docs/MAP.md +3 -3
- package/docs/auditable-demo.md +4 -4
- package/docs/cli-reference.md +2 -2
- package/docs/code-organization.md +5 -4
- package/docs/controller-evidence.md +2 -2
- package/docs/dev-alpha-candidate-patrol.md +5 -5
- package/docs/dev-delivery-warrant.md +14 -24
- package/docs/engineering-housekeeper.md +3 -3
- package/docs/github-artifact-attestation.md +9 -12
- package/docs/github-governance-authority.md +4 -4
- package/docs/node-api-reference.md +153 -167
- package/docs/publication-artifacts.md +3 -4
- package/docs/publication-authority.md +2 -2
- package/docs/release-candidate.md +21 -27
- package/docs/release-governance.md +10 -10
- package/docs/release-promotion-request.md +11 -18
- package/docs/release-propagation.md +5 -6
- package/docs/release-tail-provider-plane.md +2 -3
- package/docs/reusable-build-surface.md +13 -7
- package/docs/runtime-entry.md +122 -0
- package/docs/runtime-train-validation.md +30 -41
- package/docs/v4-publication-rehearsal.md +5 -5
- package/docs/v4-stage-capsule.md +9 -10
- package/docs/web-surface-deployments.md +16 -20
- package/docs/workflow-catalog.md +0 -1
- package/package.json +6 -6
- package/packages/core/adoption/commands/init-repo.mjs +2 -2
- package/packages/core/adoption/cross-platform-adopter-qualification.js +2 -13
- package/packages/core/adoption/qualification/actions.js +3 -5
- package/packages/core/adoption/qualification/admission.js +2 -3
- package/packages/core/build/artifact/attestation.js +0 -1
- package/packages/core/build/artifact/contracts.js +1 -4
- package/packages/core/build/artifact/store.js +6 -5
- package/packages/core/build/artifact-signing.js +4 -10
- package/packages/core/build/binary/actions.js +15 -9
- package/packages/core/build/binary-publication-dispatch.js +2 -6
- package/packages/core/build/demo/action-context.js +2 -11
- package/packages/core/build/demo/binary-action.js +8 -10
- package/packages/core/build/gate/controller.js +0 -2
- package/packages/core/build/github-attestation/action.js +2 -7
- package/packages/core/build/github-attestation/admission.js +0 -8
- package/packages/core/build/github-attestation/transaction.js +1 -2
- package/packages/core/build/lifecycle/stage-action.js +2 -0
- package/packages/core/build/lifecycle/stage.js +6 -3
- package/packages/core/build/macos-credential-island/dmg-assembly.js +0 -2
- package/packages/core/build/macos-credential-island/lib.js +2 -6
- package/packages/core/build/plan/action-context.js +0 -7
- package/packages/core/build/plan/action.js +7 -11
- package/packages/core/build/plan/admission.js +6 -73
- package/packages/core/build/plan/configuration.js +1 -1
- package/packages/core/build/plan/environment.js +1 -1
- package/packages/core/build/plan/identity.js +1 -5
- package/packages/core/build/plan/resolve.js +7 -1
- package/packages/core/build/recovery/checkpoint.js +158 -0
- package/packages/core/build/recovery/transaction.js +51 -0
- package/packages/core/build/signing/authority-actions.js +2 -11
- package/packages/core/build/signing/control.js +0 -5
- package/packages/core/build/signing/controller-transaction.js +0 -1
- package/packages/core/build/signing/delegation.js +2 -4
- package/packages/core/build/signing/dispatch.js +10 -56
- package/packages/core/build/signing/intake.js +0 -4
- package/packages/core/build/signing/prepare.js +1 -1
- package/packages/core/build/signing/request.js +3 -8
- package/packages/core/build/source/checkout-action.js +6 -10
- package/packages/core/build/source/controller.js +1 -4
- package/packages/core/build/source/lifecycle.js +3 -13
- package/packages/core/build/stage-capsule/actions.js +3 -13
- package/packages/core/build/stage-capsule/campaign/resume.js +10 -5
- package/packages/core/build/stage-capsule/rehearsal/verify.js +3 -4
- package/packages/core/build/stage-capsule-resume-planner.js +0 -1
- package/packages/core/build/summary/aggregation.js +5 -5
- package/packages/core/build/summary/finalization.js +1 -1
- package/packages/core/build/verification/actions.js +3 -12
- package/packages/core/build/verification/runner.js +22 -20
- package/packages/core/consumer/floating-consumer-evidence.js +3 -21
- package/packages/core/consumer/floating-consumer-policy.js +2 -93
- package/packages/core/consumer/floating-consumer-release-passport.js +1 -34
- package/packages/core/consumer/policy-admission.js +1 -3
- package/packages/core/contracts/buildchain-contract.js +12 -146
- package/packages/core/contracts/workflow-yaml-contract.js +11 -1
- package/packages/core/dev-delivery/candidate/admission.js +3 -4
- package/packages/core/dev-delivery/candidate/coordinates.js +0 -8
- package/packages/core/dev-delivery/commands/dev-delivery-request.sh +5 -13
- package/packages/core/dev-delivery/commands/dev-delivery-source-proof-reuse.mjs +0 -3
- package/packages/core/dev-delivery/dev-delivery-contract-surface.js +4 -52
- package/packages/core/dev-delivery/dev-delivery-execution-transfer.js +2 -15
- package/packages/core/dev-delivery/native/action-context.js +4 -32
- package/packages/core/dev-delivery/native/provider-boundary.js +0 -2
- package/packages/core/dev-delivery/native/transactions.js +1 -2
- package/packages/core/dev-delivery/queue/reconciliation-action.js +6 -10
- package/packages/core/dev-delivery/source-proof/predicates.js +0 -6
- package/packages/core/dev-delivery/source-proof/reuse.js +0 -2
- package/packages/core/dev-delivery/source-proof/seal.js +0 -2
- package/packages/core/governance/alpha-candidate/action.js +1 -10
- package/packages/core/governance/audit/actions.js +1 -3
- package/packages/core/governance/audit/collection.js +1 -3
- package/packages/core/governance/audit/identity.js +3 -31
- package/packages/core/governance/audit/transactions.js +2 -4
- package/packages/core/governance/buildchain-publication-authority.js +0 -1
- package/packages/core/governance/commands/audit-github-governance.mjs +3 -2
- package/packages/core/governance/github-governance-authority.js +0 -5
- package/packages/core/governance/receipt-admission.js +0 -15
- package/packages/core/index.js +1 -1
- package/packages/core/observability/controller/identity.js +4 -5
- package/packages/core/observability/controller-evidence.js +5 -10
- package/packages/core/paper/commands/paper.mjs +6 -6
- package/packages/core/paper/operations/plans.js +2 -2
- package/packages/core/paper/operations/provisioning-validation.js +1 -1
- package/packages/core/paper/operations/scaffold-workflows.js +29 -12
- package/packages/core/paper/operations/scaffold.js +97 -69
- package/packages/core/paper/paper-agent-entry.js +0 -11
- package/packages/core/paper/paper-runtime-channels.js +21 -66
- package/packages/core/paper/paper-scaffold-content.js +1 -1
- package/packages/core/paper/paper.js +9 -5
- package/packages/core/paper/publication/candidate.js +0 -9
- package/packages/core/paper/publication-controller.js +2 -4
- package/packages/core/providers/github/artifact-attestation.js +1 -1
- package/packages/core/publication/authority/actions.js +9 -8
- package/packages/core/publication/authority/admission.js +0 -11
- package/packages/core/publication/authority/assembly.js +2 -7
- package/packages/core/publication/authority/control-plane.js +2 -2
- package/packages/core/publication/authority/governance.js +2 -9
- package/packages/core/publication/authority/request.js +7 -2
- package/packages/core/publication/authority/verification.js +3 -18
- package/packages/core/publication/binary/action.js +5 -7
- package/packages/core/publication/candidate/qualification-action.js +1 -6
- package/packages/core/publication/candidate/stage-capsules.js +1 -1
- package/packages/core/publication/npm/preview-action.js +9 -15
- package/packages/core/publication/oci/preview-actions.js +1 -10
- package/packages/core/publication/publication-artifact-candidate.js +2 -2
- package/packages/core/publication/publication-authority.js +2 -2
- package/packages/core/publication/publication-rehearsal-projection.js +3 -3
- package/packages/core/publication/settlement/actions.js +2 -11
- package/packages/core/release/binary/coordinates-action.js +0 -13
- package/packages/core/release/binary/coordinates.js +2 -19
- package/packages/core/release/commands/promotion-channel-router.mjs +12 -56
- package/packages/core/release/commands/resume-from-candidate-run.mjs +2 -3
- package/packages/core/release/dev-alpha-active-release-train.js +0 -5
- package/packages/core/release/line/action.js +2 -13
- package/packages/core/release/next-development/actions.js +2 -5
- package/packages/core/release/passport/consumer-validation.js +1 -28
- package/packages/core/release/promote-candidate/development-source.js +7 -8
- package/packages/core/release/promotion/actions.js +7 -38
- package/packages/core/release/promotion/admission.js +3 -50
- package/packages/core/release/promotion/candidate.js +2 -4
- package/packages/core/release/promotion/channel.js +13 -101
- package/packages/core/release/promotion/qualification-action.js +2 -13
- package/packages/core/release/promotion/routing.js +16 -81
- package/packages/core/release/promotion/selection.js +1 -9
- package/packages/core/release/promotion-request.js +1 -40
- package/packages/core/release/qualification/actions.js +0 -8
- package/packages/core/release/qualification/public-build.js +1 -1
- package/packages/core/release/recovery/candidate.js +15 -21
- package/packages/core/release/recovery/capsules.js +2 -10
- package/packages/core/release/recovery/lineage.js +305 -0
- package/packages/core/release/recovery/provenance.js +1 -2
- package/packages/core/release/recovery/publication.js +4 -14
- package/packages/core/release/recovery/readback.js +19 -32
- package/packages/core/release/recovery/runtime.js +4 -95
- package/packages/core/release/release-candidate-recovery.js +4 -9
- package/packages/core/release/release-candidate.js +2 -5
- package/packages/core/release/reseal/actions.js +3 -22
- package/packages/core/release/reseal/admission.js +0 -2
- package/packages/core/release/reseal/finalize-platform.js +0 -2
- package/packages/core/release/tail-reseal-github.js +1 -2
- package/packages/core/release/tail-reseal-receipt.js +0 -1
- package/packages/core/release/tail-reseal.js +2 -20
- package/packages/core/release/version-state.js +16 -13
- package/packages/core/runtime/buildchain-domain.wasm +0 -0
- package/packages/core/runtime/checkout-identity.js +0 -13
- package/packages/core/runtime/domain-wasm-artifact.js +2 -2
- package/packages/core/runtime/entry/actions.js +121 -0
- package/packages/core/runtime/entry/activation.js +86 -0
- package/packages/core/runtime/entry/github.js +55 -0
- package/packages/core/runtime/entry/recovery.js +37 -0
- package/packages/core/runtime/entry/selection.js +110 -0
- package/packages/core/web/controller.js +1 -1
- package/packages/core/web/publication-admission-action.js +1 -8
- package/packages/core/web/web-surface-publication-candidate.js +2 -5
- package/packages/core/workflow/admission/actions.js +6 -26
- package/packages/core/workflow/admission/recovery.js +3 -43
- package/packages/core/workflow/admission/transactions.js +8 -24
- package/packages/core/workflow/commands/buildchain-cli-help.mjs +1 -1
- package/packages/core/workflow/commands/universal-workflow-engine.mjs +2 -7
- package/packages/core/workflow/dogfood/actions.js +0 -17
- package/packages/core/workflow/engine/action.js +0 -5
- package/packages/core/workflow/engine/conformance.js +1 -1
- package/packages/core/workflow/engine/execution.js +2 -6
- package/packages/core/workflow/engine/identity.js +1 -6
- package/packages/core/workflow/engine/release-environment.js +11 -35
- package/packages/core/workflow/engine/release-promotion.js +2 -2
- package/packages/core/workflow/settlement/actions.js +0 -12
- package/packages/core/workflow/universal-self-dogfood.js +2 -16
- package/packages/core/workflow/universal-workflow-bootstrap.js +16 -241
- package/packages/core/workflow/workflow-taxonomy.mjs +2 -2
- package/scripts/check-dev-delivery-actions.mjs +17 -8
- package/scripts/check-floating-consumer-policy-contract.mjs +6 -6
- package/scripts/check-inventory.mjs +1 -10
- package/scripts/check-public-dogfood-contract.mjs +34 -21
- package/scripts/check-release-topology.mjs +2 -6
- package/scripts/check-runtime-entry.mjs +133 -0
- package/scripts/check-universal-workflow-bootstrap.mjs +45 -281
- package/scripts/check-workflows.sh +0 -7
- package/scripts/generate-bootstrap-admission.mjs +1 -1
- package/scripts/generate-channel-promotion-workflow.mjs +4 -4
- package/scripts/inventory/binary.mjs +4 -4
- package/scripts/inventory/promotion.mjs +5 -3
- package/scripts/runtime-source-boundaries.mjs +70 -0
- package/scripts/site-capability-metadata.mjs +2 -2
- package/scripts/workflow-action-graph.mjs +5 -18
- package/scripts/workflow-self-reference.mjs +20 -0
- package/templates/native-dev-delivery.yml +4 -4
- package/templates/universal-buildchain-bootstrap.yml +12 -2
- package/architecture/runtime-ref-resume-authority.json +0 -64
- package/architecture/universal-workflow-train-admission.json +0 -76
- package/contracts/v4-runtime-ref-resume-authority-v1.schema.json +0 -235
- package/docs/v4-runtime-ref-resume-authority.md +0 -69
- package/packages/core/consumer/channel-selection.js +0 -211
- package/packages/core/consumer/commands/buildchain-channel-router.mjs +0 -81
- package/packages/core/consumer/invocation-selector.js +0 -4
- package/packages/core/consumer/runtime-ref-resume-authority.js +0 -621
- package/packages/core/consumer/workflow-definition-authority.js +0 -64
- package/packages/core/contracts/runtime-contract-action.js +0 -48
- package/packages/core/release/commands/promotion-identity-resolver.mjs +0 -77
- package/packages/core/release/commands/verify-promotion-router-binding.sh +0 -36
- package/packages/core/release/promotion/identities.js +0 -56
- package/packages/core/release/runtime-override-authorization.js +0 -242
- package/packages/core/runtime/commands/runtime-ref-core.mjs +0 -171
- package/packages/core/runtime/provider-closure.js +0 -60
- package/packages/core/runtime/runtime-selection-action.js +0 -34
- package/packages/core/runtime/runtime-selection.js +0 -136
- package/packages/core/runtime/workflow-runtime.js +0 -11
- package/packages/core/workflow/admission/review.js +0 -188
- package/packages/core/workflow/commands/universal-workflow-backflow.mjs +0 -26
- package/packages/core/workflow/installation.js +0 -33
- package/packages/core/workflow/settlement/backflow.js +0 -187
- package/scripts/generate-bootstrap-recovery.mjs +0 -94
- package/templates/bootstrap-recovery/actions/build/source/admit/action.yml +0 -17
- package/templates/bootstrap-recovery/actions/build/source/admit/dist/index.js +0 -63
- package/templates/bootstrap-recovery/actions/runtime/dependencies/install/action.yml +0 -18
- package/templates/bootstrap-recovery/actions/runtime/dependencies/install/dist/index.js +0 -63
- package/templates/bootstrap-recovery/actions/runtime/environment/prepare/action.yml +0 -21
- package/templates/bootstrap-recovery/actions/workflow/admission/inspect/action.yml +0 -27
- package/templates/bootstrap-recovery/actions/workflow/admission/inspect/dist/index.js +0 -64
- package/templates/bootstrap-recovery/actions/workflow/admission/review/action.yml +0 -15
- package/templates/bootstrap-recovery/actions/workflow/admission/review/dist/index.js +0 -65
- package/templates/bootstrap-recovery/actions/workflow/recovery/admit/action.yml +0 -47
- package/templates/bootstrap-recovery/actions/workflow/recovery/execute/action.yml +0 -48
- package/templates/bootstrap-recovery/actions/workflow/recovery/settle/action.yml +0 -54
- package/templates/bootstrap-recovery/actions/workflow/settlement/seal/action.yml +0 -17
- package/templates/bootstrap-recovery/actions/workflow/settlement/seal/dist/index.js +0 -65
- package/templates/bootstrap-recovery/manifest.json +0 -68
- package/templates/bootstrap-recovery/package.json +0 -9
- package/templates/universal-buildchain-bootstrap-recovery.yml +0 -115
|
@@ -3,65 +3,17 @@ export function devDeliveryWorkflowContractSurface(pkg, majorLine) {
|
|
|
3
3
|
id: "dev-pr-auto-merge",
|
|
4
4
|
kind: "workflow",
|
|
5
5
|
path: ".github/workflows/public-ops-dev-auto-merge.yml",
|
|
6
|
-
publicRef: `${pkg.repository ? "kungfu-systems/buildchain" : "buildchain"}/.github/workflows/public-ops-dev-auto-merge.yml@${majorLine}
|
|
7
|
-
requiredInputs: [
|
|
8
|
-
"target-branch",
|
|
9
|
-
"expected-pr-number",
|
|
10
|
-
"expected-head-sha",
|
|
11
|
-
],
|
|
12
|
-
requiredOutputs: [
|
|
13
|
-
"admission-receipt-root",
|
|
14
|
-
"warrant-state-root",
|
|
15
|
-
"provider-heartbeat-receipt-root",
|
|
16
|
-
"provider-finalizer-boundary-root",
|
|
17
|
-
],
|
|
6
|
+
publicRef: `${pkg.repository ? "kungfu-systems/buildchain" : "buildchain"}/.github/workflows/public-ops-dev-auto-merge.yml@${majorLine}`,
|
|
18
7
|
breakingDefaults: {
|
|
19
|
-
runtimeSelectorDefault:
|
|
8
|
+
runtimeSelectorDefault: "consumer-contract-lock-or-entry",
|
|
20
9
|
authorityMode: "two-phase-delivery-warrant",
|
|
21
10
|
boundedAuthorityWorkflowIntegration: "not-advertised",
|
|
22
11
|
boundedAuthoritySupportedSurfaces: ["cli", "node-api", "schema"],
|
|
23
|
-
publicFloatingCaller:
|
|
24
|
-
durableSelfDeliveryRef:
|
|
12
|
+
publicFloatingCaller: majorLine,
|
|
13
|
+
durableSelfDeliveryRef: majorLine,
|
|
25
14
|
independentHeartbeatRunner: "macos-15",
|
|
26
15
|
candidateCredentialAccess: "forbidden",
|
|
27
16
|
},
|
|
28
|
-
optionalInputs: [
|
|
29
|
-
"buildchain-repository",
|
|
30
|
-
"buildchain-ref",
|
|
31
|
-
"source-workflow-run-id",
|
|
32
|
-
"delivery-warrant-mode",
|
|
33
|
-
"handoff-workflow-id",
|
|
34
|
-
"assignment-root",
|
|
35
|
-
"initiative-root",
|
|
36
|
-
"source-identity-root",
|
|
37
|
-
"source-patch-root",
|
|
38
|
-
"plan-root",
|
|
39
|
-
"closure-root",
|
|
40
|
-
"dependency-root",
|
|
41
|
-
"toolchain-root",
|
|
42
|
-
"environment-root",
|
|
43
|
-
"affected-paths-json",
|
|
44
|
-
"shard-evidence-roots-json",
|
|
45
|
-
"release-blocker-priority-json",
|
|
46
|
-
"native-proof-json",
|
|
47
|
-
"native-command",
|
|
48
|
-
"native-command-root",
|
|
49
|
-
"native-heartbeat-seconds",
|
|
50
|
-
"delivery-class",
|
|
51
|
-
"delivery-priority",
|
|
52
|
-
"required-status-checks",
|
|
53
|
-
"queue-admission-context",
|
|
54
|
-
"active-lease-context",
|
|
55
|
-
"ready-label",
|
|
56
|
-
"block-labels",
|
|
57
|
-
"allowed-head-prefixes",
|
|
58
|
-
"require-approval",
|
|
59
|
-
"same-repository-only",
|
|
60
|
-
"max-merges",
|
|
61
|
-
"merge-method",
|
|
62
|
-
"landing-mode",
|
|
63
|
-
"dry-run",
|
|
64
|
-
],
|
|
65
17
|
guarantees: [
|
|
66
18
|
"this reusable workflow executes the single-flight v1 Delivery Warrant and does not advertise bounded v2 Landing integration",
|
|
67
19
|
"bounded v2 authority is a separate opt-in CLI, Node API, and schema surface whose controller deployment must be explicit",
|
|
@@ -37,12 +37,6 @@ const FAILURE_FILES = [
|
|
|
37
37
|
"warrant.json",
|
|
38
38
|
];
|
|
39
39
|
|
|
40
|
-
const DOMAIN_RUNTIME_SELECTOR =
|
|
41
|
-
/^(?:[0-9a-f]{40}|v4|v4-alpha|train\/v4\/v4\.0\/[a-z0-9][a-z0-9._-]*)$/u;
|
|
42
|
-
|
|
43
|
-
const RUNTIME_SELECTOR_DESCRIPTION =
|
|
44
|
-
"runtime selector must be an exact immutable SHA, v4, v4-alpha, or train/v4/v4.0/<capability>";
|
|
45
|
-
|
|
46
40
|
function requiredFiles(outcome) {
|
|
47
41
|
if (outcome === "succeeded") return SUCCESS_FILES;
|
|
48
42
|
if (outcome === "failed") return FAILURE_FILES;
|
|
@@ -162,12 +156,9 @@ function runtimeBinding(input = {}) {
|
|
|
162
156
|
const runtime = {
|
|
163
157
|
repository: repository(input.repository),
|
|
164
158
|
selector: text(input.selector, "runtime selector"),
|
|
165
|
-
resolvedSha:
|
|
159
|
+
resolvedSha: input.resolvedSha,
|
|
166
160
|
selectionRoot: exactRoot(input.selectionRoot, "runtime selection root"),
|
|
167
161
|
};
|
|
168
|
-
if (!DOMAIN_RUNTIME_SELECTOR.test(runtime.selector)) {
|
|
169
|
-
throw new Error(RUNTIME_SELECTOR_DESCRIPTION);
|
|
170
|
-
}
|
|
171
162
|
return runtime;
|
|
172
163
|
}
|
|
173
164
|
|
|
@@ -202,14 +193,11 @@ function verifiedRuntimeSelection(directory, expected = {}) {
|
|
|
202
193
|
schema: "kungfu.buildchain.dev-delivery-runtime-selection/v1",
|
|
203
194
|
repository: repository(selection.repository),
|
|
204
195
|
selector: text(selection.selector, "runtime selector"),
|
|
205
|
-
resolvedSha:
|
|
196
|
+
resolvedSha: selection.resolvedSha,
|
|
206
197
|
};
|
|
207
198
|
if (JSON.stringify(selection) !== JSON.stringify(normalized)) {
|
|
208
199
|
throw new Error("runtime selection is not exact canonical content");
|
|
209
200
|
}
|
|
210
|
-
if (!DOMAIN_RUNTIME_SELECTOR.test(normalized.selector)) {
|
|
211
|
-
throw new Error(RUNTIME_SELECTOR_DESCRIPTION);
|
|
212
|
-
}
|
|
213
201
|
const selectionRoot = sha256Bytes(
|
|
214
202
|
Buffer.from(`${JSON.stringify(normalized, null, 2)}\n`),
|
|
215
203
|
);
|
|
@@ -552,7 +540,6 @@ export function verifyNativeExecutionTransfer(
|
|
|
552
540
|
const runtime = verifiedRuntimeSelection(directory, {
|
|
553
541
|
repository: transfer.runtime.repository,
|
|
554
542
|
selector: transfer.runtime.selector,
|
|
555
|
-
resolvedSha: transfer.runtime.resolvedSha,
|
|
556
543
|
selectionRoot: transfer.runtime.selectionRoot,
|
|
557
544
|
});
|
|
558
545
|
const warrant = warrantEvidence(directory, transfer);
|
|
@@ -1,24 +1,12 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { command } from "../../runtime/action-process.mjs";
|
|
3
2
|
import { installationRoot } from "../../runtime/installation-root.js";
|
|
4
3
|
export function deliveryActionContext(core, env) {
|
|
5
4
|
const runtimeRoot = installationRoot(import.meta.url);
|
|
6
|
-
const expectedSha = core.getInput("runtime-sha", { required: true });
|
|
7
|
-
if (
|
|
8
|
-
!/^[a-f0-9]{40}$/u.test(expectedSha) ||
|
|
9
|
-
command(
|
|
10
|
-
"git",
|
|
11
|
-
["-C", runtimeRoot, "rev-parse", "--verify", "HEAD^{commit}"],
|
|
12
|
-
{ stdio: "pipe" },
|
|
13
|
-
).trim() !== expectedSha
|
|
14
|
-
)
|
|
15
|
-
throw new Error(
|
|
16
|
-
"Delivery action runtime differs from admitted immutable commit",
|
|
17
|
-
);
|
|
18
5
|
return {
|
|
19
6
|
workspace: path.resolve(env.GITHUB_WORKSPACE),
|
|
20
7
|
runtimeRoot,
|
|
21
|
-
runtimeSha:
|
|
8
|
+
runtimeSha: env.BUILDCHAIN_RUNTIME_SHA,
|
|
9
|
+
runtimeRef: env.BUILDCHAIN_RUNTIME_REF,
|
|
22
10
|
run: {
|
|
23
11
|
id: Number(env.GITHUB_RUN_ID),
|
|
24
12
|
attempt: Number(env.GITHUB_RUN_ATTEMPT),
|
|
@@ -34,26 +22,10 @@ export function deliveryActionContext(core, env) {
|
|
|
34
22
|
|
|
35
23
|
export function selectedDeliveryActionContext(core, env) {
|
|
36
24
|
const runtimeRoot = installationRoot(import.meta.url);
|
|
37
|
-
const selector = core.getInput("runtime-ref", { required: true });
|
|
38
|
-
if (
|
|
39
|
-
!/^(?:v4(?:-alpha)?|[0-9a-f]{40}|train\/v4\/v4\.\d+\/[a-z0-9][a-z0-9._-]*)$/u.test(
|
|
40
|
-
selector,
|
|
41
|
-
)
|
|
42
|
-
)
|
|
43
|
-
throw new Error("Unsupported delivery runtime selector");
|
|
44
|
-
const runtimeSha = command(
|
|
45
|
-
"git",
|
|
46
|
-
["-C", runtimeRoot, "rev-parse", "--verify", "HEAD^{commit}"],
|
|
47
|
-
{ stdio: "pipe" },
|
|
48
|
-
).trim();
|
|
49
|
-
if (
|
|
50
|
-
!/^[0-9a-f]{40}$/u.test(runtimeSha) ||
|
|
51
|
-
(/^[0-9a-f]{40}$/u.test(selector) && selector !== runtimeSha)
|
|
52
|
-
)
|
|
53
|
-
throw new Error("Delivery runtime differs from immutable selector");
|
|
54
25
|
return {
|
|
55
26
|
workspace: path.resolve(env.GITHUB_WORKSPACE),
|
|
56
27
|
runtimeRoot,
|
|
57
|
-
runtimeSha,
|
|
28
|
+
runtimeSha: env.BUILDCHAIN_RUNTIME_SHA,
|
|
29
|
+
runtimeRef: env.BUILDCHAIN_RUNTIME_REF,
|
|
58
30
|
};
|
|
59
31
|
}
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
import { readJson, writeJson } from "./files.js";
|
|
8
8
|
export function verifyNativeProviderBoundary({
|
|
9
9
|
directory: directoryInput,
|
|
10
|
-
runtimeSha,
|
|
11
10
|
runtimeSelectionRoot,
|
|
12
11
|
pullRequestNumber,
|
|
13
12
|
sourceHead,
|
|
@@ -35,7 +34,6 @@ export function verifyNativeProviderBoundary({
|
|
|
35
34
|
"producer.workflowRunId": run.id,
|
|
36
35
|
"producer.workflowRunAttempt": run.attempt,
|
|
37
36
|
"producer.job": nativeJob,
|
|
38
|
-
"runtime.resolvedSha": runtimeSha,
|
|
39
37
|
"runtime.selectionRoot": runtimeSelectionRoot,
|
|
40
38
|
"warrant.pullRequestNumber": pullRequestNumber,
|
|
41
39
|
"warrant.sourceHead": sourceHead,
|
|
@@ -34,9 +34,8 @@ export function verifyAdmittedRuntimeSelection(
|
|
|
34
34
|
const bytes = fs.readFileSync(file);
|
|
35
35
|
const selection = JSON.parse(bytes);
|
|
36
36
|
if (
|
|
37
|
-
selection.resolvedSha !== runtimeSha ||
|
|
38
37
|
`sha256:${crypto.createHash("sha256").update(bytes).digest("hex")}` !==
|
|
39
|
-
|
|
38
|
+
runtimeSelectionRoot
|
|
40
39
|
)
|
|
41
40
|
throw new Error("Rooted runtime selection differs from admission");
|
|
42
41
|
return selection;
|
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { installationRoot } from "../../runtime/installation-root.js";
|
|
4
3
|
import { GitHubTwoPhaseClient } from "../../providers/dev-delivery/candidate.js";
|
|
5
4
|
import { reconcileConfiguredDevMergeQueue } from "../merge-queue-policy.js";
|
|
6
|
-
export async function reconcileMergeQueueAction(
|
|
5
|
+
export async function reconcileMergeQueueAction(
|
|
6
|
+
core,
|
|
7
|
+
env,
|
|
8
|
+
{ reconcile = reconcileConfiguredDevMergeQueue } = {},
|
|
9
|
+
) {
|
|
7
10
|
const workspace = path.resolve(env.GITHUB_WORKSPACE);
|
|
8
|
-
if (
|
|
9
|
-
fs.realpathSync(installationRoot(import.meta.url)) !==
|
|
10
|
-
fs.realpathSync(workspace)
|
|
11
|
-
)
|
|
12
|
-
throw new Error(
|
|
13
|
-
"Merge queue policy must use the checked-out governed source implementation",
|
|
14
|
-
);
|
|
15
11
|
const branch = core.getInput("branch", { required: true });
|
|
16
12
|
const provider = new GitHubTwoPhaseClient({
|
|
17
13
|
repository: env.GITHUB_REPOSITORY,
|
|
18
14
|
token: core.getInput("token", { required: true }),
|
|
19
15
|
apiUrl: env.GITHUB_API_URL || "https://api.github.com",
|
|
20
16
|
});
|
|
21
|
-
const facts = await
|
|
17
|
+
const facts = await reconcile({
|
|
22
18
|
api: {
|
|
23
19
|
request: (method, endpoint, body) =>
|
|
24
20
|
provider.request(`/${endpoint}`, { method, body }),
|
|
@@ -27,9 +27,6 @@ export function sourceQualificationPredicates(input = {}) {
|
|
|
27
27
|
.map((entry) => entry.trim())
|
|
28
28
|
.filter(Boolean)
|
|
29
29
|
.sort();
|
|
30
|
-
const runtimeRef = required(input.runtimeRef, "runtimeRef");
|
|
31
|
-
const runtimeSha = exactSha(input.runtimeSha, "runtimeSha");
|
|
32
|
-
const contractDigest = required(input.contractDigest, "contractDigest");
|
|
33
30
|
const nodeVersion = required(input.nodeVersion, "nodeVersion");
|
|
34
31
|
return {
|
|
35
32
|
repository,
|
|
@@ -73,9 +70,6 @@ export function sourceQualificationPredicates(input = {}) {
|
|
|
73
70
|
),
|
|
74
71
|
toolchainRoot: devDeliveryContentRoot({
|
|
75
72
|
schema: "kungfu.buildchain.source-toolchain/v1",
|
|
76
|
-
runtimeRef,
|
|
77
|
-
runtimeSha,
|
|
78
|
-
contractDigest,
|
|
79
73
|
nodeVersion,
|
|
80
74
|
}),
|
|
81
75
|
policyRoot: gitPathRoot(sourceHead, policyPaths, "source-policy", cwd),
|
|
@@ -18,11 +18,9 @@ export function verifySourceQualificationReuse(input = {}) {
|
|
|
18
18
|
const proof = readJson(input.sourceProofPath, "source proof");
|
|
19
19
|
const receipt = readJson(input.controllerReceiptPath, "controller receipt");
|
|
20
20
|
const expectedSourceSha = exactSha(input.sourceHead, "sourceHead");
|
|
21
|
-
const expectedRuntimeSha = exactSha(input.runtimeSha, "runtimeSha");
|
|
22
21
|
const expectedRepository = required(input.repository, "repository");
|
|
23
22
|
const receiptValidation = validateControllerReceipt(receipt, {
|
|
24
23
|
expectedSourceSha,
|
|
25
|
-
expectedRuntimeSha,
|
|
26
24
|
});
|
|
27
25
|
if (
|
|
28
26
|
!receiptValidation.ok ||
|
|
@@ -5,11 +5,9 @@ import { readJson, exactSha, required } from "./io.js";
|
|
|
5
5
|
export function sealSourceQualificationProof(input = {}) {
|
|
6
6
|
const receipt = readJson(input.controllerReceiptPath, "controller receipt");
|
|
7
7
|
const expectedSourceSha = exactSha(input.sourceHead, "sourceHead");
|
|
8
|
-
const expectedRuntimeSha = exactSha(input.runtimeSha, "runtimeSha");
|
|
9
8
|
const expectedRepository = required(input.repository, "repository");
|
|
10
9
|
const validation = validateControllerReceipt(receipt, {
|
|
11
10
|
expectedSourceSha,
|
|
12
|
-
expectedRuntimeSha,
|
|
13
11
|
});
|
|
14
12
|
if (
|
|
15
13
|
!validation.ok ||
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { command } from "../../runtime/action-process.mjs";
|
|
4
3
|
import { installationRoot } from "../../runtime/installation-root.js";
|
|
5
4
|
import { normalizeDevAlphaPatrolOptions } from "./options.js";
|
|
6
5
|
import { runDevAlphaCandidatePatrol } from "./controller.js";
|
|
@@ -20,15 +19,7 @@ export async function reconcileAlphaCandidateAction(core, env) {
|
|
|
20
19
|
const prior = settle
|
|
21
20
|
? JSON.parse(core.getInput("observation-json", { required: true }))
|
|
22
21
|
: {};
|
|
23
|
-
const runtimeSha =
|
|
24
|
-
"git",
|
|
25
|
-
["-C", installationRoot(import.meta.url), "rev-parse", "HEAD"],
|
|
26
|
-
{ stdio: "pipe" },
|
|
27
|
-
).trim();
|
|
28
|
-
if (settle && prior["runtime-sha"] !== runtimeSha)
|
|
29
|
-
throw new Error(
|
|
30
|
-
"Alpha settlement runtime differs from exact observation runtime",
|
|
31
|
-
);
|
|
22
|
+
const runtimeSha = env.BUILDCHAIN_RUNTIME_SHA;
|
|
32
23
|
if (
|
|
33
24
|
settle &&
|
|
34
25
|
[
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { getOctokit } from "@actions/github";
|
|
4
|
-
import { installationRoot } from "../../runtime/installation-root.js";
|
|
5
4
|
import {
|
|
6
5
|
collectGovernanceEvidence,
|
|
7
6
|
finalizeGovernanceEvidence,
|
|
@@ -17,8 +16,7 @@ export function collectGovernanceEvidenceAction(core, env) {
|
|
|
17
16
|
repository: scoped ? env.GITHUB_REPOSITORY : "",
|
|
18
17
|
targetRef:
|
|
19
18
|
event.pull_request?.base?.ref || event.merge_group?.base_ref || "",
|
|
20
|
-
|
|
21
|
-
runtimeRoot: installationRoot(import.meta.url),
|
|
19
|
+
runtimeSha: env.BUILDCHAIN_RUNTIME_SHA,
|
|
22
20
|
workspace: env.GITHUB_WORKSPACE,
|
|
23
21
|
token: core.getInput("token", { required: true }),
|
|
24
22
|
});
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
import { createGovernanceReader } from "./github-reader.js";
|
|
11
11
|
import {
|
|
12
12
|
normalizeMembership,
|
|
13
|
-
resolveVerifierSourceRevision,
|
|
14
13
|
addMinutes,
|
|
15
14
|
repositoryVisibility,
|
|
16
15
|
selectGithubGovernanceRepositories,
|
|
@@ -119,7 +118,6 @@ export function collectGithubGovernanceAudit({
|
|
|
119
118
|
observedAt = new Date().toISOString(),
|
|
120
119
|
ttlMinutes = 15,
|
|
121
120
|
verifierSourceRevision = "",
|
|
122
|
-
root,
|
|
123
121
|
token,
|
|
124
122
|
api,
|
|
125
123
|
} = {}) {
|
|
@@ -157,7 +155,7 @@ export function collectGithubGovernanceAudit({
|
|
|
157
155
|
if (targetRef && selected.length !== 1) {
|
|
158
156
|
throw new Error("--target-ref requires exactly one selected repository");
|
|
159
157
|
}
|
|
160
|
-
const revision =
|
|
158
|
+
const revision = verifierSourceRevision;
|
|
161
159
|
const verifier = {
|
|
162
160
|
runtime: `node-${process.version}`,
|
|
163
161
|
sourceRevision: revision,
|
|
@@ -12,41 +12,13 @@ export function normalizeMembership(result) {
|
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export function
|
|
16
|
-
root,
|
|
17
|
-
requested = "",
|
|
18
|
-
run = spawnSync,
|
|
19
|
-
) {
|
|
15
|
+
export function readVerifierSourceRevision(root, run = spawnSync) {
|
|
20
16
|
const result = run("git", ["-C", root, "rev-parse", "HEAD"], {
|
|
21
17
|
encoding: "utf8",
|
|
22
18
|
timeout: 10_000,
|
|
23
19
|
});
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
throw new Error("verifier source revision is unavailable");
|
|
27
|
-
}
|
|
28
|
-
const cleanliness = run(
|
|
29
|
-
"git",
|
|
30
|
-
["-C", root, "diff", "--quiet", "HEAD", "--"],
|
|
31
|
-
{
|
|
32
|
-
encoding: "utf8",
|
|
33
|
-
timeout: 10_000,
|
|
34
|
-
},
|
|
35
|
-
);
|
|
36
|
-
if (cleanliness.status !== 0) {
|
|
37
|
-
throw new Error("verifier checkout contains tracked drift");
|
|
38
|
-
}
|
|
39
|
-
const normalized = revision.toLowerCase();
|
|
40
|
-
if (
|
|
41
|
-
requested &&
|
|
42
|
-
(!/^[0-9a-f]{40}$/i.test(requested) ||
|
|
43
|
-
requested.toLowerCase() !== normalized)
|
|
44
|
-
) {
|
|
45
|
-
throw new Error(
|
|
46
|
-
"requested verifier source revision does not match the current checkout",
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
return normalized;
|
|
20
|
+
if (result.status !== 0) throw new Error("verifier source provenance is unavailable");
|
|
21
|
+
return String(result.stdout || "").trim();
|
|
50
22
|
}
|
|
51
23
|
|
|
52
24
|
export function addMinutes(iso, minutes) {
|
|
@@ -8,8 +8,7 @@ export function collectGovernanceEvidence(
|
|
|
8
8
|
organization,
|
|
9
9
|
repository,
|
|
10
10
|
targetRef,
|
|
11
|
-
|
|
12
|
-
runtimeRoot,
|
|
11
|
+
runtimeSha,
|
|
13
12
|
workspace,
|
|
14
13
|
token,
|
|
15
14
|
},
|
|
@@ -19,8 +18,7 @@ export function collectGovernanceEvidence(
|
|
|
19
18
|
organization,
|
|
20
19
|
repository,
|
|
21
20
|
targetRef,
|
|
22
|
-
verifierSourceRevision:
|
|
23
|
-
root: runtimeRoot,
|
|
21
|
+
verifierSourceRevision: runtimeSha,
|
|
24
22
|
token,
|
|
25
23
|
});
|
|
26
24
|
const { qualifyingCount, nonQualifyingCount } = result.inventory;
|
|
@@ -58,7 +58,6 @@ const DESCRIPTORS = Object.freeze([
|
|
|
58
58
|
[".github/workflows/public-release-tail.yml", "product-publication", true, ["artifact.publish", "signed-channel.commit", "release.activate", "released-evidence.synthesize"], "caller-secrets", "caller-bound", "caller-bound", "fixed"],
|
|
59
59
|
[".github/workflows/self-build-release-verify-compat.yml", "governance-write"],
|
|
60
60
|
[".github/workflows/public-ops-stable-candidate-patrol.yml", "governance-write"],
|
|
61
|
-
[".github/workflows/public-ops-bootstrap-recovery.yml", "product-publication", true, ["universal-candidate-execution"], "caller-secrets", "none", "fixed", "caller-bound"],
|
|
62
61
|
[".github/workflows/self-ops-bootstrap-dogfood.yml", "product-publication", true, ["universal-candidate-execution"], "caller-secrets", "none", "fixed", "caller-bound"],
|
|
63
62
|
[".github/workflows/self-release-tail-dogfood.yml", "product-publication", true, ["artifact.publish", "signed-channel.commit", "release.activate", "released-evidence.synthesize"], "caller-secrets", "none", "fixed", "fixed"],
|
|
64
63
|
]);
|
|
@@ -5,6 +5,7 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
import { installationRoot } from "../../runtime/installation-root.js";
|
|
6
6
|
import { BUILDCHAIN_GITHUB_GOVERNANCE_AUTHORITY } from "../github-governance-authority.js";
|
|
7
7
|
import { collectGithubGovernanceAudit } from "../audit/collection.js";
|
|
8
|
+
import { readVerifierSourceRevision } from "../audit/identity.js";
|
|
8
9
|
function flag(args, name, fallback = "") {
|
|
9
10
|
const index = args.indexOf(`--${name}`);
|
|
10
11
|
return index === -1 ? fallback : String(args[index + 1] || "");
|
|
@@ -16,13 +17,13 @@ function hasFlag(args, name) {
|
|
|
16
17
|
|
|
17
18
|
function main(args = process.argv.slice(2)) {
|
|
18
19
|
const result = collectGithubGovernanceAudit({
|
|
19
|
-
|
|
20
|
+
token: process.env.GH_TOKEN || process.env.GITHUB_TOKEN,
|
|
20
21
|
organization: flag(args, "organization", BUILDCHAIN_GITHUB_GOVERNANCE_AUTHORITY.organization),
|
|
21
22
|
repository: flag(args, "repository"),
|
|
22
23
|
targetRef: flag(args, "target-ref"),
|
|
23
24
|
observedAt: flag(args, "observed-at", new Date().toISOString()),
|
|
24
25
|
ttlMinutes: Number(flag(args, "ttl-minutes", "15")),
|
|
25
|
-
verifierSourceRevision:
|
|
26
|
+
verifierSourceRevision: process.env.BUILDCHAIN_RUNTIME_SHA || readVerifierSourceRevision(installationRoot(import.meta.url)),
|
|
26
27
|
});
|
|
27
28
|
const output = flag(args, "output");
|
|
28
29
|
const serialized = `${JSON.stringify(result, null, 2)}\n`;
|
|
@@ -888,7 +888,6 @@ export function verifyGithubGovernanceReceipt(receipt, {
|
|
|
888
888
|
expectedRepositoryIdentityRoot,
|
|
889
889
|
expectedTargetRef,
|
|
890
890
|
expectedPolicyRoot,
|
|
891
|
-
expectedVerifierSourceRevision,
|
|
892
891
|
now = new Date().toISOString(),
|
|
893
892
|
} = {}) {
|
|
894
893
|
if (receipt?.contract !== GITHUB_GOVERNANCE_RECEIPT_CONTRACT) {
|
|
@@ -917,10 +916,6 @@ export function verifyGithubGovernanceReceipt(receipt, {
|
|
|
917
916
|
if (expectedPolicyRoot && receipt.policyRoot !== expectedPolicyRoot) {
|
|
918
917
|
throw new Error("GitHub governance receipt policy root mismatch");
|
|
919
918
|
}
|
|
920
|
-
if (expectedVerifierSourceRevision &&
|
|
921
|
-
receipt.verifier?.sourceRevision !== expectedVerifierSourceRevision) {
|
|
922
|
-
throw new Error("GitHub governance receipt verifier source revision mismatch");
|
|
923
|
-
}
|
|
924
919
|
const observed = Date.parse(receipt.observedAt);
|
|
925
920
|
const expires = Date.parse(receipt.expiresAt);
|
|
926
921
|
const instant = Date.parse(now);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { command } from "../runtime/action-process.mjs";
|
|
2
1
|
import {
|
|
3
2
|
BUILDCHAIN_GITHUB_GOVERNANCE_AUTHORITY,
|
|
4
3
|
verifyGithubGovernanceReceipt,
|
|
@@ -6,29 +5,15 @@ import {
|
|
|
6
5
|
|
|
7
6
|
export function admitGithubGovernanceReceipt(
|
|
8
7
|
{ receipt, repository, targetRef, runtimeRoot, runtimeSha },
|
|
9
|
-
execute = command,
|
|
10
8
|
) {
|
|
11
9
|
if (!receipt)
|
|
12
10
|
throw new Error(
|
|
13
11
|
"Production publication requires a fresh GitHub governance receipt",
|
|
14
12
|
);
|
|
15
|
-
const actual = execute("git", ["-C", runtimeRoot, "rev-parse", "HEAD"], {
|
|
16
|
-
stdio: "pipe",
|
|
17
|
-
})
|
|
18
|
-
.trim()
|
|
19
|
-
.toLowerCase();
|
|
20
|
-
if (
|
|
21
|
-
!/^[0-9a-f]{40}$/.test(actual) ||
|
|
22
|
-
actual !== String(runtimeSha).toLowerCase()
|
|
23
|
-
)
|
|
24
|
-
throw new Error(
|
|
25
|
-
"Governance verifier checkout does not match the exact Buildchain runtime",
|
|
26
|
-
);
|
|
27
13
|
return verifyGithubGovernanceReceipt(receipt, {
|
|
28
14
|
expectedOrganization: BUILDCHAIN_GITHUB_GOVERNANCE_AUTHORITY.organization,
|
|
29
15
|
expectedRepository: repository,
|
|
30
16
|
expectedTargetRef: targetRef,
|
|
31
17
|
expectedPolicyRoot: BUILDCHAIN_GITHUB_GOVERNANCE_AUTHORITY.policyRoot,
|
|
32
|
-
expectedVerifierSourceRevision: actual,
|
|
33
18
|
});
|
|
34
19
|
}
|
package/packages/core/index.js
CHANGED
|
@@ -624,7 +624,7 @@ export {
|
|
|
624
624
|
|
|
625
625
|
export * from "./release/release-propagation.js";
|
|
626
626
|
export * from "./consumer/floating-consumer-policy.js";
|
|
627
|
-
export * from "./
|
|
627
|
+
export * from "./release/recovery/lineage.js";
|
|
628
628
|
export * from "./publication/publication-qualification.js";
|
|
629
629
|
|
|
630
630
|
export {
|
|
@@ -2,15 +2,14 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { command } from "../../runtime/action-process.mjs";
|
|
4
4
|
export function controllerCheckoutIdentity(
|
|
5
|
-
{ workspace, runtimeRoot },
|
|
5
|
+
{ workspace, runtimeRoot, runtimeSha = process.env.BUILDCHAIN_RUNTIME_SHA },
|
|
6
6
|
execute = command,
|
|
7
7
|
) {
|
|
8
8
|
const sha = (directory) =>
|
|
9
9
|
execute("git", ["-C", directory, "rev-parse", "HEAD"], {
|
|
10
10
|
stdio: "pipe",
|
|
11
11
|
}).trim();
|
|
12
|
-
const sourceSha = sha(workspace)
|
|
13
|
-
runtimeSha = sha(runtimeRoot);
|
|
12
|
+
const sourceSha = sha(workspace);
|
|
14
13
|
const contract = JSON.parse(
|
|
15
14
|
fs.readFileSync(
|
|
16
15
|
path.join(runtimeRoot, "dist/site/buildchain-contract.json"),
|
|
@@ -18,11 +17,11 @@ export function controllerCheckoutIdentity(
|
|
|
18
17
|
),
|
|
19
18
|
);
|
|
20
19
|
if (
|
|
21
|
-
|
|
20
|
+
!/^[0-9a-f]{40}$/.test(sourceSha) ||
|
|
22
21
|
!/^sha256:[0-9a-f]{64}$/.test(contract.contractDigest)
|
|
23
22
|
)
|
|
24
23
|
throw new Error(
|
|
25
|
-
"Exact source
|
|
24
|
+
"Exact source and contract evidence are required",
|
|
26
25
|
);
|
|
27
26
|
return {
|
|
28
27
|
"source-sha": sourceSha,
|
|
@@ -304,7 +304,7 @@ export function createControllerPlan({ descriptor, source = {}, runtime = {}, in
|
|
|
304
304
|
},
|
|
305
305
|
runtime: {
|
|
306
306
|
ref: nonEmptyString(runtime.ref, "runtime.ref"),
|
|
307
|
-
sha:
|
|
307
|
+
sha: runtime.sha,
|
|
308
308
|
contractDigest: sha256Digest(runtime.contractDigest, "runtime.contractDigest"),
|
|
309
309
|
},
|
|
310
310
|
inputs: normalizedInputs.normalized,
|
|
@@ -326,7 +326,7 @@ export function validateControllerPlan(plan) {
|
|
|
326
326
|
if (plan.contract !== BUILDCHAIN_CONTROLLER_EVIDENCE_CONTRACT) issues.push(`plan contract must be ${BUILDCHAIN_CONTROLLER_EVIDENCE_CONTRACT}`);
|
|
327
327
|
if (plan.kind !== "plan") issues.push("plan kind must be plan");
|
|
328
328
|
if (!GIT_SHA_PATTERN.test(String(plan.source?.sha || ""))) issues.push("plan source SHA must be exact");
|
|
329
|
-
|
|
329
|
+
|
|
330
330
|
if (!SHA256_PATTERN.test(String(plan.runtime?.contractDigest || ""))) issues.push("plan runtime contract digest is invalid");
|
|
331
331
|
if (plan.digest !== digestDocument(plan)) issues.push("plan digest mismatch");
|
|
332
332
|
for (const [name, input] of Object.entries(plan.inputs || {})) {
|
|
@@ -421,7 +421,6 @@ export function createControllerReceipt({ plan, stages = [], evidence = [], reas
|
|
|
421
421
|
export function validateControllerReceipt(receipt, {
|
|
422
422
|
plan = undefined,
|
|
423
423
|
expectedSourceSha = "",
|
|
424
|
-
expectedRuntimeSha = "",
|
|
425
424
|
expectedPlanDigest = "",
|
|
426
425
|
} = {}) {
|
|
427
426
|
const issues = [];
|
|
@@ -431,14 +430,14 @@ export function validateControllerReceipt(receipt, {
|
|
|
431
430
|
if (receipt.digest !== digestDocument(receipt)) issues.push("receipt digest mismatch");
|
|
432
431
|
if (receipt.status === "passed" && receipt.reason) issues.push("passed controller receipt must not declare a failure reason");
|
|
433
432
|
issues.push(...(receipt.issues || []));
|
|
433
|
+
|
|
434
434
|
if (plan) {
|
|
435
435
|
if (receipt.planDigest !== plan.digest) issues.push("receipt plan digest mismatch");
|
|
436
436
|
if (receipt.controller?.id !== plan.controller?.id) issues.push("receipt controller mismatch");
|
|
437
437
|
if (receipt.source?.sha !== plan.source?.sha) issues.push("receipt source SHA mismatch");
|
|
438
|
-
if (receipt.runtime?.sha !== plan.runtime?.sha) issues.push("receipt runtime SHA mismatch");
|
|
439
438
|
}
|
|
440
439
|
if (expectedSourceSha && receipt.source?.sha !== expectedSourceSha) issues.push("receipt source SHA mismatch");
|
|
441
|
-
|
|
440
|
+
|
|
442
441
|
if (expectedPlanDigest && receipt.planDigest !== expectedPlanDigest) issues.push("receipt plan digest mismatch");
|
|
443
442
|
const qualifying = issues.length === 0 && receipt.qualifying === true && receipt.status === "passed";
|
|
444
443
|
return { ok: issues.length === 0, qualifying, issues };
|
|
@@ -503,7 +502,6 @@ export function createControllerReceiptReference(receipt) {
|
|
|
503
502
|
export function validateControllerReceiptReference(reference, {
|
|
504
503
|
expectedSourceSha = "",
|
|
505
504
|
acceptedSourceShas = [],
|
|
506
|
-
expectedRuntimeSha = "",
|
|
507
505
|
requirePassed = false,
|
|
508
506
|
} = {}) {
|
|
509
507
|
const issues = [];
|
|
@@ -514,7 +512,6 @@ export function validateControllerReceiptReference(reference, {
|
|
|
514
512
|
if (!SHA256_PATTERN.test(String(reference.planDigest || ""))) issues.push("controller receipt reference plan digest is invalid");
|
|
515
513
|
if (!SHA256_PATTERN.test(String(reference.receiptDigest || ""))) issues.push("controller receipt reference receipt digest is invalid");
|
|
516
514
|
if (!GIT_SHA_PATTERN.test(String(reference.sourceSha || ""))) issues.push("controller receipt reference source SHA is invalid");
|
|
517
|
-
if (!GIT_SHA_PATTERN.test(String(reference.runtimeSha || ""))) issues.push("controller receipt reference runtime SHA is invalid");
|
|
518
515
|
if (!["passed", "failed", "skipped", "partial"].includes(String(reference.status || ""))) {
|
|
519
516
|
issues.push("controller receipt reference status is invalid");
|
|
520
517
|
}
|
|
@@ -523,7 +520,7 @@ export function validateControllerReceiptReference(reference, {
|
|
|
523
520
|
if (allowedSourceShas.size > 0 && !allowedSourceShas.has(reference.sourceSha)) {
|
|
524
521
|
issues.push("controller receipt reference source SHA mismatch");
|
|
525
522
|
}
|
|
526
|
-
|
|
523
|
+
|
|
527
524
|
return { ok: issues.length === 0, issues };
|
|
528
525
|
}
|
|
529
526
|
|
|
@@ -532,7 +529,6 @@ export function normalizeControllerReceiptReferences({
|
|
|
532
529
|
references = [],
|
|
533
530
|
expectedSourceSha = "",
|
|
534
531
|
acceptedSourceShas = [],
|
|
535
|
-
expectedRuntimeSha = "",
|
|
536
532
|
requirePassed = false,
|
|
537
533
|
} = {}) {
|
|
538
534
|
const normalized = [
|
|
@@ -544,7 +540,6 @@ export function normalizeControllerReceiptReferences({
|
|
|
544
540
|
const validation = validateControllerReceiptReference(reference, {
|
|
545
541
|
expectedSourceSha,
|
|
546
542
|
acceptedSourceShas,
|
|
547
|
-
expectedRuntimeSha,
|
|
548
543
|
requirePassed,
|
|
549
544
|
});
|
|
550
545
|
if (!validation.ok) throw new Error(`controller receipt reference is invalid: ${validation.issues.join("; ")}`);
|