@kungfu-tech/buildchain 3.0.6-alpha.1 → 3.0.6-alpha.3

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.
Files changed (75) hide show
  1. package/README.md +4 -4
  2. package/actions/promote-buildchain-ref/README.md +8 -0
  3. package/bin/buildchain.mjs +13 -1
  4. package/contracts/auditable-demo-scenario-v1.schema.json +52 -0
  5. package/contracts/release-candidate-recovery-v1.schema.json +102 -0
  6. package/dist/site/buildchain-contract.json +129 -34
  7. package/dist/site/buildchain-site.json +171 -45
  8. package/dist/site/capability-registry.json +5 -5
  9. package/dist/site/cli-registry.json +40 -4
  10. package/dist/site/controller-registry.json +56 -4
  11. package/dist/site/kfd-claims.json +184 -20
  12. package/dist/site/kfd-upstream-aggregate.json +1 -1
  13. package/dist/site/manual-registry.json +10 -10
  14. package/dist/site/node-api-registry.json +1242 -121
  15. package/dist/site/page-registry.json +157 -31
  16. package/dist/site/public-surface-audit.json +422 -21
  17. package/dist/site/publication-authority-registry.json +66 -1
  18. package/dist/site/publication-registry.json +4 -4
  19. package/dist/site/release-provenance.json +2 -0
  20. package/dist/site/site-manifest.json +14 -14
  21. package/dist/site/workflow-registry.json +197 -15
  22. package/docs/MAP.md +1 -0
  23. package/docs/auditable-demo.md +58 -11
  24. package/docs/aws-us-elastic-runner-burst-plane.md +23 -19
  25. package/docs/cli-reference.md +154 -0
  26. package/docs/dev-alpha-candidate-patrol.md +13 -5
  27. package/docs/dev-delivery-warrant.md +158 -0
  28. package/docs/node-api-reference.md +96 -38
  29. package/docs/publication-authority.md +11 -0
  30. package/docs/publish-transaction.md +10 -1
  31. package/docs/release-candidate.md +106 -12
  32. package/docs/release-governance.md +52 -0
  33. package/docs/reusable-build-surface.md +11 -1
  34. package/docs/shifu-gate-profiles.md +12 -1
  35. package/docs/versioning.md +2 -0
  36. package/package.json +3 -1
  37. package/packages/core/buildchain-contract.js +30 -2
  38. package/packages/core/buildchain-publication-authority.js +3 -1
  39. package/packages/core/channel-candidate.js +2 -21
  40. package/packages/core/channel-promotion-baseline.js +199 -0
  41. package/packages/core/dev-delivery-candidate-identity.js +94 -0
  42. package/packages/core/dev-delivery-common.js +73 -0
  43. package/packages/core/dev-delivery-proof.js +252 -0
  44. package/packages/core/dev-delivery-warrant-cancellation.js +94 -0
  45. package/packages/core/dev-delivery-warrant-settlement.js +73 -0
  46. package/packages/core/dev-delivery-warrant.js +591 -0
  47. package/packages/core/index.js +7 -0
  48. package/packages/core/release-candidate-recovery.js +386 -0
  49. package/scripts/auditable-demo-bundle-verification.mjs +148 -0
  50. package/scripts/auditable-demo-platform.mjs +86 -50
  51. package/scripts/auditable-demo-presentation.mjs +83 -0
  52. package/scripts/auditable-demo-renditions.mjs +264 -0
  53. package/scripts/auditable-demo.mjs +24 -30
  54. package/scripts/build-contract-core.mjs +58 -3
  55. package/scripts/buildchain-cli-help.mjs +8 -0
  56. package/scripts/buildchain-patrol.mjs +9 -0
  57. package/scripts/check-inventory.mjs +13 -2
  58. package/scripts/dev-alpha-candidate-patrol.mjs +45 -48
  59. package/scripts/dev-delivery-proof.mjs +193 -0
  60. package/scripts/dev-delivery-warrant.mjs +426 -0
  61. package/scripts/dev-pr-auto-merge.mjs +488 -46
  62. package/scripts/dev-pr-delivery-warrant.mjs +209 -0
  63. package/scripts/gate-profile-core.mjs +24 -0
  64. package/scripts/generate-site-bundle.mjs +2 -2
  65. package/scripts/git-fetch-process-tree.mjs +142 -0
  66. package/scripts/lifecycle-substage-evidence.mjs +274 -0
  67. package/scripts/locked-source-checkout.mjs +6 -3
  68. package/scripts/release-candidate-resolver.mjs +35 -3
  69. package/scripts/resolve-artifact-transfer-mode.mjs +9 -0
  70. package/scripts/resolve-build-contract.mjs +7 -0
  71. package/scripts/resume-from-candidate-run.mjs +498 -0
  72. package/scripts/route-offline-runners.mjs +1 -0
  73. package/scripts/run-lifecycle-core.mjs +9 -9
  74. package/scripts/shifu-gate-profile.mjs +10 -16
  75. package/scripts/site-capability-metadata.mjs +15 -0
@@ -167,6 +167,17 @@ release-PR or trusted-manual paths.
167
167
 
168
168
  ## Consumer qualification handoff
169
169
 
170
+ For managed release candidates, a consumer whose Gate can only be decided
171
+ after the exact candidate bytes exist may provide `publication-gate-command`.
172
+ The sealed authority downloads and recomputes the RC evidence first, checks out
173
+ the exact admitted consumer source without credentials, and runs that command
174
+ with read-only evidence paths. The command must write one complete qualifying
175
+ Shifu aggregate to `BUILDCHAIN_PUBLICATION_GATE_RESULT_PATH`. Buildchain then
176
+ checks the aggregate digest and source binding before assembling the admission;
177
+ the later consumer predicate and provider action still revalidate the same
178
+ complete aggregate. A precomputed aggregate, the command, and an explicit
179
+ no-Gate decision are mutually exclusive.
180
+
170
181
  Consumers may explicitly opt in to a final, consumer-owned qualification
171
182
  predicate. Buildchain then transports the complete Gate aggregate alongside the
172
183
  sealed capability instead of reducing it to a summary. The capability binds the
@@ -8,7 +8,7 @@ confidence: high
8
8
  sensitivity: public
9
9
  evidence_grade: A
10
10
  review_state: unreviewed
11
- last_reviewed: 2026-07-31
11
+ last_reviewed: 2026-08-06
12
12
  ai_provenance:
13
13
  model_family: GPT-5
14
14
  product: Codex
@@ -97,6 +97,15 @@ state for `vX.Y.Z-alpha.N` and cannot resume it with the same transaction
97
97
  identity, alpha version selection must advance to the next prerelease instead
98
98
  of reusing or overwriting that failed transaction slot.
99
99
 
100
+ `release-candidate-promote.yml` can establish or restore this state from an
101
+ older successful candidate run through the documented fresh-event recovery
102
+ inputs. The recovery receipt and sealed bundle are verified before the action
103
+ reads or creates transaction state. If `resume-transaction-id` is supplied,
104
+ the restored durable/local transaction must already exist with that exact id;
105
+ a missing or different id fails before provider mutation. An absent transaction
106
+ is created only when no expected existing identity was requested. See
107
+ [Release Candidate: Resume from an existing candidate run](release-candidate.md#resume-from-an-existing-candidate-run).
108
+
100
109
  ## Lifecycle
101
110
 
102
111
  Repositories declare publish work in `.buildchain/buildchain.toml`:
@@ -117,19 +117,96 @@ and resolves each remaining floating shell/runtime ref exactly once. Every
117
117
  later checkout and delegated promotion receives those immutable SHAs, so a
118
118
  channel tag moving during the run cannot mix two Buildchain revisions.
119
119
 
120
- If a promote-only run failed after its consumer commit was already merged and
121
- its PR-stage artifacts were built, rerun the complete failed workflow after the
122
- fixed Buildchain channel is published:
120
+ ## Resume from an existing candidate run
123
121
 
124
- ```bash
125
- gh run rerun <run-id> --repo <owner>/<consumer>
122
+ Do not rely on `gh run rerun` after a reusable-workflow startup or router
123
+ failure. GitHub documents two different rerun behaviors: a full rerun may use a
124
+ called workflow from the currently specified ref, while a failed-job rerun uses
125
+ the same called-workflow commit as the original attempt. Neither operation is a
126
+ supported way to create a job graph that GitHub failed to resolve at startup.
127
+ See GitHub's [reusable workflow rerun behavior](https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations#behavior-of-reusable-workflows-when-re-running-jobs)
128
+ and [workflow rerun identity rules](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/re-run-workflows-and-jobs).
129
+
130
+ The supported recovery boundary is a new `workflow_dispatch` (or another new
131
+ caller event) that invokes `release-candidate-promote.yml` and supplies the old
132
+ candidate run explicitly:
133
+
134
+ ```yaml
135
+ name: Resume release candidate
136
+ on:
137
+ workflow_dispatch:
138
+ inputs:
139
+ candidate-run-id: { required: true, type: string }
140
+ target-sha: { required: true, type: string }
141
+ expected-tree: { required: true, type: string }
142
+ candidate-runtime-sha: { required: true, type: string }
143
+ buildchain-runtime-sha: { required: true, type: string }
144
+
145
+ jobs:
146
+ resume:
147
+ uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@<exact-current-buildchain-sha>
148
+ permissions:
149
+ actions: write
150
+ checks: write
151
+ contents: write
152
+ id-token: write
153
+ pull-requests: write
154
+ secrets: inherit
155
+ with:
156
+ buildchain-ref: ${{ inputs.buildchain-runtime-sha }}
157
+ channel: alpha
158
+ target-ref: alpha/v3/v3.0
159
+ target-sha: ${{ inputs.target-sha }}
160
+ artifact-name: product
161
+ artifact-patterns: product-package-*
162
+ release-candidate-workflow-file: build.yml
163
+ release-candidate-workflow-name: Build
164
+ resume-candidate-repository: ${{ github.repository }}
165
+ resume-candidate-run-id: ${{ inputs.candidate-run-id }}
166
+ resume-expected-workflow-file: build.yml
167
+ resume-expected-workflow-name: Build
168
+ resume-expected-source-tree: ${{ inputs.expected-tree }}
169
+ resume-expected-candidate-runtime-sha: ${{ inputs.candidate-runtime-sha }}
170
+ resume-buildchain-runtime-sha: ${{ inputs.buildchain-runtime-sha }}
171
+ publish-transaction-override: true
126
172
  ```
127
173
 
128
- Use a complete rerun, not `--failed`, so GitHub resolves the reusable workflow
129
- again. The release-candidate resolver reuses the existing candidate artifacts,
130
- and the durable publication transaction makes the recovery idempotent; do not
131
- open a replacement consumer PR or rebuild the native matrix solely for this
132
- router failure.
174
+ `resume-expected-candidate-root` may replace `resume-expected-source-tree`, or
175
+ callers may provide both. `resume-transaction-id` is optional; when supplied it
176
+ must identify an already durable transaction before any provider mutation.
177
+
178
+ Recovery downloads and checks the successful `pull_request` run, active
179
+ workflow file and name, same-repository merged PR, trusted repository
180
+ association, target ancestry, promotion tree, Passport candidate root,
181
+ build-summary root, controller receipts, platform matrix, artifact archive
182
+ size/digest, every manifest file, and every product payload byte. Tree equality
183
+ alone is never admission. A different promotion commit is allowed only when all
184
+ of those identities still agree.
185
+
186
+ The recovery path conditionally skips consumer dependency installation and all
187
+ product `install`, `build`, `verify`, and platform-matrix jobs. It restores the
188
+ downloaded bytes as a content-addressed sealed bundle, so npm publication uses
189
+ the original `.tgz`; it may regenerate only Buildchain-owned receipts,
190
+ attestations, signatures, Release Passport data, publication, and readback.
191
+
192
+ Success emits `kungfu-buildchain-release-candidate-recovery/v1` with
193
+ `action: reused`, the original run/source/tree, candidate and artifact roots,
194
+ the skipped stages, current tooling SHA, transaction identity/state, and an
195
+ exact receipt root. The receipt is uploaded as an Actions artifact and staged
196
+ with immutable GitHub Release Passport assets.
197
+
198
+ Missing or expired artifacts, archive or payload digest drift, tree/root,
199
+ repository/workflow/channel/target mismatch, untrusted run/PR provenance,
200
+ incomplete controller evidence, and transaction conflict fail closed with an
201
+ error code and next action. Buildchain never converts recovery failure into a
202
+ hidden full rebuild. A repository owner must choose a new candidate build
203
+ explicitly.
204
+
205
+ When a durable transaction is absent, recovery seals one from the verified
206
+ candidate. Existing `sealed`, `publishing`, `package-published`, `finalizing`,
207
+ and `complete` transactions use the normal idempotent state machine. Matching
208
+ registry and GitHub bytes are preserved, only missing publication work is
209
+ performed, and conflicting public digests enter `repair_required`.
133
210
 
134
211
  By default, the wrapper forwards GitHub Release publication to the underlying
135
212
  `promote-buildchain-ref` semver model. Once the release transaction is complete,
@@ -192,12 +269,29 @@ short-lived admission JSON in repository-specific workflow code:
192
269
  ```
193
270
 
194
271
  `publication-auto-no-gate` is an explicit consumer decision, not a default. A
195
- consumer with a Shifu Gate registry supplies `publication-gate-aggregate-json`
196
- instead. Buildchain still requires caller-owned RC evidence, an exact authority
272
+ consumer with a Shifu Gate registry either supplies
273
+ `publication-gate-aggregate-json`, or supplies a source-controlled
274
+ `publication-gate-command` that writes the aggregate to
275
+ `BUILDCHAIN_PUBLICATION_GATE_RESULT_PATH`. The command runs from the exact
276
+ consumer source in the credential-free sealed-authority job, after Buildchain
277
+ has downloaded the exact RC passport, summary, controller receipt, manifests,
278
+ and payload bytes. It can read those inputs through
279
+ `BUILDCHAIN_PUBLICATION_EVIDENCE_ROOT`; it receives no publication token, OIDC
280
+ permission, or provider write permission. Buildchain validates the aggregate
281
+ digest and exact source binding before it seals a capability. Exactly one of
282
+ the supplied aggregate, consumer command, or explicit no-Gate decision is
283
+ allowed. Buildchain still requires caller-owned RC evidence, an exact authority
197
284
  runtime and source SHA, a repository-local publisher workflow, matching npm
198
285
  target/package identity or exact caller-bound GitHub Release target, and a
199
286
  qualifying control-plane audit.
200
287
 
288
+ Promotion resolves the complete PR-stage workflow, not only the first required
289
+ status job that becomes green. `release-candidate-wait-seconds` bounds that
290
+ wait and defaults to three hours so long native builds can finish controller,
291
+ publication-tail, and retained-evidence jobs without racing a merged promotion.
292
+ An incomplete or failed workflow still fails closed; the longer bound does not
293
+ turn a partial required-check result into candidate evidence.
294
+
201
295
  GitHub-Release-only consumers use the same managed admission without inventing
202
296
  an npm package identity:
203
297
 
@@ -487,6 +487,15 @@ same slow checks. Buildchain supports GitHub merge queues for that channel
487
487
  shape. The queue validates the projected merged result and serializes the final
488
488
  ref update, so concurrent channel movement no longer invalidates the candidate.
489
489
 
490
+ GitHub Merge Queue does not by itself decide which candidate may spend a long
491
+ native proof before enqueue. Repositories with that workload use the
492
+ [Dev Delivery Warrant Queue](dev-delivery-warrant.md) as the durable,
493
+ FIFO-aging scheduling and fencing authority before native queue admission. A
494
+ selected Warrant owns one complete delivery attempt and later candidates remain
495
+ visibly queued; GitHub still owns the exact `merge_group` proof and final ref
496
+ mutation. Workflow concurrency remains only a process critical section and is
497
+ not fairness or ownership authority.
498
+
490
499
  Every required workflow must handle both `pull_request` and `merge_group`
491
500
  before the queue is enabled. Queue runs do not provide
492
501
  `github.event.pull_request`; required workflows must use the checked-out
@@ -545,6 +554,33 @@ inputs: target dev branch, required status/check names, ready and block labels,
545
554
  allowed work-branch prefixes, review requirements, maximum merges per run,
546
555
  merge method, and dry-run mode.
547
556
 
557
+ Agent delivery uses the targeted Buildchain command instead of relying on a
558
+ scheduled scan:
559
+
560
+ ```sh
561
+ buildchain dev pr-admit \
562
+ --repository kungfu-systems/example \
563
+ --branch dev/v3/v3.0 \
564
+ --pull-request 123 \
565
+ --expected-head 0123456789abcdef0123456789abcdef01234567
566
+ ```
567
+
568
+ The default is a mutation-free plan. After reviewing it, add `--execute` to
569
+ establish the configured readiness label for only that PR and exact head, read
570
+ the state back, and attempt native queue admission. Repeating execute is
571
+ idempotent: an exact matching queue entry is adopted, not submitted again. A
572
+ stale head or base, fork, draft, block label, missing approval, failed check,
573
+ active predecessor, or rejected enqueue exits nonzero. Execute mode also
574
+ creates or updates an exact-head PR comment and named commit status containing
575
+ the current state, reason, receipt root, and copyable next action. The JSON
576
+ receipt remains the complete content-addressed evidence.
577
+
578
+ GitHub auto-merge is observed but is never readiness or admission authority.
579
+ Approval plus green checks plus auto-merge enabled does not qualify a PR that
580
+ lacks explicit Buildchain delivery intent. The targeted workflow interface
581
+ exposes the same contract through `expected-pr-number` and
582
+ `expected-head-sha`; cadence patrol runs leave those inputs empty.
583
+
548
584
  The workflow defaults are conservative. A PR is skipped unless it targets the
549
585
  configured dev line, is not a draft, has the ready label, has no block label,
550
586
  comes from the same repository, uses an allowed work-branch prefix, has a
@@ -565,6 +601,15 @@ admission runs; GitHub still owns the atomic queue and protected-ref update.
565
601
  Repositories may explicitly select `landing-mode: direct` only when the target
566
602
  branch has no native queue. Queue presence always disables the direct path.
567
603
 
604
+ For slow candidates on a frequently advancing dev line, the optional
605
+ [Dev Delivery Warrant Queue](dev-delivery-warrant.md) adds durable FIFO plus
606
+ aging scheduling before native queue admission. It separates reusable source
607
+ qualification from exact merge-group integration, uses expected-old Git-ref
608
+ updates and fenced leases, and keeps the PR head unchanged when only dev moves.
609
+ The reusable caller supports `off`, read-only `shadow`, and fail-closed
610
+ `required` rollout modes. GitHub Merge Queue remains the final protected-ref
611
+ authority in every mode.
612
+
568
613
  The canonical consumer required check context is `check / check`, matching the
569
614
  reusable workflow call plus its `check` job. Buildchain's own `Verify` workflow
570
615
  emits the repository-local context `check`, so Buildchain self-promotion,
@@ -687,6 +732,13 @@ The cadence names describe patrol intensity, not release cadence:
687
732
  - monthly patrol is for structural drift checks that should not block ordinary
688
733
  development velocity.
689
734
 
735
+ Every cadence result is typed `runKind: cadence-patrol` with
736
+ `qualification: false`. A run with no open candidates reports
737
+ `no-op-no-candidates`; a run where every candidate is skipped reports
738
+ `no-op-all-skipped`. Either no-op can keep maintenance green, but neither is a
739
+ delivery qualification, a targeted admission receipt, or evidence that an
740
+ expected PR entered the merge queue.
741
+
690
742
  Stable Candidate Patrol is separate from those maintenance cadences because its
691
743
  caller-owned cron is a release-intent window. Its candidate ledger and selection
692
744
  remain generic; registry-specific side effects still run through the normal
@@ -774,6 +774,9 @@ Direct GitHub Artifact payloads default to compression level `0`. Buildchain
774
774
  artifacts are commonly already-compressed archives; storing them without a
775
775
  second compression pass shortens the upload window while preserving the same
776
776
  artifact name, run/id/digest binding, retention, and no-overwrite behavior.
777
+ Direct build and signed-finalization payload uploads include hidden files under
778
+ the caller-declared artifact paths, matching the relay path so manifest-bound
779
+ dotfiles are not silently removed in transit.
777
780
  Callers may select `1` through `9` for payloads that materially benefit from
778
781
  compression. Manifests and diagnostics retain their existing small-artifact
779
782
  behavior.
@@ -792,7 +795,14 @@ jobs:
792
795
  artifact-relay-s3-prefix: ${{ vars.BUILDCHAIN_ARTIFACT_RELAY_S3_PREFIX }}
793
796
  ```
794
797
 
795
- In relay mode, each self-hosted platform job uploads the heavy payload files to
798
+ The mode is a policy for platforms that run outside GitHub. GitHub-hosted
799
+ platforms always upload directly with `actions/upload-artifact`, even when a
800
+ mixed matrix requests `s3-to-github-artifacts`; they never send their payloads
801
+ through S3 or the replay job. Buildchain recognizes its hosted presets and the
802
+ standard hosted runner labels. Custom matrices with non-standard hosted labels
803
+ must declare `"githubHosted": true` on those platform rows.
804
+
805
+ For remaining relay-mode platforms, each job uploads the heavy payload files to
796
806
  S3 and uploads only a small `relay-manifest.json` to GitHub. A GitHub-hosted
797
807
  `relay-artifacts` job then assumes the configured download role, downloads the
798
808
  payloads from S3, verifies every file by SHA256, and re-uploads the normal
@@ -135,7 +135,18 @@ a shell string.
135
135
 
136
136
  Projects may also pass non-sensitive scalar environment through
137
137
  `gate-environment-json`; Buildchain validates the JSON shape and forwards it
138
- without interpreting names or values. Cache profile references use the same
138
+ without interpreting names or values. A custom `platforms-json` entry may add
139
+ an `environment` object when a value is platform-specific; those scalars
140
+ override the shared environment only for that matrix job. For example, a
141
+ GitHub-hosted Linux lane can select an installed compiler without leaking the
142
+ same setting into macOS or Windows:
143
+
144
+ ```yaml
145
+ platforms-json: >-
146
+ [{"id":"linux-x64","name":"Linux x64","platform":"linux","runner":"[\"ubuntu-24.04\"]","capabilities":["node","native-toolchain"],"environment":{"CC":"gcc-14","CXX":"g++-14"}}]
147
+ ```
148
+
149
+ Cache profile references use the same
139
150
  opaque `shifu-cache-profile-ref` and `shifu-cache-profile-digest` inputs as the
140
151
  reusable build. Do not place tokens, credentials, or other secrets in workflow
141
152
  inputs or Gate receipts.
@@ -79,6 +79,8 @@ repository changes are patch".
79
79
 
80
80
  | Date | Action | Line | Faces | Class | Rationale | PR |
81
81
  | ---------- | ------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
82
+ | 2026-08-05 | extend-minor | `v3.0` | auditable-demo-scenario, auditable-demo-capture, auditable-demo-adapter | additive | Add an opt-in deterministic readable-playback declaration that preserves captured terminal payloads and order while normalizing only presentation timing; omitted playback continues to use observed PTY timestamps, and existing composition modes remain unchanged. | |
83
+ | 2026-08-04 | extend-minor | `v3.0` | dev-delivery-warrant-queue, source-qualification-proof, integration-delivery-proof, dev-delivery-cli, reusable-dev-delivery-workflows | additive | Add durable fair and fenced protected-dev scheduling plus split source/integration proof contracts. Existing PR admission remains available through explicit `off` and `shadow` rollout modes; no existing command, export, or release flow is removed. | |
82
84
  | 2026-08-01 | extend-minor | `v3.0` | cli-reference-registry, node-api-symbol-registry, golden-path-manual | additive | Add generated, drift-checked CLI and Node API reference registries to the public site bundle, plus a package-tested first-user Golden Path; existing command execution and import semantics remain unchanged. | |
83
85
  | 2026-07-31 | extend-minor | `v3.0` | auditable-demo-workflow, auditable-demo-media-profile, auditable-demo-media-receipt | additive | Add an opt-in responsive profile that binds source-resolution and exact 1280x720 MP4/WebM/GIF renditions to one Gate and receipt while rejecting upscales, aspect-ratio drift, and profile changes between Gate-only and full-render paths. | |
84
86
  | 2026-07-31 | extend-minor | `v3.0` | release-candidate-family-evidence, release-passport-evidence-attachment, promotion-action, release-passport-cli | additive | Restore all-ref v2 parity for optional Initiative-family candidate binding and typed product-owned release evidence attachments while retaining Kungfu native Family State authority and the newer v3 post-activation released-evidence stage. | #2089 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungfu-tech/buildchain",
3
- "version": "3.0.6-alpha.1",
3
+ "version": "3.0.6-alpha.3",
4
4
  "private": false,
5
5
  "description": "Buildchain Release Passport, release governance, CLI toolkit, and site facts.",
6
6
  "repository": "https://github.com/kungfu-systems/buildchain",
@@ -28,6 +28,7 @@
28
28
  "./cache-evidence": "./packages/core/cache-evidence.js",
29
29
  "./controller-evidence": "./packages/core/controller-evidence.js",
30
30
  "./diagnostics": "./packages/core/diagnostics.js",
31
+ "./dev-delivery-warrant": "./packages/core/dev-delivery-warrant.js",
31
32
  "./homebrew": "./packages/core/homebrew.js",
32
33
  "./issue-reporting": "./packages/core/issue-reporting.js",
33
34
  "./kfd": "./packages/core/kfd.js",
@@ -50,6 +51,7 @@
50
51
  "./github-governance-authority": "./packages/core/github-governance-authority.js",
51
52
  "./kfd-gate": "./packages/core/kfd-gate.js",
52
53
  "./release-candidate": "./packages/core/release-candidate.js",
54
+ "./release-candidate-recovery": "./packages/core/release-candidate-recovery.js",
53
55
  "./stable-candidate-ledger": "./packages/core/stable-candidate-ledger.js",
54
56
  "./release-passport": "./packages/core/release-passport.js",
55
57
  "./release-passport-contract": "./packages/core/release-passport-contract.js",
@@ -210,7 +210,7 @@ export function createBuildchainContractWorld({
210
210
  path: ".github/workflows/release-candidate-promote.yml",
211
211
  publicRef: `${pkg.repository ? "kungfu-systems/buildchain" : "buildchain"}/.github/workflows/release-candidate-promote.yml@${majorLine}`,
212
212
  requiredInputs: ["channel"],
213
- requiredOutputs: ["promoted-sha", "built-source-sha", "release-candidate-artifact"],
213
+ requiredOutputs: ["promoted-sha", "built-source-sha", "release-candidate-artifact", "release-candidate-action"],
214
214
  breakingDefaults: {
215
215
  channelDefault: "auto",
216
216
  alphaShellDefault: `${majorLine}-alpha`,
@@ -225,6 +225,15 @@ export function createBuildchainContractWorld({
225
225
  "buildchain-stable-contract-lock-path",
226
226
  "release-candidate-workflow-file",
227
227
  "release-candidate-workflow-name",
228
+ "resume-candidate-repository",
229
+ "resume-candidate-run-id",
230
+ "resume-expected-workflow-file",
231
+ "resume-expected-workflow-name",
232
+ "resume-expected-source-tree",
233
+ "resume-expected-candidate-root",
234
+ "resume-expected-candidate-runtime-sha",
235
+ "resume-buildchain-runtime-sha",
236
+ "resume-transaction-id",
228
237
  "publish-required-artifacts-json",
229
238
  "release-passport-kfd-1-witness-jsons",
230
239
  "release-passport-kfd-2-claim-jsons",
@@ -267,11 +276,17 @@ export function createBuildchainContractWorld({
267
276
  "train and exact-SHA runtime overrides remain limited to trusted workflow_dispatch actors",
268
277
  "promotion reuses PR-stage release-candidate artifacts",
269
278
  "promotion does not run the heavy native build matrix",
279
+ "a fresh workflow event can recover an exact successful candidate run after startup or router failure",
280
+ "recovery validates repository, workflow, PR, ancestry, tree, candidate roots, controller evidence, manifests, archive digests, and payload bytes before mutation",
281
+ "recovery emits action reused and never silently falls back to a full build",
270
282
  "built source and promotion channel SHA are recorded separately",
271
283
  "contract drift is checked before release-candidate resolution and publish",
272
284
  "publish-gate source locks are created by the wrapper and enforced by promote-buildchain-ref before publish side effects",
273
285
  "GitHub Release passport and evidence publication is delegated to promote-buildchain-ref after the semver release transaction completes",
274
286
  ],
287
+ compatibleBreakingDigests: [
288
+ "sha256:acd401cfc46450115a3763fd4b679d85f185e8757ebd52510d6262e1533df4cf",
289
+ ],
275
290
  }),
276
291
  surface(root, {
277
292
  id: "advanced-release-candidate-promote",
@@ -279,7 +294,7 @@ export function createBuildchainContractWorld({
279
294
  path: ".github/workflows/.release-candidate-promote.yml",
280
295
  publicRef: `${pkg.repository ? "kungfu-systems/buildchain" : "buildchain"}/.github/workflows/.release-candidate-promote.yml@${majorLine}`,
281
296
  requiredInputs: ["channel"],
282
- requiredOutputs: ["promoted-sha", "built-source-sha", "release-candidate-artifact"],
297
+ requiredOutputs: ["promoted-sha", "built-source-sha", "release-candidate-artifact", "release-candidate-action"],
283
298
  breakingDefaults: {
284
299
  promoteOnlyReleaseCandidate: true,
285
300
  requiredStatusCheck: "check / check",
@@ -298,10 +313,23 @@ export function createBuildchainContractWorld({
298
313
  "promotion-publication-channel",
299
314
  "promotion-target-ref",
300
315
  "promotion-override-used",
316
+ "resume-candidate-repository",
317
+ "resume-candidate-run-id",
318
+ "resume-expected-workflow-file",
319
+ "resume-expected-workflow-name",
320
+ "resume-expected-source-tree",
321
+ "resume-expected-candidate-root",
322
+ "resume-expected-candidate-runtime-sha",
323
+ "resume-buildchain-runtime-sha",
324
+ "resume-transaction-id",
301
325
  ],
302
326
  guarantees: [
303
327
  "advanced promotion verifies routed shell, runtime, lock, publication channel, and target bindings before candidate resolution",
304
328
  "promotion reuses PR-stage release-candidate artifacts and does not run the heavy native build matrix",
329
+ "resume-from-candidate-run is fail-closed and uses a fresh caller event instead of rerunning a frozen startup graph",
330
+ ],
331
+ compatibleBreakingDigests: [
332
+ "sha256:aa30f22e3af0a89841310bdbdc900844dd95a66974db173fa140a71bbd7e82c0",
305
333
  ],
306
334
  }),
307
335
  surface(root, {
@@ -24,6 +24,7 @@ const DESCRIPTORS = Object.freeze([
24
24
  [".github/workflows/build-surface-fixture.yml", "non-publication-oidc"],
25
25
  [".github/workflows/build.yml", "non-publication-oidc"],
26
26
  [".github/workflows/buildchain-alpha-self-dogfood.yml", "non-publication-oidc"],
27
+ [".github/workflows/buildchain-dev-delivery.yml", "governance-write"],
27
28
  [".github/workflows/buildchain-patrol-daily.yml", "governance-write"],
28
29
  [".github/workflows/buildchain-patrol-monthly.yml", "governance-write"],
29
30
  [".github/workflows/buildchain-patrol-weekly.yml", "governance-write"],
@@ -32,6 +33,8 @@ const DESCRIPTORS = Object.freeze([
32
33
  [".github/workflows/buildchain-stable-candidate-patrol.yml", "governance-write"],
33
34
  [".github/workflows/dev-qualification-patrol.yml", "governance-write"],
34
35
  [".github/workflows/dev-alpha-candidate-patrol.yml", "governance-write"],
36
+ [".github/workflows/dev-delivery-warrant-close.yml", "governance-write"],
37
+ [".github/workflows/dev-delivery-warrant-cancel.yml", "governance-write"],
35
38
  [".github/workflows/dev-merge-queue-governance.yml", "governance-write"],
36
39
  [".github/workflows/dev-pr-auto-merge.yml", "governance-write"],
37
40
  [".github/workflows/github-governance-audit.yml", "governance-write"],
@@ -75,7 +78,6 @@ export function buildchainPublicationAuthorityDescriptors() {
75
78
  runnerPolicy: publicationCapable ? "qualified-measured" : "unqualified",
76
79
  }));
77
80
  }
78
-
79
81
  export function createBuildchainPublicationAuthorityRegistry({ root = process.cwd() } = {}) {
80
82
  const workflowsDir = path.join(root, ".github", "workflows");
81
83
  const workflows = fs.readdirSync(workflowsDir)
@@ -1,6 +1,7 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
 
3
3
  import crypto from "node:crypto";
4
+ import { normalizeChannelCandidateSelection } from "./channel-promotion-baseline.js";
4
5
 
5
6
  export const CHANNEL_CANDIDATE_DECISION_SCHEMA =
6
7
  "kungfu-buildchain-channel-candidate-decision/v1";
@@ -95,27 +96,7 @@ export function decideChannelCandidate(input) {
95
96
  throw new Error("sourceBranch and targetBranch must differ");
96
97
  const sourceSha = sha(input.sourceSha, "sourceSha");
97
98
  const targetSha = sha(input.targetSha, "targetSha");
98
- const selection = input.selection
99
- ? {
100
- mode: required(input.selection.mode, "selection.mode"),
101
- observedSourceHeadSha: sha(
102
- input.selection.observedSourceHeadSha,
103
- "selection.observedSourceHeadSha",
104
- ),
105
- skippedNewerCommitCount: Number(
106
- input.selection.skippedNewerCommitCount || 0,
107
- ),
108
- }
109
- : undefined;
110
- if (
111
- selection &&
112
- (!Number.isSafeInteger(selection.skippedNewerCommitCount) ||
113
- selection.skippedNewerCommitCount < 0)
114
- ) {
115
- throw new Error(
116
- "selection.skippedNewerCommitCount must be a non-negative integer",
117
- );
118
- }
99
+ const selection = normalizeChannelCandidateSelection(input.selection);
119
100
  const now = required(input.now || new Date().toISOString(), "now");
120
101
  const maxAgeSeconds = Number(input.maxAgeSeconds ?? 7 * 24 * 60 * 60);
121
102
  if (!Number.isSafeInteger(maxAgeSeconds) || maxAgeSeconds <= 0) {