@kungfu-tech/buildchain 3.0.5 → 3.0.6-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/actions/macos-credential-island/README.md +8 -0
- package/bin/buildchain.mjs +1 -1
- package/contracts/auditable-demo-media-profiles-v1.json +61 -0
- package/contracts/auditable-demo-scenario-v1.schema.json +164 -0
- package/contracts/evidence/auditable-demo-responsive-web-delivery-v1.json +3 -3
- package/contracts/evidence/auditable-demo-web-delivery-v1.json +3 -3
- package/dist/site/buildchain-contract.json +107 -26
- package/dist/site/buildchain-site.json +121 -49
- package/dist/site/capability-registry.json +3 -3
- package/dist/site/cli-registry.json +9 -3
- package/dist/site/controller-registry.json +27 -3
- package/dist/site/kfd-claims.json +101 -15
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +10 -9
- package/dist/site/node-api-registry.json +540 -31
- package/dist/site/page-registry.json +105 -29
- package/dist/site/public-surface-audit.json +184 -11
- package/dist/site/publication-authority-registry.json +62 -1
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +13 -13
- package/dist/site/workflow-registry.json +118 -4
- package/docs/MAP.md +4 -1
- package/docs/auditable-demo.md +90 -7
- package/docs/aws-us-elastic-runner-burst-plane.md +151 -16
- package/docs/cli-reference.md +35 -2
- package/docs/dev-alpha-candidate-patrol.md +14 -5
- package/docs/dev-qualification-patrol.md +108 -0
- package/docs/node-api-reference.md +123 -72
- package/docs/publish-transaction.md +7 -5
- package/docs/release-flow.md +4 -0
- package/docs/release-governance.md +39 -0
- package/docs/release-propagation.md +93 -0
- package/docs/reusable-build-surface.md +53 -12
- package/docs/stable-candidate-patrol.md +5 -2
- package/package.json +1 -1
- package/packages/core/buildchain-contract.js +36 -1
- package/packages/core/buildchain-publication-authority.js +3 -0
- package/packages/core/public-surface-audit.js +4 -35
- package/packages/core/release-propagation-agent-entry.js +185 -0
- package/packages/core/release-propagation-pickup.js +387 -0
- package/packages/core/release-propagation-push.js +293 -0
- package/packages/core/release-propagation-release.js +61 -18
- package/packages/core/release-propagation-stage-evidence.js +36 -0
- package/packages/core/release-propagation-work.js +8 -4
- package/packages/core/release-propagation.js +27 -2
- package/packages/core/workflow-call-contract.js +308 -0
- package/packages/core/workflow-yaml-contract.js +272 -0
- package/scripts/artifact-signing-controller-core.mjs +525 -0
- package/scripts/artifact-signing-controller.mjs +302 -0
- package/scripts/artifact-signing-delegation.mjs +51 -3
- package/scripts/auditable-demo-platform.mjs +564 -0
- package/scripts/auditable-demo-renditions.mjs +7 -2
- package/scripts/auditable-demo-transport-smoke.mjs +176 -0
- package/scripts/auditable-demo.mjs +27 -21
- package/scripts/aws-macos-jit-controller-core.mjs +389 -0
- package/scripts/aws-macos-jit-controller-runtime.mjs +82 -0
- package/scripts/aws-macos-jit-controller.mjs +558 -0
- package/scripts/aws-macos-jit-job-controller.mjs +401 -0
- package/scripts/aws-windows-jit-campaign-core.mjs +296 -0
- package/scripts/aws-windows-jit-campaign.mjs +202 -0
- package/scripts/aws-windows-jit-controller-core.mjs +20 -2
- package/scripts/aws-windows-jit-controller.mjs +184 -109
- package/scripts/aws-windows-jit-core.mjs +21 -3
- package/scripts/aws-windows-jit.mjs +2 -0
- package/scripts/build-standalone-binary.mjs +6 -0
- package/scripts/buildchain-cli-help.mjs +2 -1
- package/scripts/capture-package-release-propagation.mjs +24 -1
- package/scripts/check-inventory.mjs +6 -0
- package/scripts/compiler-cache-evidence.mjs +90 -7
- package/scripts/dev-alpha-candidate-patrol.mjs +80 -5
- package/scripts/dev-pr-auto-merge.mjs +4 -4
- package/scripts/dev-qualification-patrol.mjs +594 -0
- package/scripts/dispatch-artifact-signing-authority.mjs +312 -61
- package/scripts/finalize-native-artifact-signing-result.mjs +37 -15
- package/scripts/generate-site-bundle.mjs +5 -0
- package/scripts/inspect-artifact-signing-requests.mjs +12 -0
- package/scripts/locked-source-checkout.mjs +17 -3
- package/scripts/release-propagation.mjs +150 -2
- package/scripts/run-lifecycle-core.mjs +25 -0
- package/scripts/site-capability-metadata.mjs +1 -1
- package/scripts/stable-candidate-patrol.mjs +30 -4
- package/scripts/workflow-call-contract.mjs +133 -0
|
@@ -415,9 +415,10 @@ first run can stop at `finalizing` after registry publication. If the reviewed
|
|
|
415
415
|
merge commit later contains that exact transaction release material but the
|
|
416
416
|
exact tag is still absent, a retry performs finalization only: it reloads the
|
|
417
417
|
same durable source, release material, tooling, evidence, version, and target
|
|
418
|
-
bindings; creates the exact
|
|
419
|
-
|
|
420
|
-
|
|
418
|
+
bindings; creates the exact tag at the transaction source SHA; moves floating
|
|
419
|
+
refs to the transaction release SHA; and completes the passport from the
|
|
420
|
+
transaction source tree. It does not rerun the provider mutation and does not
|
|
421
|
+
authorize the newer composite channel tree
|
|
421
422
|
as published material. A different source tree still requires a new version and
|
|
422
423
|
a fresh release candidate.
|
|
423
424
|
|
|
@@ -536,8 +537,9 @@ inside the mutation boundary.
|
|
|
536
537
|
|
|
537
538
|
If finalization fails after an exact Git tag is created, the next run reads the
|
|
538
539
|
durable `finalizing` state, verifies the exact tag points at the recorded
|
|
539
|
-
|
|
540
|
-
|
|
540
|
+
source SHA (while accepting legacy release/material targets for recovery), and
|
|
541
|
+
retries the remaining floating refs. An exact tag at an unrelated SHA is a
|
|
542
|
+
material conflict and blocks recovery.
|
|
541
543
|
|
|
542
544
|
## CLI Recovery
|
|
543
545
|
|
package/docs/release-flow.md
CHANGED
|
@@ -96,6 +96,10 @@ published artifacts are already durable.
|
|
|
96
96
|
The intended governance split is:
|
|
97
97
|
|
|
98
98
|
- exact tags such as `v3.0.2` and `v3.0.3-alpha.0` are immutable audit refs;
|
|
99
|
+
- for publish transactions, the exact tag points to the transaction
|
|
100
|
+
`source_sha`, matching package-registry source metadata such as npm
|
|
101
|
+
`gitHead`; generated version-state commits remain on protected branches and
|
|
102
|
+
floating channel refs;
|
|
99
103
|
- floating tags such as `v3`, `v3.0`, `v3.0-alpha`, and `v3-alpha` are mutable channel refs
|
|
100
104
|
owned by the Buildchain promotion token;
|
|
101
105
|
- protected branches still require reviewed channel PRs before Buildchain can
|
|
@@ -575,6 +575,38 @@ context shape into the other. Consumer repositories can keep their context
|
|
|
575
575
|
stable while changing the actual verification command declaratively in
|
|
576
576
|
`buildchain.toml`:
|
|
577
577
|
|
|
578
|
+
Before a release caller is merged, consumers should also verify its exact
|
|
579
|
+
reusable-workflow call contract. The checker reads the caller and an already
|
|
580
|
+
checked-out exact Buildchain commit; it never resolves a floating ref or starts
|
|
581
|
+
a release. It rejects unknown or missing inputs and secrets, literal type
|
|
582
|
+
drift, insufficient permissions, untrusted event classes, and a caller pin that
|
|
583
|
+
does not equal the checked callee commit. Defaults, workflow bytes, and the
|
|
584
|
+
complete interface are bound into `contractRoot`; the receipt additionally
|
|
585
|
+
binds the caller commit/tree and both workflow digests.
|
|
586
|
+
|
|
587
|
+
```sh
|
|
588
|
+
node .buildchain/workflow-contract-runtime/scripts/workflow-call-contract.mjs check \
|
|
589
|
+
--caller-root . \
|
|
590
|
+
--caller-workflow .github/workflows/release-new-version.yml \
|
|
591
|
+
--caller-repository kungfu-systems/example \
|
|
592
|
+
--job promote \
|
|
593
|
+
--callee-root .buildchain/workflow-contract-runtime \
|
|
594
|
+
--callee-workflow .github/workflows/release-candidate-promote.yml \
|
|
595
|
+
--callee-repository kungfu-systems/buildchain \
|
|
596
|
+
--trusted-event workflow_dispatch \
|
|
597
|
+
--trusted-event pull_request:closed \
|
|
598
|
+
--expected-contract-root "$(cat .buildchain/release-call-contract-root)" \
|
|
599
|
+
--output .buildchain/workflow-call-receipts/release-new-version.json
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
The checkout at `.buildchain/workflow-contract-runtime` must use the same
|
|
603
|
+
40-character SHA written in the caller's `uses:` edge. To accept an intentional
|
|
604
|
+
contract change, first run without `--expected-contract-root`, review the full
|
|
605
|
+
diagnostic and exact coordinates, then replace only the committed root. The
|
|
606
|
+
ordinary PR check runs this command before any candidate or promotion dispatch.
|
|
607
|
+
Local pre-commit rehearsal may add `--allow-dirty`; that result is marked
|
|
608
|
+
`receiptReusable: false` and cannot replace the clean exact-source receipt.
|
|
609
|
+
|
|
578
610
|
```toml
|
|
579
611
|
[lifecycle.install]
|
|
580
612
|
command = "cargo fetch --locked"
|
|
@@ -831,6 +863,13 @@ must be absent or already point at accepted release material. This preserves an
|
|
|
831
863
|
immutable tag that represents a completed transaction while allowing a tag
|
|
832
864
|
collision discovered after registry publication to recover without republishing.
|
|
833
865
|
|
|
866
|
+
For package publish transactions, the immutable public version tag points to
|
|
867
|
+
the transaction `source_sha`, so registry source metadata such as npm `gitHead`
|
|
868
|
+
and the Git tag identify the same source commit. Protected branches and mutable
|
|
869
|
+
channel tags continue to point to the generated `release_sha`. Recovery accepts
|
|
870
|
+
older completed transactions whose exact tags already point to recorded release
|
|
871
|
+
or release-material SHAs, but new tags are source-bound.
|
|
872
|
+
|
|
834
873
|
Every Buildchain publish model that can run registry side effects must bind the
|
|
835
874
|
publish entrypoint to an immutable `publish-gate/*` source lock. The reusable
|
|
836
875
|
`release-candidate-promote.yml@v3` wrapper creates or updates that gate ref and
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: active
|
|
3
|
+
period: ongoing
|
|
4
|
+
theme: buildchain-release-propagation
|
|
5
|
+
doc_type: technical-reference
|
|
6
|
+
source_level: local-files
|
|
7
|
+
confidence: high
|
|
8
|
+
sensitivity: public
|
|
9
|
+
evidence_grade: A
|
|
10
|
+
review_state: unreviewed
|
|
11
|
+
last_reviewed: 2026-08-03
|
|
12
|
+
ai_provenance:
|
|
13
|
+
model_family: GPT-5
|
|
14
|
+
product: Codex
|
|
15
|
+
generated_at: 2026-08-03
|
|
16
|
+
invisible_context: not asserted
|
|
17
|
+
---
|
|
18
|
+
|
|
1
19
|
# Release Propagation
|
|
2
20
|
|
|
3
21
|
Release propagation lets a finalized upstream release open a downstream update
|
|
@@ -205,6 +223,53 @@ The receipt keeps four machine states separate:
|
|
|
205
223
|
|
|
206
224
|
Package publication or alpha completion never implies either visibility state.
|
|
207
225
|
|
|
226
|
+
## Unified Site agent entry
|
|
227
|
+
|
|
228
|
+
An Agent begins every Site upstream update through one policy-reporting entry:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
buildchain release-propagation entry plan \
|
|
232
|
+
--source-id <paper|kfd|buildchain|kungfu-core> \
|
|
233
|
+
--channel <alpha|release> \
|
|
234
|
+
--json
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The entry does not blur content and code release policies:
|
|
238
|
+
|
|
239
|
+
| Upstream | Trigger policy | Entry result |
|
|
240
|
+
| ----------- | ------------------------- | -------------------------------------------------- |
|
|
241
|
+
| Paper | automatic release handoff | requires or resumes the exact captured Work |
|
|
242
|
+
| KFD | automatic release handoff | requires or resumes the exact captured Work |
|
|
243
|
+
| Buildchain | explicit Site intent | resolves an exact published package before capture |
|
|
244
|
+
| Kungfu Core | explicit Site intent | resolves an exact published package before capture |
|
|
245
|
+
|
|
246
|
+
Paper and KFD releases keep automatic capture-only handoff. Buildchain and
|
|
247
|
+
Kungfu Core releases remain inert until a downstream Agent receives explicit
|
|
248
|
+
Site-update intent. In all four cases, the entry reports the selected policy,
|
|
249
|
+
exact release coordinate when one has been admitted, Work root and recovery
|
|
250
|
+
cursor when one exists, and one machine-readable next action. A GitHub PR is a
|
|
251
|
+
delivery stage inside that Work; it is not the handoff unit.
|
|
252
|
+
|
|
253
|
+
For an automatic handoff, bind the exact artifact rather than resolving a
|
|
254
|
+
floating tag again:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
buildchain release-propagation entry plan \
|
|
258
|
+
--source-id kfd \
|
|
259
|
+
--handoff-work work.json \
|
|
260
|
+
--json
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
The deterministic recovery table is available without repository mutation:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
buildchain release-propagation entry fault-matrix --json
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
It classifies current and duplicate Work as successful no-ops, supersession as
|
|
270
|
+
an explicit decision boundary, stale base/expected-old and operational failures
|
|
271
|
+
as retryable, and package/schema disagreement as a hard safety gate.
|
|
272
|
+
|
|
208
273
|
## Agent-native work envelope
|
|
209
274
|
|
|
210
275
|
Setting `agent-work-mode: capture-only` makes a finalized release emit a
|
|
@@ -372,6 +437,34 @@ buildchain release-propagation work repair ... --output successor.json --json
|
|
|
372
437
|
buildchain release-propagation work complete ... --output successor.json --json
|
|
373
438
|
```
|
|
374
439
|
|
|
440
|
+
The `push-branch` stage has an executable, fail-closed entrypoint:
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
buildchain release-propagation work push-plan \
|
|
444
|
+
--work work.json \
|
|
445
|
+
--expected-work-root sha256:<64-hex> \
|
|
446
|
+
--cwd downstream-worktree \
|
|
447
|
+
--remote origin \
|
|
448
|
+
--json
|
|
449
|
+
|
|
450
|
+
buildchain release-propagation work push-branch \
|
|
451
|
+
--work work.json \
|
|
452
|
+
--expected-work-root sha256:<64-hex> \
|
|
453
|
+
--cwd downstream-worktree \
|
|
454
|
+
--remote origin \
|
|
455
|
+
--execute \
|
|
456
|
+
--json
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
The executor checks the exact GitHub repository, current managed branch,
|
|
460
|
+
captured downstream base, and expected-old Work root. It pushes only the current
|
|
461
|
+
commit with `HEAD:refs/heads/<managed-branch>`, never a bare branch or wildcard,
|
|
462
|
+
never a force option, then reads that exact remote ref back. Its typed branch
|
|
463
|
+
reconciliation evidence records the argv, source SHA, destination ref, prior
|
|
464
|
+
remote SHA, observed remote SHA, and whether a mutation occurred. A wrong
|
|
465
|
+
repository, unrelated branch, stale base, concurrent writer, or non-fast-forward
|
|
466
|
+
target fails closed without mutating another branch.
|
|
467
|
+
|
|
375
468
|
Known operational races (`stale-branch`, `expected-old-mismatch`,
|
|
376
469
|
`lockfile-drift`, `failed-check`, `interrupted-execution`, and `ci-delay`) return
|
|
377
470
|
a retryable repair action. Semantic ambiguity, missing credentials, policy
|
|
@@ -8,11 +8,11 @@ confidence: high
|
|
|
8
8
|
sensitivity: public
|
|
9
9
|
evidence_grade: A
|
|
10
10
|
review_state: unreviewed
|
|
11
|
-
last_reviewed: 2026-
|
|
11
|
+
last_reviewed: 2026-08-03
|
|
12
12
|
ai_provenance:
|
|
13
13
|
model_family: GPT-5
|
|
14
14
|
product: Codex
|
|
15
|
-
generated_at: 2026-
|
|
15
|
+
generated_at: 2026-08-03
|
|
16
16
|
invisible_context: not asserted
|
|
17
17
|
---
|
|
18
18
|
|
|
@@ -105,6 +105,8 @@ jobs:
|
|
|
105
105
|
artifact-paths: |
|
|
106
106
|
dist
|
|
107
107
|
build/stage
|
|
108
|
+
pre-upload-transport-smoke-scenario-path: .buildchain/auditable-demo.json
|
|
109
|
+
pre-upload-transport-smoke-artifact-root: .
|
|
108
110
|
expected-artifacts-json: >-
|
|
109
111
|
{"minFiles":2,"requiredPaths":["dist/libnode.tar.gz","dist/checksums.txt"]}
|
|
110
112
|
process-summary-path: .buildchain/diagnostics/process-summary.json
|
|
@@ -113,6 +115,15 @@ jobs:
|
|
|
113
115
|
publish-source-ref: publish-gate/release/v22/v22.22/22.22.3-kf.0
|
|
114
116
|
```
|
|
115
117
|
|
|
118
|
+
For a standalone Linux binary demo, the optional pre-upload transport smoke
|
|
119
|
+
uses the same declarative scenario as the later capture workflow. Buildchain
|
|
120
|
+
copies the distribution containing the scenario metadata, strips file execute
|
|
121
|
+
bits to model GitHub Artifact transport, restores only the declared
|
|
122
|
+
digest-bound executable closure, and runs `transportSmoke` before either the
|
|
123
|
+
GitHub Artifact or S3 relay upload step. The smoke must be non-interactive and
|
|
124
|
+
is hard-capped at 60 seconds. Omitting the input preserves the ordinary build
|
|
125
|
+
surface; enabling it requires a scenario with `transportSmoke`.
|
|
126
|
+
|
|
116
127
|
`runner-preset` is the stable first-class surface for known runner fleets:
|
|
117
128
|
|
|
118
129
|
| Preset | Platforms |
|
|
@@ -439,6 +450,7 @@ jobs:
|
|
|
439
450
|
checkout-cache-timeout-seconds: 60
|
|
440
451
|
checkout-cache-github-timeout-seconds: 600
|
|
441
452
|
checkout-cache-fetch-attempts: 3
|
|
453
|
+
checkout-history-mode: shallow
|
|
442
454
|
```
|
|
443
455
|
|
|
444
456
|
`checkout-cache-mode` accepts:
|
|
@@ -449,6 +461,14 @@ jobs:
|
|
|
449
461
|
| `auto` | Try the trusted cache first; on miss, record the miss and fall back according to `checkout-cache-fallback`. |
|
|
450
462
|
| `require` | Require the cache to provide the locked commit and fail before lifecycle work if unavailable. |
|
|
451
463
|
|
|
464
|
+
`checkout-history-mode` defaults to `shallow`, preserving the bounded single-
|
|
465
|
+
commit transport used by ordinary builds. Set it to `full` only when a
|
|
466
|
+
consumer gate must inspect source ancestry, for example when an Alpha pull
|
|
467
|
+
request qualifies GitHub's synthetic merge ref while retained evidence is
|
|
468
|
+
bound to an ancestor of the source-lock head. Full mode still verifies the
|
|
469
|
+
resolved immutable `HEAD` and tree; it changes only whether the advertised
|
|
470
|
+
source ref is fetched with depth one or with its reachable history.
|
|
471
|
+
|
|
452
472
|
The cache can be a local/LAN mirror URL template or a runner-local bare
|
|
453
473
|
reference repository template. Templates support `{owner}`, `{repo}`,
|
|
454
474
|
`{repository}`, `{repositorySlug}`, and `{sha}`. The workflow also reads
|
|
@@ -511,7 +531,14 @@ the preparation step. Buildchain probes its version, runs `sccache
|
|
|
511
531
|
`compiler-cache-preparation.json`. The receipt binds the source commit/tree,
|
|
512
532
|
Buildchain runtime, platform, cache profile, and any declared dependency,
|
|
513
533
|
toolchain, or policy roots. It resets counters only; it does not delete cached
|
|
514
|
-
compiler outputs.
|
|
534
|
+
compiler outputs. The same preparation exports `RUSTC_WRAPPER`,
|
|
535
|
+
`CMAKE_C_COMPILER_LAUNCHER`, and `CMAKE_CXX_COMPILER_LAUNCHER` so Cargo and
|
|
536
|
+
CMake/Ninja compilation actually passes through the audited tool.
|
|
537
|
+
|
|
538
|
+
After the build lifecycle, Buildchain probes the reset counter set again. When
|
|
539
|
+
`compiler-cache-required` is true, the build fails closed if sccache observed
|
|
540
|
+
zero compiler requests or zero cacheable requests. This prevents an installed
|
|
541
|
+
but unbound sccache binary from being reported as an active compiler cache.
|
|
515
542
|
|
|
516
543
|
Final diagnostics admit sccache hit/miss outcomes as current-run evidence only
|
|
517
544
|
when that preparation receipt is present and valid. A bare `sccache
|
|
@@ -615,7 +642,8 @@ Every native and container build lane reads this declaration after the build
|
|
|
615
642
|
lifecycle and before verification. Buildchain binds the exact artifact bytes or directory tree to
|
|
616
643
|
the caller repository, source commit, source tree, immutable runtime, platform,
|
|
617
644
|
and requested signature semantics, then publishes a deterministic
|
|
618
|
-
`<artifact>-signing-request-<platform>-<source-sha>`
|
|
645
|
+
`<artifact>-signing-request-<platform>-<source-sha>-<run-id>-<run-attempt>`
|
|
646
|
+
request. No consumer
|
|
619
647
|
workflow step is required. The lifecycle runner automatically adds declarations
|
|
620
648
|
selected for the current platform to the `build` manifest scan, including
|
|
621
649
|
subjects outside the caller's ordinary `artifact-paths`; this extends the
|
|
@@ -668,14 +696,27 @@ Buildchain-owned signing authority is responsible for credential selection,
|
|
|
668
696
|
native signing, notarization where applicable, immutable result delivery, and a
|
|
669
697
|
receipt bound to the request digest, runtime SHA, output digest, and signature
|
|
670
698
|
evidence. Consumer repositories neither receive nor duplicate credential-island
|
|
671
|
-
material.
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
699
|
+
material. Each platform lane seals and uploads the unsigned request plus a
|
|
700
|
+
run-attempt-bound control request, completes functional verification, and exits.
|
|
701
|
+
It does not dispatch or poll the authority. A separate `ubuntu-24.04` controller
|
|
702
|
+
starts only after the build matrices complete, validates the exact source,
|
|
703
|
+
tree, runtime, request-set root, platform, run attempt, and correlation, then
|
|
704
|
+
dispatches and awaits the protected authority workflow. Its retained receipt
|
|
705
|
+
records two independent immutable identities: the consumer Buildchain runtime
|
|
706
|
+
SHA carried by the control request and the exact authority-ref commit resolved
|
|
707
|
+
immediately before dispatch. The former validates the request-producing
|
|
708
|
+
runtime; the latter must equal the authority workflow run's `head_sha` and is
|
|
709
|
+
retained with the exact authority run and result artifact. If the protected ref
|
|
710
|
+
moves between resolution and dispatch, settlement fails closed. Failure, timeout, or
|
|
711
|
+
cancellation produces a non-qualifying receipt and no finalization delegation.
|
|
712
|
+
|
|
713
|
+
A second GitHub-hosted finalization lane downloads the original control request,
|
|
714
|
+
controller receipt, and delegation, verifies their roots and coordinates agree,
|
|
715
|
+
then verifies the authority result against the sealed request, imports the exact
|
|
716
|
+
signed bytes, and recomputes the final manifest before replacing the
|
|
717
|
+
deterministic artifact. The signing result is never downloaded back to a
|
|
718
|
+
self-hosted native runner, so a macOS caller is released before credential-island
|
|
719
|
+
signing and notarization complete.
|
|
679
720
|
Platform manifests, KFD evidence, checksums, and Release Passport inputs
|
|
680
721
|
therefore observe the final signed artifact rather than the pre-signing build
|
|
681
722
|
output.
|
|
@@ -8,7 +8,7 @@ confidence: high
|
|
|
8
8
|
sensitivity: public
|
|
9
9
|
evidence_grade: A
|
|
10
10
|
review_state: self-reviewed
|
|
11
|
-
last_reviewed: 2026-
|
|
11
|
+
last_reviewed: 2026-08-03
|
|
12
12
|
ai_provenance:
|
|
13
13
|
model_family: GPT-5
|
|
14
14
|
product: Codex
|
|
@@ -141,7 +141,10 @@ bot, or human service-account token as `approval-token`. The approval identity
|
|
|
141
141
|
must differ from the promotion token identity that opens the PR. When no
|
|
142
142
|
`approval-token` is passed, `auto-approve: true` falls back to the caller
|
|
143
143
|
`github.token` and therefore requires GitHub Actions approval permission. The
|
|
144
|
-
generated PR may use auto-merge, but it never bypasses the target branch
|
|
144
|
+
generated PR may use auto-merge, but it never bypasses the target branch
|
|
145
|
+
checks. Callers can select `merge-method: merge`, `squash`, or `rebase`; the
|
|
146
|
+
default is `merge` for compatibility. Unsupported values fail closed before
|
|
147
|
+
GitHub is called.
|
|
145
148
|
|
|
146
149
|
Before enabling `auto-approve` and `auto-merge`, the caller repository must
|
|
147
150
|
provide one approval path and enable auto-merge:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungfu-tech/buildchain",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.6-alpha.0",
|
|
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",
|
|
@@ -72,6 +72,41 @@ function majorLineFromPackageVersion(version = "") {
|
|
|
72
72
|
return match ? `v${match[1]}` : "v3";
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
function declarativeAuditableDemoSurface(root, pkg, majorLine) {
|
|
76
|
+
return surface(root, {
|
|
77
|
+
id: "declarative-auditable-demo",
|
|
78
|
+
kind: "workflow",
|
|
79
|
+
path: ".github/workflows/.declarative-auditable-demo.yml",
|
|
80
|
+
publicRef: `${pkg.repository ? "kungfu-systems/buildchain" : "buildchain"}/.github/workflows/.declarative-auditable-demo.yml@${majorLine}`,
|
|
81
|
+
requiredInputs: ["binary-artifact-name", "binary-artifact-digest", "renderer-image"],
|
|
82
|
+
requiredOutputs: [
|
|
83
|
+
"source-sha", "capture-artifact-name", "capture-artifact-digest",
|
|
84
|
+
"evidence-artifact-name", "evidence-artifact-digest", "publication-pr-url",
|
|
85
|
+
],
|
|
86
|
+
breakingDefaults: {
|
|
87
|
+
scenarioPathDefault: ".buildchain/auditable-demo.json",
|
|
88
|
+
renderMediaDefault: false,
|
|
89
|
+
materializeDefault: false,
|
|
90
|
+
mediaProfileDefault: "responsive-web-delivery-v1",
|
|
91
|
+
artifactRetentionDaysDefault: 14,
|
|
92
|
+
executionBoundary: "exact-binary-network-none-secret-free-60-seconds",
|
|
93
|
+
},
|
|
94
|
+
optionalInputs: [
|
|
95
|
+
"buildchain-repository", "source-ref", "scenario-path", "render-media",
|
|
96
|
+
"media-profile", "materialize", "materialize-base-ref", "artifact-retention-days",
|
|
97
|
+
],
|
|
98
|
+
guarantees: [
|
|
99
|
+
"one versioned declaration can contain multiple demos with multiple ordered literal argv steps",
|
|
100
|
+
"every demo uses the exact same-run standalone binary admitted by producer-owned artifact name and digest",
|
|
101
|
+
"capture runs without network or inherited secrets and retains independent native 1080p and 720p terminal dimensions",
|
|
102
|
+
"the generic adapter feeds the required auditable demo Gate and immutable renderer without product-specific glue",
|
|
103
|
+
"full rendering emits a content-addressed Release Passport and idempotent protected README update pull request",
|
|
104
|
+
"manual, alpha, and release callers use the same capture, Gate, renderer, passport, and materializer implementation",
|
|
105
|
+
"identity, compliance, Product System metadata, package metadata, registry history, scans, and generation grant no authority",
|
|
106
|
+
],
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
75
110
|
export function createBuildchainContractWorld({
|
|
76
111
|
root = process.cwd(),
|
|
77
112
|
packageJson = undefined,
|
|
@@ -360,7 +395,7 @@ export function createBuildchainContractWorld({
|
|
|
360
395
|
"Build Images owns encoding, Buildchain owns qualification and receipts, and site repositories own browser loading and accessibility behavior",
|
|
361
396
|
"media qualification does not claim browser playback, responsive layout, reduced-motion behavior, accessibility, or production deployment",
|
|
362
397
|
],
|
|
363
|
-
}),
|
|
398
|
+
}), declarativeAuditableDemoSurface(root, pkg, majorLine),
|
|
364
399
|
surface(root, {
|
|
365
400
|
id: "promote-buildchain-ref-action",
|
|
366
401
|
kind: "action",
|
|
@@ -5,6 +5,7 @@ import { createPublicationAuthorityRegistry } from "./publication-authority.js";
|
|
|
5
5
|
|
|
6
6
|
const DESCRIPTORS = Object.freeze([
|
|
7
7
|
[".github/workflows/.auditable-demo.yml", "non-publication-oidc"],
|
|
8
|
+
[".github/workflows/.declarative-auditable-demo.yml", "governance-write"],
|
|
8
9
|
[".github/workflows/.build.yml", "non-publication-oidc"],
|
|
9
10
|
[".github/workflows/.release-candidate-promote.yml", "product-publication", true, ["npm-publish", "github-release", "channel-ref"], "trusted-publishing", "none", "fixed", "caller-bound"],
|
|
10
11
|
[".github/workflows/.publication-authority.yml", "evidence-publication"],
|
|
@@ -19,6 +20,7 @@ const DESCRIPTORS = Object.freeze([
|
|
|
19
20
|
[".github/workflows/binary-distribution.yml", "evidence-publication"],
|
|
20
21
|
[".github/workflows/binary-release-assets.yml", "governance-write"],
|
|
21
22
|
[".github/workflows/artifact-signing-authority.yml", "evidence-publication"],
|
|
23
|
+
[".github/workflows/auditable-demo.yml", "governance-write"],
|
|
22
24
|
[".github/workflows/build-surface-fixture.yml", "non-publication-oidc"],
|
|
23
25
|
[".github/workflows/build.yml", "non-publication-oidc"],
|
|
24
26
|
[".github/workflows/buildchain-alpha-self-dogfood.yml", "non-publication-oidc"],
|
|
@@ -28,6 +30,7 @@ const DESCRIPTORS = Object.freeze([
|
|
|
28
30
|
[".github/workflows/buildchain-patrol.yml", "governance-write"],
|
|
29
31
|
[".github/workflows/buildchain-ref-promotion.yml", "governance-write"],
|
|
30
32
|
[".github/workflows/buildchain-stable-candidate-patrol.yml", "governance-write"],
|
|
33
|
+
[".github/workflows/dev-qualification-patrol.yml", "governance-write"],
|
|
31
34
|
[".github/workflows/dev-alpha-candidate-patrol.yml", "governance-write"],
|
|
32
35
|
[".github/workflows/dev-merge-queue-governance.yml", "governance-write"],
|
|
33
36
|
[".github/workflows/dev-pr-auto-merge.yml", "governance-write"],
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
commandId,
|
|
6
6
|
enumerateCliCommandsFromBin,
|
|
7
7
|
} from "./public-surface-cli.js";
|
|
8
|
+
import { parseReusableWorkflowInterface } from "./workflow-yaml-contract.js";
|
|
8
9
|
|
|
9
10
|
export { enumerateCliCommandsFromBin } from "./public-surface-cli.js";
|
|
10
11
|
|
|
@@ -46,38 +47,6 @@ function listDirectories(root, dir) {
|
|
|
46
47
|
.sort();
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
function parseYamlWorkflowCall(text) {
|
|
50
|
-
const lines = text.split(/\r?\n/);
|
|
51
|
-
const result = { reusable: false, inputs: [], secrets: [], outputs: [] };
|
|
52
|
-
const workflowCallIndex = lines.findIndex((line) => /^(\s*)workflow_call:\s*$/.test(line));
|
|
53
|
-
if (workflowCallIndex === -1) return result;
|
|
54
|
-
result.reusable = true;
|
|
55
|
-
const workflowCallIndent = lines[workflowCallIndex].match(/^(\s*)/)?.[1].length || 0;
|
|
56
|
-
let section = "";
|
|
57
|
-
for (const line of lines.slice(workflowCallIndex + 1)) {
|
|
58
|
-
const currentIndent = line.match(/^(\s*)/)?.[1].length || 0;
|
|
59
|
-
if (line.trim() && currentIndent <= workflowCallIndent) break;
|
|
60
|
-
const sectionMatch = line.match(new RegExp(`^\\s{${workflowCallIndent + 2}}(inputs|secrets|outputs):\\s*$`));
|
|
61
|
-
if (sectionMatch) {
|
|
62
|
-
section = sectionMatch[1];
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
if (line.trim() && currentIndent <= workflowCallIndent + 2) {
|
|
66
|
-
section = "";
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
if (!section) continue;
|
|
70
|
-
const fieldMatch = line.match(new RegExp(`^\\s{${workflowCallIndent + 4}}([A-Za-z0-9_-]+):\\s*$`));
|
|
71
|
-
if (fieldMatch) result[section].push(fieldMatch[1]);
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
reusable: result.reusable,
|
|
75
|
-
inputs: uniqueSorted(result.inputs),
|
|
76
|
-
secrets: uniqueSorted(result.secrets),
|
|
77
|
-
outputs: uniqueSorted(result.outputs),
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
50
|
function parseYamlTopLevelInputs(text) {
|
|
82
51
|
const lines = text.split(/\r?\n/);
|
|
83
52
|
const inputs = [];
|
|
@@ -104,14 +73,14 @@ function parseYamlTopLevelInputs(text) {
|
|
|
104
73
|
|
|
105
74
|
export function enumerateWorkflowInputs({ root = process.cwd() } = {}) {
|
|
106
75
|
return listFiles(root, ".github/workflows", (name) => /\.ya?ml$/.test(name)).map((relPath) => {
|
|
107
|
-
const contract =
|
|
76
|
+
const contract = parseReusableWorkflowInterface(readText(root, relPath));
|
|
108
77
|
return {
|
|
109
78
|
id: relPath.replace(/^\.github\/workflows\//, "").replace(/\.ya?ml$/, ""),
|
|
110
79
|
path: relPath,
|
|
111
80
|
reusable: contract.reusable,
|
|
112
|
-
inputs: contract.inputs,
|
|
81
|
+
inputs: contract.inputs.map((entry) => entry.name),
|
|
113
82
|
inputCount: contract.inputs.length,
|
|
114
|
-
secrets: contract.secrets,
|
|
83
|
+
secrets: contract.secrets.map((entry) => entry.name),
|
|
115
84
|
secretCount: contract.secrets.length,
|
|
116
85
|
outputs: contract.outputs,
|
|
117
86
|
outputCount: contract.outputs.length,
|