@kungfu-tech/buildchain 3.0.2 → 3.0.3-alpha.1
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 +1 -1
- package/CONTRIBUTING.md +1 -1
- package/README.md +27 -1
- package/actions/promote-buildchain-ref/README.md +90 -19
- package/actions/report-buildchain-issue/README.md +20 -2
- package/actions/run-lifecycle/README.md +5 -0
- package/actions/validate-config/README.md +19 -1
- package/bin/buildchain.mjs +56 -2
- package/bin/internal/command-registry.mjs +82 -0
- package/bin/internal/trust-release-cli.mjs +1 -0
- package/contracts/auditable-demo-media-profiles-v1.json +116 -1
- package/contracts/buildchain-v2-residuals-v1.json +146 -0
- package/contracts/evidence/auditable-demo-responsive-web-delivery-v1.json +143 -0
- package/contracts/evidence/auditable-demo-web-delivery-v1.json +7 -3
- package/contracts/fixtures/auditable-demo-responsive-web-delivery-v1/complete-transcript.txt +2 -0
- package/contracts/fixtures/auditable-demo-responsive-web-delivery-v1/public-projection.json +16 -0
- package/contracts/fixtures/auditable-demo-responsive-web-delivery-v1/scene.json +12 -0
- package/dist/site/buildchain-contract.json +188 -46
- package/dist/site/buildchain-site.json +181 -90
- package/dist/site/capability-registry.json +5 -5
- package/dist/site/cli-registry.json +860 -98
- package/dist/site/controller-registry.json +118 -5
- package/dist/site/kfd-claims.json +233 -19
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +20 -20
- package/dist/site/node-api-registry.json +374 -59
- package/dist/site/page-registry.json +156 -65
- package/dist/site/public-surface-audit.json +231 -22
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +3 -0
- package/dist/site/site-manifest.json +24 -24
- package/dist/site/workflow-registry.json +575 -79
- package/docs/MAP.md +22 -4
- package/docs/auditable-demo.md +54 -13
- package/docs/aws-us-elastic-runner-burst-plane.md +381 -0
- package/docs/cli.md +119 -12
- package/docs/consumer-issue-reporting.md +20 -2
- package/docs/dev-alpha-candidate-patrol.md +24 -10
- package/docs/github-governance-authority.md +24 -31
- package/docs/lifecycle-protocol.md +20 -2
- package/docs/migration-inventory.md +24 -5
- package/docs/observed-evidence-patrol.md +28 -12
- package/docs/ownership.md +19 -1
- package/docs/publication-artifacts.md +158 -18
- package/docs/publication-authority.md +4 -4
- package/docs/publish-transaction.md +78 -31
- package/docs/release-candidate.md +24 -0
- package/docs/release-flow.md +50 -32
- package/docs/release-governance.md +39 -32
- package/docs/release-passport.md +4 -0
- package/docs/release-propagation.md +57 -12
- package/docs/reusable-build-surface.md +218 -90
- package/docs/runtime-train-validation.md +20 -2
- package/docs/shifu-gate-profiles.md +7 -1
- package/docs/stable-candidate-patrol.md +6 -6
- package/docs/toolkit-observability.md +22 -0
- package/docs/versioning.md +46 -24
- package/docs/web-surface-deployments.md +82 -1
- package/package.json +7 -5
- package/packages/core/README.md +60 -4
- package/packages/core/artifact-signing.js +1 -0
- package/packages/core/buildchain-contract.js +9 -4
- package/packages/core/cache-evidence.js +1 -0
- package/packages/core/controller-evidence.js +2 -0
- package/packages/core/diagnostics.js +105 -30
- package/packages/core/github-governance-authority.js +25 -17
- package/packages/core/index.js +40 -0
- package/packages/core/paper.js +3226 -0
- package/packages/core/public-surface-audit.js +3 -0
- package/packages/core/publication-artifact.js +1 -6
- package/packages/core/publication-authority.js +1 -0
- package/packages/core/publication-control-plane-audit.js +28 -0
- package/packages/core/publication-reproducibility.js +947 -0
- package/packages/core/publication-sealed-bundle.js +190 -0
- package/packages/core/publish-transaction.js +147 -17
- package/packages/core/release-candidate.js +234 -0
- package/packages/core/release-passport.js +519 -228
- package/packages/core/release-propagation.js +175 -1
- package/packages/core/stable-release-gate.js +4 -1
- package/scripts/artifact-signing-delegation.mjs +268 -0
- package/scripts/audit-github-governance.mjs +32 -13
- package/scripts/audit-publication-control-plane.mjs +17 -8
- package/scripts/auditable-demo.mjs +266 -7
- package/scripts/aws-codebuild-toolchain.mjs +285 -0
- package/scripts/aws-macos-jit-core.mjs +378 -0
- package/scripts/aws-macos-jit.mjs +123 -0
- package/scripts/aws-runner-burst-core.mjs +248 -0
- package/scripts/aws-runner-burst.mjs +79 -0
- package/scripts/aws-windows-jit-core.mjs +374 -0
- package/scripts/aws-windows-jit.mjs +121 -0
- package/scripts/build-contract-core.mjs +69 -6
- package/scripts/build-standalone-binary.mjs +23 -0
- package/scripts/buildchain-contract-lock.mjs +1 -1
- package/scripts/buildchain-patrol.mjs +1 -1
- package/scripts/check-internal-architecture.mjs +69 -2
- package/scripts/check-inventory.mjs +70 -2
- package/scripts/check-javascript-syntax.mjs +31 -0
- package/scripts/check-maintainability.mjs +371 -0
- package/scripts/compiler-cache-evidence.mjs +221 -0
- package/scripts/dev-alpha-candidate-patrol.mjs +288 -43
- package/scripts/dispatch-artifact-signing-authority.mjs +7 -1
- package/scripts/finalize-native-artifact-signing-result.mjs +185 -31
- package/scripts/gate-profile-core.mjs +6 -1
- package/scripts/generate-channel-promotion-workflow.mjs +3 -12
- package/scripts/generate-release-candidate-passport.mjs +4 -0
- package/scripts/generate-site-bundle.mjs +84 -18
- package/scripts/import-artifact-signing-results.mjs +64 -5
- package/scripts/inspect-artifact-signing-requests.mjs +52 -14
- package/scripts/maintainability-metrics.mjs +339 -0
- package/scripts/npm-publish-transaction.mjs +57 -6
- package/scripts/observed-evidence.mjs +151 -33
- package/scripts/paper.mjs +645 -0
- package/scripts/promotion-channel-router.mjs +16 -4
- package/scripts/publication-reproducibility.mjs +62 -0
- package/scripts/reconcile-github-governance.mjs +8 -1
- package/scripts/release-propagation.mjs +39 -0
- package/scripts/resolve-artifact-signing-upload-route.mjs +55 -0
- package/scripts/resolve-build-contract.mjs +6 -0
- package/scripts/route-offline-runners.mjs +236 -0
- package/scripts/run-candidate-body-prefix-renderer.mjs +187 -0
- package/scripts/run-lifecycle-core.mjs +62 -1
- package/scripts/runtime-ref-core.mjs +36 -4
- package/scripts/seal-artifact-signing-requests.mjs +64 -12
- package/scripts/stable-candidate-qualification.mjs +50 -0
- package/scripts/verify-artifact-signing-results.mjs +26 -1
- package/scripts/web-surface-core.mjs +272 -86
- package/scripts/web-surface-production-decision.mjs +19 -3
package/docs/MAP.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: active
|
|
3
|
+
period: ongoing
|
|
4
|
+
theme: buildchain-documentation-map
|
|
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-07-31
|
|
12
|
+
ai_provenance:
|
|
13
|
+
model_family: GPT-5
|
|
14
|
+
product: Codex
|
|
15
|
+
generated_at: 2026-07-31
|
|
16
|
+
invisible_context: not asserted
|
|
17
|
+
---
|
|
18
|
+
|
|
1
19
|
# Documentation Map
|
|
2
20
|
|
|
3
21
|
Start here. Find the question you have; follow it to the document that answers
|
|
@@ -10,7 +28,7 @@ running artifact), *use* (consume / extend) - and a **status**:
|
|
|
10
28
|
- `stable` - current and holds.
|
|
11
29
|
- `draft` - exists, rough or incomplete.
|
|
12
30
|
- `to write` - planned; the material exists but is not yet a single doc.
|
|
13
|
-
- `retired` - intentionally not part of the active Buildchain
|
|
31
|
+
- `retired` - intentionally not part of the active Buildchain v3 surface.
|
|
14
32
|
|
|
15
33
|
## Capability Coverage
|
|
16
34
|
|
|
@@ -118,7 +136,7 @@ replace them.
|
|
|
118
136
|
| How do I automatically qualify alpha candidates and publish the newest non-revoked qualified candidate at a fixed window? | [`stable-candidate-patrol.md`](stable-candidate-patrol.md) | use | preview |
|
|
119
137
|
| How do I deploy a site/app preview, staging, or production surface? | [`web-surface-deployments.md`](web-surface-deployments.md) | use | stable |
|
|
120
138
|
| How do I publish observed infrastructure contracts for downstream consumers? | [`infra-contract.md`](infra-contract.md) | use | preview |
|
|
121
|
-
| How do I use the active actions directly? | [`../actions/validate-config/README.md`](../actions/validate-config/README.md), [`../actions/run-lifecycle/README.md`](../actions/run-lifecycle/README.md), [`../actions/promote-buildchain-ref/README.md`](../actions/promote-buildchain-ref/README.md), [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md) | use | stable |
|
|
139
|
+
| How do I use the active actions directly? | [`../actions/validate-config/README.md`](../actions/validate-config/README.md), [`../actions/run-lifecycle/README.md`](../actions/run-lifecycle/README.md), [`../actions/promote-buildchain-ref/README.md`](../actions/promote-buildchain-ref/README.md), [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md), [`../actions/github-artifact-attestation/README.md`](../actions/github-artifact-attestation/README.md), [`../actions/macos-credential-island/README.md`](../actions/macos-credential-island/README.md); `dist/site/workflow-registry.json#actions` is authoritative for the six-entry inventory. | use | stable |
|
|
122
140
|
| How can a consumer workflow report a Buildchain-owned failure back to Buildchain? | [`consumer-issue-reporting.md`](consumer-issue-reporting.md) + [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md) | use | stable |
|
|
123
141
|
| What do the fixture repositories demonstrate? | [`../fixtures/libnode-shaped/README.md`](../fixtures/libnode-shaped/README.md), [`../fixtures/publish-transaction-shaped/README.md`](../fixtures/publish-transaction-shaped/README.md), [`../fixtures/web-surface-shaped/README.md`](../fixtures/web-surface-shaped/README.md), [`../fixtures/publication-artifact-shaped/README.md`](../fixtures/publication-artifact-shaped/README.md) | verify | stable |
|
|
124
142
|
| What license and contribution terms apply? | [`../LICENSE`](../LICENSE) + [`../LICENSE-POLICY.md`](../LICENSE-POLICY.md) | use | stable |
|
|
@@ -129,14 +147,14 @@ replace them.
|
|
|
129
147
|
|
|
130
148
|
- **ABV / old workflows / old action repositories** -> [`release-governance.md`](release-governance.md)
|
|
131
149
|
and [`migration-inventory.md`](migration-inventory.md).
|
|
132
|
-
- **
|
|
150
|
+
- **v3 / v3-alpha / v3.0 / v3.0-alpha / exact tags / floating tags** ->
|
|
133
151
|
[`release-governance.md`](release-governance.md) and
|
|
134
152
|
[`release-flow.md`](release-flow.md).
|
|
135
153
|
- **Buildchain self-dogfood / released alpha canary / stable compatibility lane** ->
|
|
136
154
|
[`release-governance.md`](release-governance.md#buildchain-alpha-self-dogfood).
|
|
137
155
|
- **qualified alpha ledger / scheduled stable selection / hold and revoke** ->
|
|
138
156
|
[`stable-candidate-patrol.md`](stable-candidate-patrol.md).
|
|
139
|
-
- **
|
|
157
|
+
- **v3.1 vs v3.2 / when to open a new minor line** ->
|
|
140
158
|
[`versioning.md`](versioning.md).
|
|
141
159
|
- **dry-run / what would happen if this channel PR merges** -> [`cli.md`](cli.md)
|
|
142
160
|
and [`release-flow.md`](release-flow.md).
|
package/docs/auditable-demo.md
CHANGED
|
@@ -8,11 +8,11 @@ confidence: high
|
|
|
8
8
|
sensitivity: public
|
|
9
9
|
evidence_grade: A
|
|
10
10
|
review_state: self-reviewed
|
|
11
|
-
last_reviewed: 2026-07-
|
|
11
|
+
last_reviewed: 2026-07-31
|
|
12
12
|
ai_provenance:
|
|
13
13
|
model_family: GPT-5
|
|
14
14
|
product: Codex
|
|
15
|
-
generated_at: 2026-07-
|
|
15
|
+
generated_at: 2026-07-31
|
|
16
16
|
invisible_context_boundary: No hidden model build, parameter count, or private corpus is asserted.
|
|
17
17
|
---
|
|
18
18
|
|
|
@@ -41,6 +41,18 @@ public-projection.json
|
|
|
41
41
|
scene.json
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
It may additionally emit one declared `terminal-capture.json` using
|
|
45
|
+
`kungfu.terminal-capture/v1`. The optional capture is bounded to 60 seconds,
|
|
46
|
+
fixed 80-200 by 24-80 terminal cells, 10,000 events, and 4 MiB of canonical
|
|
47
|
+
base64 bytes. It must contain a passed completion sentinel and an explicitly
|
|
48
|
+
empty authority-grant list. Existing three-file adapters remain valid.
|
|
49
|
+
|
|
50
|
+
Terminal bytes are volatile observations, not Work, Warrant, capability, or
|
|
51
|
+
publication authority. First-party or System identity, KFD compliance, Product
|
|
52
|
+
System metadata, package metadata, scan output, registry history, and
|
|
53
|
+
standalone generation remain non-authoritative unless an exact higher-level
|
|
54
|
+
contract independently admits them.
|
|
55
|
+
|
|
44
56
|
The adapter must not rebuild or rerun the product. It receives:
|
|
45
57
|
|
|
46
58
|
```text
|
|
@@ -49,6 +61,15 @@ The adapter must not rebuild or rerun the product. It receives:
|
|
|
49
61
|
--source-coordinate PATH
|
|
50
62
|
```
|
|
51
63
|
|
|
64
|
+
Consumers with one shared adapter for several deterministic demos may also set
|
|
65
|
+
`adapter-arguments-json` to a bounded JSON array. Buildchain parses the array,
|
|
66
|
+
rejects malformed values, newlines, NUL bytes, more than 32 arguments, values
|
|
67
|
+
longer than 256 bytes, and attempts to override the three coordinate flags
|
|
68
|
+
above, then appends the accepted strings directly to the adapter argv. It never
|
|
69
|
+
evaluates a shell command. The exact argument vector and its content root are
|
|
70
|
+
retained in `adapter.json`; the Gate receipt binds that root. Adapter arguments
|
|
71
|
+
select consumer-owned capture behavior only and grant no authority.
|
|
72
|
+
|
|
52
73
|
`--source-coordinate` identifies the caller repository, run, artifact id,
|
|
53
74
|
artifact name, upload digest, expiry, and exact source SHA. The workflow finds
|
|
54
75
|
exactly one live artifact with the requested name in the current caller run and
|
|
@@ -78,7 +99,8 @@ The Gate:
|
|
|
78
99
|
- resolves and downloads one exact same-run GitHub Artifact;
|
|
79
100
|
- invokes the checked-in adapter by argv, never as an evaluated shell string;
|
|
80
101
|
- rejects undeclared adapter outputs, symlinks, invalid UTF-8, invalid scene or
|
|
81
|
-
projection
|
|
102
|
+
projection or terminal-capture schemas, implicit capture grants,
|
|
103
|
+
out-of-range transcript references, and oversized input;
|
|
82
104
|
- derives a one-second compatibility scene from the consumer projection;
|
|
83
105
|
- anonymously pulls an immutable `image@sha256:digest` renderer;
|
|
84
106
|
- runs it as non-root with `--network none`, a read-only root filesystem, and a
|
|
@@ -105,6 +127,11 @@ distribution checksums. A web-delivery profile also retains
|
|
|
105
127
|
`media-inspection.json`, whose content root is bound into the receipt.
|
|
106
128
|
`render-media: false` does not weaken or skip the Gate.
|
|
107
129
|
|
|
130
|
+
When the Gate bundle contains a qualified terminal capture, the render job
|
|
131
|
+
passes it read-only to the immutable renderer. The renderer manifest binds the
|
|
132
|
+
capture root and terminal-state-machine version, but raw capture bytes remain
|
|
133
|
+
in the Gate bundle rather than being copied into the public media bundle.
|
|
134
|
+
|
|
108
135
|
## Media Qualification Profiles
|
|
109
136
|
|
|
110
137
|
The single machine-readable source is
|
|
@@ -116,6 +143,7 @@ shell fragments, arbitrary profile paths, or transcoding instructions.
|
|
|
116
143
|
| --- | --- |
|
|
117
144
|
| `archive-v1` | Default compatibility contract. Retains the exact renderer outputs and classifies GIF as README compatibility evidence without making a browser-delivery claim. |
|
|
118
145
|
| `web-delivery-v1` | Independently qualifies H.264 MP4 and VP9 WebM playback sources, forbids audio, requires exact scene dimensions and bounded duration/frame-rate drift, checks per-rendition byte ceilings, and proves MP4 `moov` precedes `mdat`. PNG remains the lossless evidence poster. |
|
|
146
|
+
| `responsive-web-delivery-v1` | Extends `web-delivery-v1` with exact 1280x720 H.264 MP4 and VP9 WebM responsive sources plus a 1280x720 README GIF while keeping the primary MP4/WebM and evidence poster at the source scene dimensions. Every declared downscale must preserve the scene aspect ratio and may never upscale. |
|
|
119
147
|
| `site-hero-v1` | Extends `web-delivery-v1` and additionally requires a qualified WebP browser poster. The current Build Images v1 renderer does not emit that member, so selecting this profile fails closed until the producer adds it. |
|
|
120
148
|
|
|
121
149
|
For web-delivery profiles, Buildchain runs its own fixed `ffprobe` invocation
|
|
@@ -129,16 +157,22 @@ field remains supporting evidence, never sufficient authority.
|
|
|
129
157
|
|
|
130
158
|
The default `archive-v1` path preserves the existing v1 media receipt exactly.
|
|
131
159
|
An explicitly selected web-delivery profile emits a v2 media receipt with a
|
|
132
|
-
content-addressed rendition list and explicit roles
|
|
133
|
-
site builds select `primary-video`,
|
|
134
|
-
`alternate-video`, `
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
the
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
160
|
+
content-addressed rendition list and explicit roles, MIME types, dimensions,
|
|
161
|
+
and dimension policy. Agents and site builds select `primary-video`,
|
|
162
|
+
`alternate-video`, `responsive-primary-video`,
|
|
163
|
+
`responsive-alternate-video`, `browser-poster`, or evidence-only roles from
|
|
164
|
+
that receipt; they do not infer semantics from extensions or filenames.
|
|
165
|
+
Profile-declared responsive renditions must match their exact dimensions,
|
|
166
|
+
remain within the source scene, and preserve its aspect ratio. Additional
|
|
167
|
+
producer-declared renditions remain bounded by the selected profile and cannot
|
|
168
|
+
raise their own byte ceiling. Unbound outputs, implicit upscales, aspect-ratio
|
|
169
|
+
drift, duplicate singleton roles, unknown profiles, or unsupported required
|
|
170
|
+
versions fail closed.
|
|
171
|
+
|
|
172
|
+
The required Gate binds the exact selected media profile and the smoke media
|
|
173
|
+
qualification root before optional full rendering starts. Gate-only validation
|
|
174
|
+
and full rendering therefore exercise the same profile contract; a later media
|
|
175
|
+
job cannot silently switch rendition authority.
|
|
142
176
|
|
|
143
177
|
Initial byte ceilings are derived from the checked-in
|
|
144
178
|
`auditable-demo-web-delivery-v1` fixture rendered by Build Images
|
|
@@ -147,6 +181,12 @@ PNG ceilings are the next power of two above sixteen times the measured member
|
|
|
147
181
|
bytes. The not-yet-produced WebP poster uses eight times the measured lossless
|
|
148
182
|
PNG as its conservative proxy. The path-scoped qualification workflow
|
|
149
183
|
regenerates the content-addressed evidence and fails on any byte or fact drift.
|
|
184
|
+
Its matrix retains the original 1280x720 web-delivery baseline on the renderer
|
|
185
|
+
that produced it and separately measures the responsive profile against a
|
|
186
|
+
1920x1080 fixture and the first exact renderer release that emits both
|
|
187
|
+
source-resolution and 720p renditions. This keeps historical budget evidence
|
|
188
|
+
reproducible while giving the responsive contract its own immutable
|
|
189
|
+
qualification root.
|
|
150
190
|
|
|
151
191
|
## Consumer Example
|
|
152
192
|
|
|
@@ -183,6 +223,7 @@ jobs:
|
|
|
183
223
|
source-artifact-name: ${{ needs.build.outputs.artifact-name }}
|
|
184
224
|
source-artifact-digest: ${{ needs.build.outputs.artifact-digest }}
|
|
185
225
|
adapter-path: scripts/auditable-demo-adapter
|
|
226
|
+
adapter-arguments-json: '["--demo-id","agent-work-lab"]'
|
|
186
227
|
renderer-image: ghcr.io/kungfu-systems/build-images/demo-renderer@sha256:RENDERER_DIGEST
|
|
187
228
|
render-media: false
|
|
188
229
|
media-profile: archive-v1
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: draft
|
|
3
|
+
period: 2026-07-28
|
|
4
|
+
theme: aws-us-elastic-runner-burst-plane
|
|
5
|
+
doc_type: design
|
|
6
|
+
source_level: local-files-and-provider-docs
|
|
7
|
+
confidence: high
|
|
8
|
+
sensitivity: public
|
|
9
|
+
evidence_grade: A
|
|
10
|
+
review_state: unreviewed
|
|
11
|
+
last_reviewed: 2026-07-30
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# AWS US elastic runner burst plane
|
|
15
|
+
|
|
16
|
+
The local runner fleet remains the normal Kungfu build plane. This AWS US plane
|
|
17
|
+
is an explicit, temporary overflow mechanism with sequential qualification:
|
|
18
|
+
|
|
19
|
+
1. Linux CodeBuild proof of concept under USD 50.
|
|
20
|
+
2. Windows EC2 one-job JIT runners.
|
|
21
|
+
3. One bounded 24-hour EC2 Mac campaign.
|
|
22
|
+
|
|
23
|
+
No later phase can start from design intent alone. The preceding phase must
|
|
24
|
+
produce a qualifying source-bound receipt, actual cost, and zero-resource
|
|
25
|
+
cleanup proof.
|
|
26
|
+
|
|
27
|
+
## Phase 1 contract
|
|
28
|
+
|
|
29
|
+
`aws-us-codebuild-linux` is a Linux-only runner preset. It requires the exact
|
|
30
|
+
CodeBuild project name and resolves the runner label at workflow evaluation
|
|
31
|
+
time:
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
codebuild-<project>-<github.run_id>-<github.run_attempt>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The GitHub-hosted `trust-gate` remains ahead of the matrix job. A fork pull
|
|
38
|
+
request therefore fails or skips before the CodeBuild `runs-on` label exists as
|
|
39
|
+
a queued job. The dedicated consumer workflow is manual-only and does not add
|
|
40
|
+
the preset to dev, alpha, release, signing, notarization, deployment, or
|
|
41
|
+
publication workflows.
|
|
42
|
+
|
|
43
|
+
The CodeBuild project is:
|
|
44
|
+
|
|
45
|
+
- repository-scoped through an AWS CodeConnections GitHub App;
|
|
46
|
+
- one ephemeral runner and one GitHub job per CodeBuild build;
|
|
47
|
+
- outside a VPC, with no idle VM, NAT gateway, public ingress, SSH, or persistent
|
|
48
|
+
workspace;
|
|
49
|
+
- limited to two concurrent builds, 15 queued minutes, and 40 execution
|
|
50
|
+
minutes;
|
|
51
|
+
- allowed to write only its dedicated CloudWatch log group and request a token
|
|
52
|
+
from its dedicated GitHub App connection;
|
|
53
|
+
- forbidden from receiving signing, notarization, package publication, release,
|
|
54
|
+
deploy, static AWS, long-lived GitHub, or SSH credentials.
|
|
55
|
+
|
|
56
|
+
The AWS-managed Ubuntu 24.04 standard image is the immutable base. Before a
|
|
57
|
+
native lifecycle starts, Buildchain installs the distribution's `gcc-14` and
|
|
58
|
+
`g++-14` packages, exposes only per-job `gcc`/`g++` aliases, and downloads the
|
|
59
|
+
pinned Kitware CMake 3.31.6 archive after verifying its reviewed SHA256. The
|
|
60
|
+
resolved package manager, versions, and CMake source digest are retained as
|
|
61
|
+
`aws-native-toolchain.json`; no toolchain state survives the ephemeral
|
|
62
|
+
CodeBuild execution. The toolchain adapter also retains the reviewed Amazon
|
|
63
|
+
Linux 2023 `gcc14` path for compatible projects.
|
|
64
|
+
|
|
65
|
+
## Cost and kill-switch envelope
|
|
66
|
+
|
|
67
|
+
The 2026-07-28 AWS Price List entry for
|
|
68
|
+
`BUILD_GENERAL1_XLARGE` Linux in `us-east-1` is USD 0.0798 per build minute.
|
|
69
|
+
The contract rounds that rate up to USD 0.08. Twelve fully timed-out accepted
|
|
70
|
+
builds reserve at most USD 38.40. At project concurrency two, the fail-closed
|
|
71
|
+
controller can see at most two over-cap builds. The envelope conservatively
|
|
72
|
+
charges both race builds for their complete 40-minute timeout rather than
|
|
73
|
+
assuming fast EventBridge delivery. The bounded CodeBuild maximum is therefore
|
|
74
|
+
USD 44.80, below the dedicated USD 49 budget and leaving USD 4.20 for the small
|
|
75
|
+
controller, state, notification, and log charges.
|
|
76
|
+
|
|
77
|
+
The controller stores an idempotent build-id ledger, an atomic accepted-build
|
|
78
|
+
counter, and worst-case reservation in DynamoDB. Duplicate EventBridge delivery
|
|
79
|
+
does not consume the bounded build allowance. It deletes the CodeBuild webhook
|
|
80
|
+
and stops the triggering build when:
|
|
81
|
+
|
|
82
|
+
- the accepted-build or reserved-cost cap is reached;
|
|
83
|
+
- actual-cost telemetry is missing or more than six hours old;
|
|
84
|
+
- actual CodeBuild spend reaches the budget;
|
|
85
|
+
- AWS Budgets sends the 80% or 95% actual-spend notification;
|
|
86
|
+
- the kill switch was already set.
|
|
87
|
+
|
|
88
|
+
The stack starts fail closed: it has no cost telemetry item and CloudFormation
|
|
89
|
+
does not create the webhook. Before arming the webhook, the operator must write
|
|
90
|
+
a current Cost Explorer observation to the `COST` item, clear only the dedicated
|
|
91
|
+
controller's killed state, and create the exact workflow-filtered webhook.
|
|
92
|
+
Re-arming after any kill is a separate provider mutation and requires a new
|
|
93
|
+
explicit approval.
|
|
94
|
+
|
|
95
|
+
## Qualification evidence
|
|
96
|
+
|
|
97
|
+
Each successful job uploads `aws-runner-burst.json`, binding:
|
|
98
|
+
|
|
99
|
+
- consumer repository, exact source SHA and ref;
|
|
100
|
+
- GitHub run id, attempt and job;
|
|
101
|
+
- CodeBuild project, build id, build ARN and initiator;
|
|
102
|
+
- observation timestamp and canonical digest.
|
|
103
|
+
|
|
104
|
+
Linux qualification requires:
|
|
105
|
+
|
|
106
|
+
- at least 10 trusted exact-source successful jobs;
|
|
107
|
+
- observed concurrency of at least two;
|
|
108
|
+
- p95 queue-to-start of at most five minutes;
|
|
109
|
+
- actual incremental AWS spend below USD 49;
|
|
110
|
+
- no idle build and no active cloud residue.
|
|
111
|
+
|
|
112
|
+
`node scripts/aws-runner-burst.mjs verify-linux --input <snapshot.json>` fails
|
|
113
|
+
closed when cost telemetry is missing/stale or any acceptance predicate is
|
|
114
|
+
false.
|
|
115
|
+
|
|
116
|
+
### Phase 1 recorded outcome
|
|
117
|
+
|
|
118
|
+
The Linux phase passed on 2026-07-29. Ten trusted exact-source Kungfu jobs
|
|
119
|
+
completed successfully, including four overlapping two-job waves. The observed
|
|
120
|
+
CodeBuild queue-to-start p95 was 0.696 seconds. All 16 paid executions,
|
|
121
|
+
including six diagnostic runs, produced a conservative incremental compute
|
|
122
|
+
upper bound of USD 25.798 by rounding every execution up to a whole minute at
|
|
123
|
+
the live AWS Price List rate.
|
|
124
|
+
|
|
125
|
+
The global webhook kill switch was exercised after the tenth qualifying job.
|
|
126
|
+
The project then reported no webhook or in-progress build, and the card-owned
|
|
127
|
+
EC2 inventory was empty. AWS Billing and Cost Explorer still reported an
|
|
128
|
+
estimated zero during their provider ingestion delay; the retained
|
|
129
|
+
execution-derived upper bound is therefore the immediate cost proof and must be
|
|
130
|
+
reconciled with the eventual AWS line item in the final campaign report.
|
|
131
|
+
|
|
132
|
+
The source-bound evidence and deterministic phase receipt are:
|
|
133
|
+
|
|
134
|
+
- `evidence/aws-us-elastic-runner-burst-plane/linux-codebuild-qualification-input.json`
|
|
135
|
+
- `evidence/aws-us-elastic-runner-burst-plane/linux-codebuild-qualification-receipt.json`
|
|
136
|
+
|
|
137
|
+
## Phase 2 contract
|
|
138
|
+
|
|
139
|
+
The Windows phase uses the explicit `aws-us-ec2-windows-jit` runner preset.
|
|
140
|
+
Its caller supplies one bounded label under
|
|
141
|
+
`aws-us-ec2-windows-jit-<qualification-id>`, and Buildchain resolves exactly
|
|
142
|
+
one Windows x64 native lane. The reusable trust gate still runs on a
|
|
143
|
+
GitHub-hosted runner before the JIT label can select EC2.
|
|
144
|
+
|
|
145
|
+
The provider creates repository-level GitHub JIT configuration for
|
|
146
|
+
`kungfu-systems/kungfu`. Its `labels` request must contain all four scheduling
|
|
147
|
+
labels: `self-hosted`, `Windows`, `X64`, and the card-scoped
|
|
148
|
+
`aws-us-ec2-windows-jit-<qualification-id>` label. GitHub's JIT endpoint does
|
|
149
|
+
not infer the default OS and architecture labels when they are omitted. The
|
|
150
|
+
encoded configuration is never placed in EC2 user data, a tag, a command log,
|
|
151
|
+
or an artifact. The operator writes it to a card-scoped SSM SecureString under
|
|
152
|
+
`/kungfu/burst/windows/`; the instance role can read and delete only that
|
|
153
|
+
prefix. Bootstrap reads the value once, deletes the parameter immediately, and
|
|
154
|
+
passes it only to the pinned runner process.
|
|
155
|
+
|
|
156
|
+
Each runner uses:
|
|
157
|
+
|
|
158
|
+
- Amazon's current Windows Server 2025 Full Base AMI, resolved through the
|
|
159
|
+
public SSM AMI parameter and retained by exact AMI id and name;
|
|
160
|
+
- `c7i.4xlarge`, one instance and one JIT runner per job;
|
|
161
|
+
- GitHub Actions Runner 2.336.0 with the official Windows x64 SHA256;
|
|
162
|
+
- PowerShell 7.6.4 with the official Windows x64 MSI SHA256 and Microsoft
|
|
163
|
+
Authenticode verification;
|
|
164
|
+
- pinned PortableGit 2.55.0.3 with its GitHub release SHA256, exposing only its
|
|
165
|
+
`cmd` directory so POSIX compatibility tools cannot shadow Windows tools;
|
|
166
|
+
- a Microsoft Authenticode-verified Visual Studio 2022 Build Tools bootstrap;
|
|
167
|
+
- IMDSv2, an encrypted root volume with delete-on-termination, no inbound
|
|
168
|
+
security-group rule, no key pair, and no warm Auto Scaling capacity.
|
|
169
|
+
|
|
170
|
+
Runner diagnostics and a redacted lifecycle record are uploaded to the
|
|
171
|
+
provider's encrypted, private evidence bucket. The runner process exits after
|
|
172
|
+
one job, Windows shuts down, and EC2's instance-initiated shutdown behavior is
|
|
173
|
+
set to `terminate`. A five-minute reaper terminates card-owned stopped or
|
|
174
|
+
three-hour-old instances and deletes only their dedicated JIT parameter.
|
|
175
|
+
|
|
176
|
+
At the 2026-07-29 AWS Price List rate of USD 1.45 per Windows
|
|
177
|
+
`c7i.4xlarge` hour, six accepted three-hour instances reserve USD 26.10. The
|
|
178
|
+
two-instance race envelope reserves another USD 8.70, producing a USD 34.80
|
|
179
|
+
worst case below the dedicated USD 40 budget. Budget notifications at 80% and
|
|
180
|
+
95% invoke the same card-scoped global kill switch.
|
|
181
|
+
|
|
182
|
+
Qualification requires one runner-profile smoke, three trusted exact-source
|
|
183
|
+
full Windows jobs, independent cancellation and timeout cleanup exercises, and
|
|
184
|
+
zero repository runner, EC2 instance, disposable volume, min capacity, and
|
|
185
|
+
desired capacity within 15 minutes of the final job.
|
|
186
|
+
|
|
187
|
+
## Phase 3 contract
|
|
188
|
+
|
|
189
|
+
The macOS phase uses the explicit `aws-us-ec2-macos-jit` runner preset. Its
|
|
190
|
+
caller supplies one unique label under
|
|
191
|
+
`aws-us-ec2-macos-jit-<qualification-id>`, and Buildchain resolves exactly one
|
|
192
|
+
native macOS ARM64 lane with `self-hosted`, `macOS`, `ARM64`, and the unique
|
|
193
|
+
campaign label. The reusable trust gate remains ahead of the JIT runner.
|
|
194
|
+
|
|
195
|
+
Unlike Windows, the Mac campaign deliberately reuses one instance on one
|
|
196
|
+
`mac2.metal` Dedicated Host. The operator allocates exactly one tagged host,
|
|
197
|
+
launches exactly one tagged instance, and sends three sequential SSM bootstrap
|
|
198
|
+
commands. Each command consumes and immediately deletes a distinct repository
|
|
199
|
+
JIT SecureString under `/kungfu/burst/macos/`, then runs GitHub Actions Runner
|
|
200
|
+
2.336.0 for exactly one job. The runner archive is pinned to the official
|
|
201
|
+
macOS ARM64 SHA256. No GitHub, signing, notarization, publication, SSH, or
|
|
202
|
+
static AWS credential is admitted to the instance.
|
|
203
|
+
|
|
204
|
+
The instance uses the exact retained Amazon EC2 macOS AMI, IMDSv2, an encrypted
|
|
205
|
+
delete-on-termination root volume, no inbound security-group rule, and the
|
|
206
|
+
AMI's preinstalled SSM Agent and AWS CLI v2. The three accepted jobs must bind
|
|
207
|
+
to the same host id, instance id, AMI id, source SHA, and campaign. At least one
|
|
208
|
+
job must exercise the full native lifecycle.
|
|
209
|
+
|
|
210
|
+
AWS imposes a 24-hour minimum Dedicated Host allocation. The contract therefore
|
|
211
|
+
keeps the one host for at least 24 hours even if all three jobs finish earlier.
|
|
212
|
+
At the recorded USD 0.6498 hourly rate, the minimum commitment rounds to USD
|
|
213
|
+
15.60. A 30-hour fail-closed ceiling rounds to USD 19.49, below the dedicated
|
|
214
|
+
USD 25 budget. A ten-minute reaper terminates an expired campaign instance and
|
|
215
|
+
retries host release after the minimum allocation and Apple scrub constraints
|
|
216
|
+
allow it. Budget notifications at 80% and 95% invoke the same card-scoped kill
|
|
217
|
+
switch.
|
|
218
|
+
|
|
219
|
+
Qualification requires three trusted exact-source one-job JIT runs on the one
|
|
220
|
+
host, including at least one full run, plus proof that:
|
|
221
|
+
|
|
222
|
+
- the instance terminated and the encrypted disposable volume disappeared;
|
|
223
|
+
- Apple host scrub completed;
|
|
224
|
+
- the Dedicated Host was released between 24 and 30 hours after allocation;
|
|
225
|
+
- the repository has no registered campaign runner;
|
|
226
|
+
- AWS has no active campaign instance or allocated campaign host;
|
|
227
|
+
- actual incremental spend remained below USD 25.
|
|
228
|
+
|
|
229
|
+
## Provider lifecycle
|
|
230
|
+
|
|
231
|
+
The three infrastructure templates live under
|
|
232
|
+
`infra/aws-us-elastic-runner-burst-plane/`. Creating a change set is the review
|
|
233
|
+
boundary. Executing it, completing the GitHub App connection, creating or
|
|
234
|
+
re-arming a webhook, allocating or releasing a Dedicated Host, writing cost
|
|
235
|
+
telemetry, dispatching paid jobs, operating a kill switch, and deleting a stack
|
|
236
|
+
are all explicit provider mutations.
|
|
237
|
+
|
|
238
|
+
The reviewed Phase 1 provider sequence is below. It deliberately separates
|
|
239
|
+
connection creation, change-set inspection, stack execution, cost observation,
|
|
240
|
+
and webhook arming:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
burst_profile=us
|
|
244
|
+
burst_region=us-east-1
|
|
245
|
+
burst_stack=kungfu-buildchain-linux-burst-poc
|
|
246
|
+
burst_project=kungfu-buildchain-linux-burst-poc
|
|
247
|
+
burst_connection_name=kungfu-linux-burst-poc
|
|
248
|
+
burst_change_set=phase1-linux-codebuild-poc
|
|
249
|
+
|
|
250
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
251
|
+
codeconnections create-connection \
|
|
252
|
+
--provider-type GitHub \
|
|
253
|
+
--connection-name "$burst_connection_name" \
|
|
254
|
+
--tags Key=kungfu:owner,Value=buildchain \
|
|
255
|
+
Key=kungfu:plane,Value=aws-us-elastic-runner-burst
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
The returned connection is `PENDING` until an operator completes the GitHub App
|
|
259
|
+
handshake in AWS. Read back `ConnectionStatus=AVAILABLE` before creating the
|
|
260
|
+
change set. Do not put an OAuth token or GitHub token in the shell:
|
|
261
|
+
|
|
262
|
+
AWS CodeConnections connection names are limited to 32 characters, so keep the
|
|
263
|
+
shorter connection name even when the stack and project use the longer
|
|
264
|
+
Buildchain-specific name.
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
burst_connection_arn=REPLACE_WITH_AVAILABLE_CONNECTION_ARN
|
|
268
|
+
|
|
269
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
270
|
+
codeconnections get-connection \
|
|
271
|
+
--connection-arn "$burst_connection_arn"
|
|
272
|
+
|
|
273
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
274
|
+
cloudformation create-change-set \
|
|
275
|
+
--stack-name "$burst_stack" \
|
|
276
|
+
--change-set-name "$burst_change_set" \
|
|
277
|
+
--change-set-type CREATE \
|
|
278
|
+
--template-body \
|
|
279
|
+
file://infra/aws-us-elastic-runner-burst-plane/codebuild-poc.template.yml \
|
|
280
|
+
--capabilities CAPABILITY_IAM \
|
|
281
|
+
--parameters \
|
|
282
|
+
ParameterKey=GitHubConnectionArn,ParameterValue="$burst_connection_arn" \
|
|
283
|
+
ParameterKey=ProjectName,ParameterValue="$burst_project"
|
|
284
|
+
|
|
285
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
286
|
+
cloudformation wait change-set-create-complete \
|
|
287
|
+
--stack-name "$burst_stack" \
|
|
288
|
+
--change-set-name "$burst_change_set"
|
|
289
|
+
|
|
290
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
291
|
+
cloudformation describe-change-set \
|
|
292
|
+
--stack-name "$burst_stack" \
|
|
293
|
+
--change-set-name "$burst_change_set"
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Only after the change-set resource list and IAM diff are accepted:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
300
|
+
cloudformation execute-change-set \
|
|
301
|
+
--stack-name "$burst_stack" \
|
|
302
|
+
--change-set-name "$burst_change_set"
|
|
303
|
+
|
|
304
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
305
|
+
cloudformation wait stack-create-complete \
|
|
306
|
+
--stack-name "$burst_stack"
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Arming requires a fresh, operator-observed CodeBuild cost value. `COST` is the
|
|
310
|
+
only mutable telemetry item and `CONTROL` is the only state cleared:
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
burst_table=$(
|
|
314
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
315
|
+
cloudformation describe-stacks \
|
|
316
|
+
--stack-name "$burst_stack" \
|
|
317
|
+
--query "Stacks[0].Outputs[?OutputKey=='StateTable'].OutputValue" \
|
|
318
|
+
--output text
|
|
319
|
+
)
|
|
320
|
+
burst_observed_at=$(date -u +%s)
|
|
321
|
+
burst_actual_usd=REPLACE_WITH_CURRENT_CODEBUILD_ACTUAL_USD
|
|
322
|
+
|
|
323
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
324
|
+
dynamodb put-item \
|
|
325
|
+
--table-name "$burst_table" \
|
|
326
|
+
--item "{\"pk\":{\"S\":\"COST\"},\"actual_usd\":{\"N\":\"$burst_actual_usd\"},\"observed_at\":{\"N\":\"$burst_observed_at\"}}"
|
|
327
|
+
|
|
328
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
329
|
+
dynamodb delete-item \
|
|
330
|
+
--table-name "$burst_table" \
|
|
331
|
+
--key '{"pk":{"S":"CONTROL"}}'
|
|
332
|
+
|
|
333
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
334
|
+
codebuild create-webhook \
|
|
335
|
+
--project-name "$burst_project" \
|
|
336
|
+
--filter-groups \
|
|
337
|
+
'[[{"type":"EVENT","pattern":"WORKFLOW_JOB_QUEUED"},{"type":"WORKFLOW_NAME","pattern":"^AWS US Linux Burst Qualification$"}]]'
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
The immediate global kill is idempotent and targets only the dedicated project:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
344
|
+
codebuild delete-webhook \
|
|
345
|
+
--project-name "$burst_project"
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
After preserving the qualification evidence and proving no build is in
|
|
349
|
+
progress, rollback removes only the card-owned stack and connection:
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
353
|
+
cloudformation delete-stack \
|
|
354
|
+
--stack-name "$burst_stack"
|
|
355
|
+
|
|
356
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
357
|
+
cloudformation wait stack-delete-complete \
|
|
358
|
+
--stack-name "$burst_stack"
|
|
359
|
+
|
|
360
|
+
aws --profile "$burst_profile" --region "$burst_region" \
|
|
361
|
+
codeconnections delete-connection \
|
|
362
|
+
--connection-arn "$burst_connection_arn"
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Phase cleanup evidence must include:
|
|
366
|
+
|
|
367
|
+
- CodeBuild batch/list results showing no in-progress build;
|
|
368
|
+
- controller state and accepted-build ledger;
|
|
369
|
+
- CodeBuild actual cost observation and its timestamp;
|
|
370
|
+
- no EC2 instance, volume, launch template, Auto Scaling group, or dedicated
|
|
371
|
+
host created by this phase;
|
|
372
|
+
- the CodeBuild webhook deleted or the whole stack deleted.
|
|
373
|
+
|
|
374
|
+
## Source boundaries
|
|
375
|
+
|
|
376
|
+
The design follows the current AWS CodeBuild GitHub Actions runner contract:
|
|
377
|
+
`WORKFLOW_JOB_QUEUED` starts an ephemeral runner, the run id maps cancellation,
|
|
378
|
+
and the build terminates after one job. It uses the current GitHub guidance to
|
|
379
|
+
prefer ephemeral autoscaled self-hosted runners and to retain runner logs
|
|
380
|
+
externally. Provider documentation and the live AWS Price List query are the
|
|
381
|
+
authoritative external sources; this document is an auditable cache.
|