@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
|
@@ -54,9 +54,9 @@ function materializeRecoveryEvidence({
|
|
|
54
54
|
runtimeRoot,
|
|
55
55
|
recoveryRunId,
|
|
56
56
|
recoveryRunAttempt,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
60
|
runId,
|
|
61
61
|
run,
|
|
62
62
|
selected,
|
|
@@ -104,9 +104,9 @@ function materializeRecoveryEvidence({
|
|
|
104
104
|
runtimeRoot,
|
|
105
105
|
recoveryRunId,
|
|
106
106
|
recoveryRunAttempt,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
110
|
})
|
|
111
111
|
: "";
|
|
112
112
|
const tarballs = publication.npmArtifacts.map((entry) =>
|
|
@@ -219,7 +219,6 @@ async function qualifyRecoveredCandidate({
|
|
|
219
219
|
publicationNames,
|
|
220
220
|
bundleRoot,
|
|
221
221
|
repoInfo,
|
|
222
|
-
candidateRuntimeSha,
|
|
223
222
|
publishArtifactKind,
|
|
224
223
|
publishPackageMain,
|
|
225
224
|
releasePatterns,
|
|
@@ -262,8 +261,7 @@ async function qualifyRecoveredCandidate({
|
|
|
262
261
|
bundleRoot,
|
|
263
262
|
repository: repoInfo.fullName,
|
|
264
263
|
passport,
|
|
265
|
-
|
|
266
|
-
publishArtifactKind,
|
|
264
|
+
publishArtifactKind,
|
|
267
265
|
publishPackageMain,
|
|
268
266
|
releasePatterns,
|
|
269
267
|
platformManifests: platformManifestEvidence.manifests,
|
|
@@ -273,8 +271,7 @@ async function qualifyRecoveredCandidate({
|
|
|
273
271
|
rematerializeOnResume,
|
|
274
272
|
});
|
|
275
273
|
const stageCapsules = resolveRecoveredStageCapsules({
|
|
276
|
-
|
|
277
|
-
runtimeSha,
|
|
274
|
+
runtimeSha,
|
|
278
275
|
sidecar: stageCapsuleSidecar,
|
|
279
276
|
passport,
|
|
280
277
|
downloads,
|
|
@@ -318,7 +315,6 @@ async function qualifyRecoveredCandidate({
|
|
|
318
315
|
targetTree: targetCommit.tree?.sha,
|
|
319
316
|
expectedSourceTree,
|
|
320
317
|
expectedCandidateRoot,
|
|
321
|
-
expectedRuntimeSha: candidateRuntimeSha,
|
|
322
318
|
expectedTransactionId: transactionId,
|
|
323
319
|
existingTransaction,
|
|
324
320
|
run: normalizeCandidateRun(run, repoInfo.fullName),
|
|
@@ -371,7 +367,6 @@ export async function resumeFromCandidateRun({
|
|
|
371
367
|
targetSha,
|
|
372
368
|
expectedSourceTree = "",
|
|
373
369
|
expectedCandidateRoot = "",
|
|
374
|
-
candidateRuntimeSha,
|
|
375
370
|
runtimeSha,
|
|
376
371
|
transactionId = "",
|
|
377
372
|
artifactName = "",
|
|
@@ -387,9 +382,9 @@ export async function resumeFromCandidateRun({
|
|
|
387
382
|
recoveryRunId,
|
|
388
383
|
recoveryRunAttempt = "1",
|
|
389
384
|
runtimeRoot = installationRoot(import.meta.url),
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
|
|
393
388
|
fetchImpl = globalThis.fetch,
|
|
394
389
|
} = {}) {
|
|
395
390
|
const repoInfo = splitRepository(repository);
|
|
@@ -466,8 +461,7 @@ export async function resumeFromCandidateRun({
|
|
|
466
461
|
publicationNames,
|
|
467
462
|
bundleRoot,
|
|
468
463
|
repoInfo,
|
|
469
|
-
|
|
470
|
-
publishArtifactKind,
|
|
464
|
+
publishArtifactKind,
|
|
471
465
|
publishPackageMain,
|
|
472
466
|
releasePatterns,
|
|
473
467
|
channel,
|
|
@@ -510,9 +504,9 @@ export async function resumeFromCandidateRun({
|
|
|
510
504
|
runtimeRoot,
|
|
511
505
|
recoveryRunId,
|
|
512
506
|
recoveryRunAttempt,
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
|
|
516
510
|
runId,
|
|
517
511
|
run,
|
|
518
512
|
selected,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { domainContentRoot } from "../../contracts/canonical-contracts.js";
|
|
2
2
|
import { validateStageCapsule } from "../../build/stage-capsule.js";
|
|
3
|
-
import { runtimeResumeDocumentRoot } from "
|
|
3
|
+
import { runtimeResumeDocumentRoot } from "./lineage.js";
|
|
4
4
|
export function verifyReleaseCandidateStageCapsules({
|
|
5
5
|
sidecar,
|
|
6
6
|
passport,
|
|
@@ -25,7 +25,6 @@ export function verifyReleaseCandidateStageCapsules({
|
|
|
25
25
|
sidecar.source?.sha !== passport.source.headSha ||
|
|
26
26
|
sidecar.source?.treeSha !== passport.source.treeHash ||
|
|
27
27
|
sidecar.buildAttempt?.id !== expectedAttempt ||
|
|
28
|
-
sidecar.buildAttempt?.runtimeSha !== passport.buildchain.sha ||
|
|
29
28
|
sidecar.consumerPolicyReceiptRoot !== passport.consumerPolicy?.receiptRoot
|
|
30
29
|
) {
|
|
31
30
|
throw new Error(
|
|
@@ -66,11 +65,7 @@ export function verifyReleaseCandidateStageCapsules({
|
|
|
66
65
|
new Date(download.artifact.expires_at).toISOString() ||
|
|
67
66
|
entry.capsule.identity.policyRoot !== sidecar.consumerPolicyReceiptRoot ||
|
|
68
67
|
entry.capsule.identity.sourceRoot !==
|
|
69
|
-
domainContentRoot("candidate-identity", passport.source)
|
|
70
|
-
entry.capsule.identity.runtimeRoot !==
|
|
71
|
-
domainContentRoot("candidate-identity", {
|
|
72
|
-
sha: passport.buildchain.sha,
|
|
73
|
-
})
|
|
68
|
+
domainContentRoot("candidate-identity", passport.source)
|
|
74
69
|
) {
|
|
75
70
|
throw new Error(
|
|
76
71
|
`Stage Capsule ${entry.platform} does not bind the verified provider artifact`,
|
|
@@ -91,12 +86,9 @@ export function verifyReleaseCandidateStageCapsules({
|
|
|
91
86
|
}
|
|
92
87
|
|
|
93
88
|
export function resolveRecoveredStageCapsules({
|
|
94
|
-
candidateRuntimeSha,
|
|
95
|
-
runtimeSha,
|
|
96
89
|
sidecar,
|
|
97
90
|
passport,
|
|
98
91
|
downloads,
|
|
99
92
|
}) {
|
|
100
|
-
if (candidateRuntimeSha === runtimeSha) return [];
|
|
101
93
|
return verifyReleaseCandidateStageCapsules({ sidecar, passport, downloads });
|
|
102
94
|
}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
export const RUNTIME_RESUME_LINEAGE_CONTRACT =
|
|
3
|
+
"buildchain.runtime-resume-lineage/v2";
|
|
4
|
+
const EXACT_SHA = /^[0-9a-f]{40}$/u;
|
|
5
|
+
const SHA256_ROOT = /^sha256:[0-9a-f]{64}$/u;
|
|
6
|
+
const TOKEN = /^[A-Za-z0-9][A-Za-z0-9._:/-]*$/u;
|
|
7
|
+
function stableJson(value) {
|
|
8
|
+
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
|
|
9
|
+
if (value && typeof value === "object") {
|
|
10
|
+
return `{${Object.keys(value)
|
|
11
|
+
.sort()
|
|
12
|
+
.map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`)
|
|
13
|
+
.join(",")}}`;
|
|
14
|
+
}
|
|
15
|
+
return JSON.stringify(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function runtimeResumeDocumentRoot(value) {
|
|
19
|
+
return `sha256:${crypto.createHash("sha256").update(stableJson(value)).digest("hex")}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function exactSha(value, label) {
|
|
23
|
+
const normalized = String(value || "")
|
|
24
|
+
.trim()
|
|
25
|
+
.toLowerCase();
|
|
26
|
+
if (!EXACT_SHA.test(normalized)) {
|
|
27
|
+
throw new Error(`${label} must be an exact 40-character Git SHA`);
|
|
28
|
+
}
|
|
29
|
+
return normalized;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function root(value, label) {
|
|
33
|
+
const normalized = String(value || "")
|
|
34
|
+
.trim()
|
|
35
|
+
.toLowerCase();
|
|
36
|
+
if (!SHA256_ROOT.test(normalized)) {
|
|
37
|
+
throw new Error(`${label} must be a sha256 content root`);
|
|
38
|
+
}
|
|
39
|
+
return normalized;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function nonEmpty(value, label) {
|
|
43
|
+
const normalized = String(value || "").trim();
|
|
44
|
+
if (!normalized) throw new Error(`${label} must be non-empty`);
|
|
45
|
+
return normalized;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function token(value, label) {
|
|
49
|
+
const normalized = nonEmpty(value, label);
|
|
50
|
+
if (!TOKEN.test(normalized)) {
|
|
51
|
+
throw new Error(`${label} must be an ASCII identity token`);
|
|
52
|
+
}
|
|
53
|
+
return normalized;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function exactKeys(value, expected, label) {
|
|
57
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
58
|
+
throw new Error(`${label} must be an object`);
|
|
59
|
+
}
|
|
60
|
+
const actual = Object.keys(value).sort();
|
|
61
|
+
const canonical = [...expected].sort();
|
|
62
|
+
if (
|
|
63
|
+
actual.length !== canonical.length ||
|
|
64
|
+
actual.some((key, index) => key !== canonical[index])
|
|
65
|
+
) {
|
|
66
|
+
throw new Error(`${label} has an invalid field set`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function sortedUnique(values, label) {
|
|
71
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
72
|
+
throw new Error(`${label} must be a non-empty array`);
|
|
73
|
+
}
|
|
74
|
+
const normalized = values.map((value, index) =>
|
|
75
|
+
token(value, `${label}[${index}]`),
|
|
76
|
+
);
|
|
77
|
+
const expected = [...new Set(normalized)].sort((left, right) =>
|
|
78
|
+
Buffer.from(left).compare(Buffer.from(right)),
|
|
79
|
+
);
|
|
80
|
+
if (
|
|
81
|
+
normalized.length !== expected.length ||
|
|
82
|
+
normalized.some((value, index) => value !== expected[index])
|
|
83
|
+
) {
|
|
84
|
+
throw new Error(`${label} must be byte-sorted and duplicate-free`);
|
|
85
|
+
}
|
|
86
|
+
return normalized;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function createRuntimeResumeLineage({
|
|
90
|
+
repository,
|
|
91
|
+
buildAttempt,
|
|
92
|
+
resumeAttempt,
|
|
93
|
+
source,
|
|
94
|
+
consumerPolicyReceiptRoot,
|
|
95
|
+
requiredPlatforms,
|
|
96
|
+
stageCapsules,
|
|
97
|
+
resumePlanRoot,
|
|
98
|
+
finalPublicReadbackRoot,
|
|
99
|
+
} = {}) {
|
|
100
|
+
const buildId = token(buildAttempt?.id, "buildAttempt.id");
|
|
101
|
+
const resumeId = token(resumeAttempt?.id, "resumeAttempt.id");
|
|
102
|
+
if (buildId === resumeId) {
|
|
103
|
+
throw new Error("resume must create a new governed attempt");
|
|
104
|
+
}
|
|
105
|
+
const buildRuntimeSha = buildAttempt?.runtimeSha;
|
|
106
|
+
const resumeRuntimeSha = resumeAttempt?.runtimeSha;
|
|
107
|
+
const sourceIdentity = {
|
|
108
|
+
sha: exactSha(source?.sha, "source.sha"),
|
|
109
|
+
treeSha: exactSha(source?.treeSha, "source.treeSha"),
|
|
110
|
+
};
|
|
111
|
+
const policyRoot = root(
|
|
112
|
+
consumerPolicyReceiptRoot,
|
|
113
|
+
"consumerPolicyReceiptRoot",
|
|
114
|
+
);
|
|
115
|
+
const platforms = sortedUnique(requiredPlatforms, "requiredPlatforms");
|
|
116
|
+
if (!Array.isArray(stageCapsules))
|
|
117
|
+
throw new Error("stageCapsules must be an array");
|
|
118
|
+
const capsuleByPlatform = new Map();
|
|
119
|
+
for (const [index, capsule] of stageCapsules.entries()) {
|
|
120
|
+
exactKeys(
|
|
121
|
+
capsule,
|
|
122
|
+
[
|
|
123
|
+
"platform",
|
|
124
|
+
"capsuleRoot",
|
|
125
|
+
"identityRoot",
|
|
126
|
+
"artifactDigest",
|
|
127
|
+
"sourceSha",
|
|
128
|
+
"sourceTreeSha",
|
|
129
|
+
"policyRoot",
|
|
130
|
+
"buildRuntimeSha",
|
|
131
|
+
"sealed",
|
|
132
|
+
],
|
|
133
|
+
`stageCapsules[${index}]`,
|
|
134
|
+
);
|
|
135
|
+
const platform = token(
|
|
136
|
+
capsule.platform,
|
|
137
|
+
`stageCapsules[${index}].platform`,
|
|
138
|
+
);
|
|
139
|
+
if (!platforms.includes(platform)) {
|
|
140
|
+
throw new Error(`stageCapsules[${index}] names an undeclared platform`);
|
|
141
|
+
}
|
|
142
|
+
if (capsuleByPlatform.has(platform)) {
|
|
143
|
+
throw new Error(`duplicate Stage Capsule for ${platform}`);
|
|
144
|
+
}
|
|
145
|
+
if (capsule.sealed !== true)
|
|
146
|
+
throw new Error(`Stage Capsule ${platform} is not sealed`);
|
|
147
|
+
if (
|
|
148
|
+
exactSha(capsule.sourceSha, `${platform}.sourceSha`) !==
|
|
149
|
+
sourceIdentity.sha ||
|
|
150
|
+
exactSha(capsule.sourceTreeSha, `${platform}.sourceTreeSha`) !==
|
|
151
|
+
sourceIdentity.treeSha ||
|
|
152
|
+
root(capsule.policyRoot, `${platform}.policyRoot`) !== policyRoot
|
|
153
|
+
) {
|
|
154
|
+
throw new Error(
|
|
155
|
+
`Stage Capsule ${platform} identity is stale or ambiguous`,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
capsuleByPlatform.set(platform, {
|
|
159
|
+
platform,
|
|
160
|
+
capsuleRoot: root(capsule.capsuleRoot, `${platform}.capsuleRoot`),
|
|
161
|
+
identityRoot: root(capsule.identityRoot, `${platform}.identityRoot`),
|
|
162
|
+
artifactDigest: root(
|
|
163
|
+
capsule.artifactDigest,
|
|
164
|
+
`${platform}.artifactDigest`,
|
|
165
|
+
),
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
const reusedCapsules = platforms
|
|
169
|
+
.filter((platform) => capsuleByPlatform.has(platform))
|
|
170
|
+
.map((platform) => capsuleByPlatform.get(platform));
|
|
171
|
+
const rebuildPlatforms = platforms.filter(
|
|
172
|
+
(platform) => !capsuleByPlatform.has(platform),
|
|
173
|
+
);
|
|
174
|
+
const lineage = {
|
|
175
|
+
schemaVersion: 2,
|
|
176
|
+
contract: RUNTIME_RESUME_LINEAGE_CONTRACT,
|
|
177
|
+
status: "qualified",
|
|
178
|
+
repository: nonEmpty(repository, "repository"),
|
|
179
|
+
source: sourceIdentity,
|
|
180
|
+
consumerPolicyReceiptRoot: policyRoot,
|
|
181
|
+
attempts: {
|
|
182
|
+
build: { id: buildId, runtimeSha: buildRuntimeSha },
|
|
183
|
+
resume: { id: resumeId, runtimeSha: resumeRuntimeSha },
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
continuation: {
|
|
187
|
+
mechanism: "new-governed-attempt",
|
|
188
|
+
rerunFailedJobs: false,
|
|
189
|
+
resumePlanRoot: root(resumePlanRoot, "resumePlanRoot"),
|
|
190
|
+
},
|
|
191
|
+
stageCapsules: {
|
|
192
|
+
requiredPlatforms: platforms,
|
|
193
|
+
reused: reusedCapsules,
|
|
194
|
+
rebuildPlatforms,
|
|
195
|
+
},
|
|
196
|
+
finalPublicReadbackRoot: root(
|
|
197
|
+
finalPublicReadbackRoot,
|
|
198
|
+
"finalPublicReadbackRoot",
|
|
199
|
+
),
|
|
200
|
+
};
|
|
201
|
+
return { lineage, lineageRoot: runtimeResumeDocumentRoot(lineage) };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function validSourceIdentity(source) {
|
|
205
|
+
return (
|
|
206
|
+
EXACT_SHA.test(String(source?.sha || "")) &&
|
|
207
|
+
EXACT_SHA.test(String(source?.treeSha || ""))
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function platformLineageFailures(stageCapsules) {
|
|
212
|
+
const failures = [];
|
|
213
|
+
const required = stageCapsules?.requiredPlatforms || [];
|
|
214
|
+
const reused = stageCapsules?.reused || [];
|
|
215
|
+
const rebuilt = stageCapsules?.rebuildPlatforms || [];
|
|
216
|
+
const requiredCanonical = [...new Set(required)].sort();
|
|
217
|
+
const reusedPlatforms = reused.map((entry) => entry.platform);
|
|
218
|
+
const rebuiltCanonical = [...new Set(rebuilt)].sort();
|
|
219
|
+
if (
|
|
220
|
+
required.length === 0 ||
|
|
221
|
+
required.length !== requiredCanonical.length ||
|
|
222
|
+
!required.every((platform, index) => platform === requiredCanonical[index])
|
|
223
|
+
) {
|
|
224
|
+
failures.push("required-platforms-invalid");
|
|
225
|
+
}
|
|
226
|
+
if (
|
|
227
|
+
reusedPlatforms.length !== new Set(reusedPlatforms).size ||
|
|
228
|
+
rebuilt.length !== rebuiltCanonical.length ||
|
|
229
|
+
!reusedPlatforms.every((platform) => !rebuilt.includes(platform))
|
|
230
|
+
) {
|
|
231
|
+
failures.push("platform-lineage-ambiguous");
|
|
232
|
+
}
|
|
233
|
+
if (
|
|
234
|
+
[...reusedPlatforms, ...rebuilt].sort().join("\0") !==
|
|
235
|
+
[...required].sort().join("\0")
|
|
236
|
+
) {
|
|
237
|
+
failures.push("platform-lineage-incomplete");
|
|
238
|
+
}
|
|
239
|
+
if (
|
|
240
|
+
!reused.every((entry) =>
|
|
241
|
+
[entry.capsuleRoot, entry.identityRoot, entry.artifactDigest].every(
|
|
242
|
+
(value) => SHA256_ROOT.test(String(value || "")),
|
|
243
|
+
),
|
|
244
|
+
)
|
|
245
|
+
) {
|
|
246
|
+
failures.push("capsule-root-invalid");
|
|
247
|
+
}
|
|
248
|
+
return failures;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function verifyRuntimeResumeLineage({
|
|
252
|
+
lineage,
|
|
253
|
+
lineageRoot,
|
|
254
|
+
repository = "",
|
|
255
|
+
sourceSha = "",
|
|
256
|
+
consumerPolicyReceiptRoot = "",
|
|
257
|
+
} = {}) {
|
|
258
|
+
const failures = [];
|
|
259
|
+
const check = (condition, code) => {
|
|
260
|
+
if (!condition) failures.push(code);
|
|
261
|
+
};
|
|
262
|
+
check(
|
|
263
|
+
lineage?.contract === RUNTIME_RESUME_LINEAGE_CONTRACT,
|
|
264
|
+
"contract-invalid",
|
|
265
|
+
);
|
|
266
|
+
check(lineage?.status === "qualified", "status-not-qualified");
|
|
267
|
+
check(
|
|
268
|
+
SHA256_ROOT.test(String(lineageRoot || "")) &&
|
|
269
|
+
lineageRoot === runtimeResumeDocumentRoot(lineage),
|
|
270
|
+
"lineage-root-mismatch",
|
|
271
|
+
);
|
|
272
|
+
check(
|
|
273
|
+
lineage?.attempts?.build?.id &&
|
|
274
|
+
lineage?.attempts?.resume?.id &&
|
|
275
|
+
lineage.attempts.build.id !== lineage.attempts.resume.id,
|
|
276
|
+
"attempt-not-fresh",
|
|
277
|
+
);
|
|
278
|
+
check(validSourceIdentity(lineage?.source), "source-identity-invalid");
|
|
279
|
+
check(
|
|
280
|
+
lineage?.continuation?.mechanism === "new-governed-attempt" &&
|
|
281
|
+
lineage?.continuation?.rerunFailedJobs === false,
|
|
282
|
+
"continuation-mechanism-invalid",
|
|
283
|
+
);
|
|
284
|
+
failures.push(...platformLineageFailures(lineage?.stageCapsules));
|
|
285
|
+
check(
|
|
286
|
+
[
|
|
287
|
+
lineage?.consumerPolicyReceiptRoot,
|
|
288
|
+
lineage?.continuation?.resumePlanRoot,
|
|
289
|
+
lineage?.finalPublicReadbackRoot,
|
|
290
|
+
].every((value) => SHA256_ROOT.test(String(value || ""))),
|
|
291
|
+
"evidence-root-invalid",
|
|
292
|
+
);
|
|
293
|
+
if (sourceSha)
|
|
294
|
+
check(lineage?.source?.sha === sourceSha, "source-sha-mismatch");
|
|
295
|
+
if (consumerPolicyReceiptRoot) {
|
|
296
|
+
check(
|
|
297
|
+
lineage?.consumerPolicyReceiptRoot === consumerPolicyReceiptRoot,
|
|
298
|
+
"consumer-policy-root-mismatch",
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
if (repository) {
|
|
302
|
+
check(lineage?.repository === repository, "repository-mismatch");
|
|
303
|
+
}
|
|
304
|
+
return { ok: failures.length === 0, failures };
|
|
305
|
+
}
|
|
@@ -36,8 +36,7 @@ export function resolveAnchorRecoveryRequest({
|
|
|
36
36
|
!/^[0-9a-f]{40}$/u.test(String(request.supersededCandidate?.sha || "")) ||
|
|
37
37
|
!/^sha256:[0-9a-f]{64}$/u.test(
|
|
38
38
|
String(request.supersededCandidate?.root || ""),
|
|
39
|
-
)
|
|
40
|
-
request.runtime?.sha !== passport.buildchain?.sha
|
|
39
|
+
)
|
|
41
40
|
) {
|
|
42
41
|
throw new Error(
|
|
43
42
|
"anchored candidate request does not bind the sealed recovery identity",
|
|
@@ -13,20 +13,14 @@ export function createRecoveredPublicationCandidate({
|
|
|
13
13
|
allFiles,
|
|
14
14
|
repository,
|
|
15
15
|
passport,
|
|
16
|
-
candidateRuntimeSha,
|
|
17
16
|
}) {
|
|
18
|
-
if (passport.buildchain?.sha !== candidateRuntimeSha) {
|
|
19
|
-
throw new Error(
|
|
20
|
-
`recovered publication candidate runtime mismatch: passport=${passport.buildchain?.sha || "<empty>"} expected=${candidateRuntimeSha || "<empty>"}`,
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
17
|
const payload = {
|
|
24
18
|
schemaVersion: 1,
|
|
25
19
|
contract: PUBLICATION_ARTIFACT_CANDIDATE_CONTRACT,
|
|
26
20
|
repository,
|
|
27
21
|
sourceSha: passport.source.headSha,
|
|
28
22
|
sourceTreeSha: passport.source.treeHash,
|
|
29
|
-
runtimeSha:
|
|
23
|
+
runtimeSha: passport.buildchain?.sha,
|
|
30
24
|
releaseCandidateRoot: `sha256:${passport.candidateHash}`,
|
|
31
25
|
files: allFiles.map(({ path: filePath, size, sha256 }) => ({
|
|
32
26
|
path: filePath,
|
|
@@ -45,7 +39,6 @@ export function createRecoveredPublication({
|
|
|
45
39
|
bundleRoot,
|
|
46
40
|
repository,
|
|
47
41
|
passport,
|
|
48
|
-
candidateRuntimeSha,
|
|
49
42
|
publishArtifactKind,
|
|
50
43
|
publishPackageMain,
|
|
51
44
|
releasePatterns,
|
|
@@ -78,8 +71,7 @@ export function createRecoveredPublication({
|
|
|
78
71
|
allFiles,
|
|
79
72
|
repository,
|
|
80
73
|
passport,
|
|
81
|
-
|
|
82
|
-
});
|
|
74
|
+
});
|
|
83
75
|
const sealed = resolveOciCandidate({ payloadRoot: bundleRoot, passport });
|
|
84
76
|
return {
|
|
85
77
|
manifest: sealed.manifest,
|
|
@@ -97,8 +89,7 @@ export function createRecoveredPublication({
|
|
|
97
89
|
allFiles,
|
|
98
90
|
repository,
|
|
99
91
|
passport,
|
|
100
|
-
|
|
101
|
-
});
|
|
92
|
+
});
|
|
102
93
|
const version = String(passport.target?.version || "").trim();
|
|
103
94
|
if (!version)
|
|
104
95
|
throw new Error(
|
|
@@ -163,8 +154,7 @@ export function createRecoveredPublication({
|
|
|
163
154
|
allFiles,
|
|
164
155
|
repository,
|
|
165
156
|
passport,
|
|
166
|
-
|
|
167
|
-
});
|
|
157
|
+
});
|
|
168
158
|
const manifest = createPublicationSealedBundle({
|
|
169
159
|
candidate,
|
|
170
160
|
packageName: main.metadata.name,
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { compareSemver } from "../../publication/candidate/registry-hydration.js";
|
|
3
3
|
import { githubJson } from "./../candidate/transport.js";
|
|
4
|
-
import { runtimeResumeDocumentRoot } from "
|
|
4
|
+
import { runtimeResumeDocumentRoot } from "./lineage.js";
|
|
5
5
|
export function validateRuntimeResumePublicReadback({
|
|
6
6
|
targetRef,
|
|
7
7
|
targetSha,
|
|
8
8
|
targetVersion,
|
|
9
|
-
|
|
9
|
+
floatingSha,
|
|
10
10
|
exactTagSha,
|
|
11
11
|
tagLineage,
|
|
12
|
-
runtimeLineage,
|
|
13
12
|
floatingTargetLineage,
|
|
14
|
-
runtimeSha,
|
|
15
13
|
version,
|
|
16
14
|
transaction,
|
|
17
15
|
main,
|
|
18
16
|
npm,
|
|
19
17
|
}) {
|
|
20
|
-
const
|
|
18
|
+
const distTag = version.includes("-") ? "alpha" : "latest";
|
|
19
|
+
const channelVersion = npm["dist-tags"]?.[distTag];
|
|
21
20
|
let channelDidNotRegress = false;
|
|
22
21
|
try {
|
|
23
22
|
channelDidNotRegress = compareSemver(channelVersion, version) >= 0;
|
|
@@ -29,18 +28,16 @@ export function validateRuntimeResumePublicReadback({
|
|
|
29
28
|
transaction?.version !== version ||
|
|
30
29
|
exactTagSha !== transaction?.source_sha ||
|
|
31
30
|
!["ahead", "identical"].includes(tagLineage?.status) ||
|
|
32
|
-
!["ahead", "identical"].includes(runtimeLineage?.status) ||
|
|
33
31
|
!["ahead", "identical"].includes(floatingTargetLineage?.status) ||
|
|
34
|
-
!
|
|
32
|
+
!floatingSha ||
|
|
35
33
|
!targetSha ||
|
|
36
|
-
!runtimeSha ||
|
|
37
34
|
channelVersion !== targetVersion ||
|
|
38
35
|
!channelDidNotRegress ||
|
|
39
36
|
!npm.versions?.[channelVersion]?.dist?.integrity ||
|
|
40
37
|
npm.versions?.[version]?.dist?.integrity !== main.digest
|
|
41
38
|
) {
|
|
42
39
|
throw new Error(
|
|
43
|
-
"cross-runtime final public readback does not match durable publication bytes
|
|
40
|
+
"cross-runtime final public readback does not match durable publication bytes",
|
|
44
41
|
);
|
|
45
42
|
}
|
|
46
43
|
}
|
|
@@ -48,7 +45,6 @@ export function validateRuntimeResumePublicReadback({
|
|
|
48
45
|
export async function readPublicResumeState({
|
|
49
46
|
repoInfo,
|
|
50
47
|
targetRef,
|
|
51
|
-
runtimeSha,
|
|
52
48
|
version,
|
|
53
49
|
transaction,
|
|
54
50
|
token,
|
|
@@ -73,9 +69,11 @@ export async function readPublicResumeState({
|
|
|
73
69
|
);
|
|
74
70
|
const packageUrl = `https://registry.npmjs.org/${encodeURIComponent(main.name)}`;
|
|
75
71
|
const exactTag = transaction.exact_tag || `v${version}`;
|
|
76
|
-
const
|
|
72
|
+
const floatingRef = `v${version.split(".")[0]}${version.includes("-") ? "-alpha" : ""}`;
|
|
73
|
+
const distTag = version.includes("-") ? "alpha" : "latest";
|
|
74
|
+
const [targetSha, floatingSha, exactTagSha, npmResponse] = await Promise.all([
|
|
77
75
|
readRef(`heads/${targetRef}`),
|
|
78
|
-
readRef(
|
|
76
|
+
readRef(`tags/${floatingRef}`),
|
|
79
77
|
readRef(`tags/${exactTag}`),
|
|
80
78
|
fetchImpl(packageUrl),
|
|
81
79
|
]);
|
|
@@ -85,7 +83,7 @@ export async function readPublicResumeState({
|
|
|
85
83
|
);
|
|
86
84
|
}
|
|
87
85
|
const npm = await npmResponse.json();
|
|
88
|
-
const [tagLineage,
|
|
86
|
+
const [tagLineage, floatingTargetLineage, targetPackageFile] =
|
|
89
87
|
await Promise.all([
|
|
90
88
|
githubJson({
|
|
91
89
|
apiUrl,
|
|
@@ -97,13 +95,7 @@ export async function readPublicResumeState({
|
|
|
97
95
|
apiUrl,
|
|
98
96
|
token,
|
|
99
97
|
fetchImpl,
|
|
100
|
-
path: `/repos/${repoInfo.owner}/${repoInfo.repo}/compare/${
|
|
101
|
-
}),
|
|
102
|
-
githubJson({
|
|
103
|
-
apiUrl,
|
|
104
|
-
token,
|
|
105
|
-
fetchImpl,
|
|
106
|
-
path: `/repos/${repoInfo.owner}/${repoInfo.repo}/compare/${alphaSha}...${targetSha}`,
|
|
98
|
+
path: `/repos/${repoInfo.owner}/${repoInfo.repo}/compare/${floatingSha}...${targetSha}`,
|
|
107
99
|
}),
|
|
108
100
|
githubJson({
|
|
109
101
|
apiUrl,
|
|
@@ -130,13 +122,11 @@ export async function readPublicResumeState({
|
|
|
130
122
|
targetRef,
|
|
131
123
|
targetSha,
|
|
132
124
|
targetVersion,
|
|
133
|
-
|
|
125
|
+
floatingSha,
|
|
134
126
|
exactTagSha,
|
|
135
127
|
tagLineage,
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
runtimeSha,
|
|
139
|
-
version,
|
|
128
|
+
floatingTargetLineage,
|
|
129
|
+
version,
|
|
140
130
|
transaction,
|
|
141
131
|
main,
|
|
142
132
|
npm,
|
|
@@ -149,21 +139,18 @@ export async function readPublicResumeState({
|
|
|
149
139
|
version,
|
|
150
140
|
refs: {
|
|
151
141
|
target: { ref: targetRef, sha: targetSha },
|
|
152
|
-
floating: { ref:
|
|
142
|
+
floating: { ref: floatingRef, sha: floatingSha },
|
|
153
143
|
exactTag: { ref: exactTag, sha: exactTagSha },
|
|
154
144
|
},
|
|
155
145
|
npm: {
|
|
156
146
|
package: main.name,
|
|
157
147
|
version,
|
|
158
|
-
distTag
|
|
148
|
+
distTag,
|
|
159
149
|
integrity: npm.versions[version].dist.integrity,
|
|
160
150
|
targetVersion,
|
|
161
|
-
distTagVersion: npm["dist-tags"]
|
|
162
|
-
distTagIntegrity: npm.versions[npm["dist-tags"]
|
|
151
|
+
distTagVersion: npm["dist-tags"][distTag],
|
|
152
|
+
distTagIntegrity: npm.versions[npm["dist-tags"][distTag]].dist.integrity,
|
|
163
153
|
},
|
|
164
154
|
};
|
|
165
155
|
return { ...body, root: runtimeResumeDocumentRoot(body) };
|
|
166
156
|
}
|
|
167
|
-
|
|
168
|
-
export const resolveRuntimeResumePublicRuntimeSha = (material) =>
|
|
169
|
-
material?.buildAttempt?.runtimeSha || "";
|