@kungfu-tech/buildchain 3.0.5 → 3.0.6-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/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 +126 -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 +103 -16
- package/dist/site/kfd-upstream-aggregate.json +9 -9
- package/dist/site/manual-registry.json +10 -9
- package/dist/site/node-api-registry.json +540 -31
- package/dist/site/page-registry.json +110 -29
- package/dist/site/public-surface-audit.json +186 -12
- 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 +120 -5
- package/docs/MAP.md +5 -1
- package/docs/auditable-demo.md +90 -7
- package/docs/aws-us-elastic-runner-burst-plane.md +181 -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 +47 -1
- 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 +3 -2
- 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 +295 -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 +185 -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 +15 -15
- package/scripts/dev-qualification-patrol.mjs +594 -0
- package/scripts/dispatch-artifact-signing-authority.mjs +310 -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
|
@@ -126,6 +126,7 @@
|
|
|
126
126
|
"checkout-cache-mode",
|
|
127
127
|
"checkout-cache-reference-repository-template",
|
|
128
128
|
"checkout-cache-timeout-seconds",
|
|
129
|
+
"checkout-history-mode",
|
|
129
130
|
"compiler-cache-platforms-json",
|
|
130
131
|
"compiler-cache-provider",
|
|
131
132
|
"compiler-cache-required",
|
|
@@ -147,6 +148,8 @@
|
|
|
147
148
|
"linux-container-preset",
|
|
148
149
|
"node-version",
|
|
149
150
|
"platforms-json",
|
|
151
|
+
"pre-upload-transport-smoke-artifact-root",
|
|
152
|
+
"pre-upload-transport-smoke-scenario-path",
|
|
150
153
|
"process-sample-interval-ms",
|
|
151
154
|
"process-summary-path",
|
|
152
155
|
"publish-anchor-request-json",
|
|
@@ -175,7 +178,7 @@
|
|
|
175
178
|
"verify-command",
|
|
176
179
|
"working-directory"
|
|
177
180
|
],
|
|
178
|
-
"inputCount":
|
|
181
|
+
"inputCount": 85,
|
|
179
182
|
"secrets": [
|
|
180
183
|
"BUILDCHAIN_ARTIFACT_RELAY_S3_DOWNLOAD_ROLE_ARN",
|
|
181
184
|
"BUILDCHAIN_ARTIFACT_RELAY_S3_ROLE_ARN",
|
|
@@ -268,6 +271,48 @@
|
|
|
268
271
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
269
272
|
"nonDuplicationRationale": "Existing workflow identity retained for caller compatibility and repository orchestration."
|
|
270
273
|
},
|
|
274
|
+
{
|
|
275
|
+
"id": ".declarative-auditable-demo",
|
|
276
|
+
"path": ".github/workflows/.declarative-auditable-demo.yml",
|
|
277
|
+
"reusable": true,
|
|
278
|
+
"inputs": [
|
|
279
|
+
"artifact-retention-days",
|
|
280
|
+
"binary-artifact-digest",
|
|
281
|
+
"binary-artifact-name",
|
|
282
|
+
"buildchain-repository",
|
|
283
|
+
"materialize",
|
|
284
|
+
"materialize-base-ref",
|
|
285
|
+
"media-profile",
|
|
286
|
+
"render-media",
|
|
287
|
+
"renderer-image",
|
|
288
|
+
"scenario-path",
|
|
289
|
+
"source-ref"
|
|
290
|
+
],
|
|
291
|
+
"inputCount": 11,
|
|
292
|
+
"secrets": [
|
|
293
|
+
"DEMO_UPDATE_TOKEN"
|
|
294
|
+
],
|
|
295
|
+
"secretCount": 1,
|
|
296
|
+
"outputs": [
|
|
297
|
+
"capture-artifact-digest",
|
|
298
|
+
"capture-artifact-name",
|
|
299
|
+
"evidence-artifact-digest",
|
|
300
|
+
"evidence-artifact-name",
|
|
301
|
+
"publication-pr-url",
|
|
302
|
+
"source-sha"
|
|
303
|
+
],
|
|
304
|
+
"outputCount": 6,
|
|
305
|
+
"surface": "declarative-auditable-demo",
|
|
306
|
+
"capabilityGroup": "api-cli-reference",
|
|
307
|
+
"status": "preview",
|
|
308
|
+
"owner": "buildchain-workflows",
|
|
309
|
+
"maturity": "preview",
|
|
310
|
+
"introducedVersion": "pre-3.0.2-alpha.4",
|
|
311
|
+
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
312
|
+
"deprecationReplacement": "",
|
|
313
|
+
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
314
|
+
"nonDuplicationRationale": "Existing workflow identity retained for caller compatibility and repository orchestration."
|
|
315
|
+
},
|
|
271
316
|
{
|
|
272
317
|
"id": ".gate-profile",
|
|
273
318
|
"path": ".github/workflows/.gate-profile.yml",
|
|
@@ -1050,6 +1095,27 @@
|
|
|
1050
1095
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
1051
1096
|
"nonDuplicationRationale": "Existing workflow identity retained for caller compatibility and repository orchestration."
|
|
1052
1097
|
},
|
|
1098
|
+
{
|
|
1099
|
+
"id": "auditable-demo",
|
|
1100
|
+
"path": ".github/workflows/auditable-demo.yml",
|
|
1101
|
+
"reusable": false,
|
|
1102
|
+
"inputs": [],
|
|
1103
|
+
"inputCount": 0,
|
|
1104
|
+
"secrets": [],
|
|
1105
|
+
"secretCount": 0,
|
|
1106
|
+
"outputs": [],
|
|
1107
|
+
"outputCount": 0,
|
|
1108
|
+
"surface": "repository-workflow",
|
|
1109
|
+
"capabilityGroup": "api-cli-reference",
|
|
1110
|
+
"status": "active",
|
|
1111
|
+
"owner": "buildchain-workflows",
|
|
1112
|
+
"maturity": "active",
|
|
1113
|
+
"introducedVersion": "pre-3.0.2-alpha.4",
|
|
1114
|
+
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
1115
|
+
"deprecationReplacement": "",
|
|
1116
|
+
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
1117
|
+
"nonDuplicationRationale": "Existing workflow identity retained for caller compatibility and repository orchestration."
|
|
1118
|
+
},
|
|
1053
1119
|
{
|
|
1054
1120
|
"id": "binary-distribution",
|
|
1055
1121
|
"path": ".github/workflows/binary-distribution.yml",
|
|
@@ -1155,6 +1221,7 @@
|
|
|
1155
1221
|
"checkout-cache-mode",
|
|
1156
1222
|
"checkout-cache-reference-repository-template",
|
|
1157
1223
|
"checkout-cache-timeout-seconds",
|
|
1224
|
+
"checkout-history-mode",
|
|
1158
1225
|
"compiler-cache-platforms-json",
|
|
1159
1226
|
"compiler-cache-provider",
|
|
1160
1227
|
"compiler-cache-required",
|
|
@@ -1176,6 +1243,8 @@
|
|
|
1176
1243
|
"linux-container-preset",
|
|
1177
1244
|
"node-version",
|
|
1178
1245
|
"platforms-json",
|
|
1246
|
+
"pre-upload-transport-smoke-artifact-root",
|
|
1247
|
+
"pre-upload-transport-smoke-scenario-path",
|
|
1179
1248
|
"process-sample-interval-ms",
|
|
1180
1249
|
"process-summary-path",
|
|
1181
1250
|
"publish-anchor-request-json",
|
|
@@ -1204,7 +1273,7 @@
|
|
|
1204
1273
|
"verify-command",
|
|
1205
1274
|
"working-directory"
|
|
1206
1275
|
],
|
|
1207
|
-
"inputCount":
|
|
1276
|
+
"inputCount": 88,
|
|
1208
1277
|
"secrets": [
|
|
1209
1278
|
"BUILDCHAIN_ARTIFACT_RELAY_S3_DOWNLOAD_ROLE_ARN",
|
|
1210
1279
|
"BUILDCHAIN_ARTIFACT_RELAY_S3_ROLE_ARN",
|
|
@@ -1534,12 +1603,14 @@
|
|
|
1534
1603
|
"reusable": true,
|
|
1535
1604
|
"inputs": [
|
|
1536
1605
|
"alpha-workflow-path",
|
|
1606
|
+
"auto-merge",
|
|
1537
1607
|
"buildchain-ref",
|
|
1538
1608
|
"buildchain-repository",
|
|
1539
1609
|
"create-pull-request",
|
|
1540
1610
|
"dev-workflow-path",
|
|
1541
1611
|
"dry-run",
|
|
1542
1612
|
"max-age-seconds",
|
|
1613
|
+
"merge-method",
|
|
1543
1614
|
"pull-request-body-prefix",
|
|
1544
1615
|
"pull-request-body-prefix-renderer",
|
|
1545
1616
|
"reactivation-authorized",
|
|
@@ -1547,7 +1618,7 @@
|
|
|
1547
1618
|
"source-branch",
|
|
1548
1619
|
"target-branch"
|
|
1549
1620
|
],
|
|
1550
|
-
"inputCount":
|
|
1621
|
+
"inputCount": 15,
|
|
1551
1622
|
"secrets": [
|
|
1552
1623
|
"promotion-token"
|
|
1553
1624
|
],
|
|
@@ -1610,13 +1681,14 @@
|
|
|
1610
1681
|
"landing-mode",
|
|
1611
1682
|
"max-merges",
|
|
1612
1683
|
"merge-method",
|
|
1684
|
+
"queue-admission-context",
|
|
1613
1685
|
"ready-label",
|
|
1614
1686
|
"require-approval",
|
|
1615
1687
|
"required-status-checks",
|
|
1616
1688
|
"same-repository-only",
|
|
1617
1689
|
"target-branch"
|
|
1618
1690
|
],
|
|
1619
|
-
"inputCount":
|
|
1691
|
+
"inputCount": 14,
|
|
1620
1692
|
"secrets": [
|
|
1621
1693
|
"github-token"
|
|
1622
1694
|
],
|
|
@@ -1641,6 +1713,48 @@
|
|
|
1641
1713
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
1642
1714
|
"nonDuplicationRationale": "Existing workflow identity retained for caller compatibility and repository orchestration."
|
|
1643
1715
|
},
|
|
1716
|
+
{
|
|
1717
|
+
"id": "dev-qualification-patrol",
|
|
1718
|
+
"path": ".github/workflows/dev-qualification-patrol.yml",
|
|
1719
|
+
"reusable": true,
|
|
1720
|
+
"inputs": [
|
|
1721
|
+
"buildchain-ref",
|
|
1722
|
+
"buildchain-repository",
|
|
1723
|
+
"dev-workflow-path",
|
|
1724
|
+
"dispatch-inputs-json",
|
|
1725
|
+
"dry-run",
|
|
1726
|
+
"max-attempts",
|
|
1727
|
+
"mutation-authorized",
|
|
1728
|
+
"preflight-workflow-path",
|
|
1729
|
+
"priority-workflows-json",
|
|
1730
|
+
"source-branch"
|
|
1731
|
+
],
|
|
1732
|
+
"inputCount": 10,
|
|
1733
|
+
"secrets": [
|
|
1734
|
+
"qualification-token"
|
|
1735
|
+
],
|
|
1736
|
+
"secretCount": 1,
|
|
1737
|
+
"outputs": [
|
|
1738
|
+
"action",
|
|
1739
|
+
"active-run-id",
|
|
1740
|
+
"decision-root",
|
|
1741
|
+
"pending-sha",
|
|
1742
|
+
"reason",
|
|
1743
|
+
"source-sha",
|
|
1744
|
+
"state"
|
|
1745
|
+
],
|
|
1746
|
+
"outputCount": 7,
|
|
1747
|
+
"surface": "repository-patrol",
|
|
1748
|
+
"capabilityGroup": "governance-versioning",
|
|
1749
|
+
"status": "active",
|
|
1750
|
+
"owner": "buildchain-workflows",
|
|
1751
|
+
"maturity": "active",
|
|
1752
|
+
"introducedVersion": "pre-3.0.2-alpha.4",
|
|
1753
|
+
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
1754
|
+
"deprecationReplacement": "",
|
|
1755
|
+
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
1756
|
+
"nonDuplicationRationale": "Existing workflow identity retained for caller compatibility and repository orchestration."
|
|
1757
|
+
},
|
|
1644
1758
|
{
|
|
1645
1759
|
"id": "github-artifact-attestation",
|
|
1646
1760
|
"path": ".github/workflows/github-artifact-attestation.yml",
|
|
@@ -2424,6 +2538,7 @@
|
|
|
2424
2538
|
"hold",
|
|
2425
2539
|
"hold-reason",
|
|
2426
2540
|
"ledger-ref",
|
|
2541
|
+
"merge-method",
|
|
2427
2542
|
"minimum-soak-seconds",
|
|
2428
2543
|
"release-now",
|
|
2429
2544
|
"required-checks",
|
|
@@ -2431,7 +2546,7 @@
|
|
|
2431
2546
|
"revoked-versions",
|
|
2432
2547
|
"target-branch"
|
|
2433
2548
|
],
|
|
2434
|
-
"inputCount":
|
|
2549
|
+
"inputCount": 16,
|
|
2435
2550
|
"secrets": [
|
|
2436
2551
|
"approval-token",
|
|
2437
2552
|
"promotion-token"
|
package/docs/MAP.md
CHANGED
|
@@ -84,7 +84,7 @@ workflow, action, and Node API export also carries a `capabilityGroup`,
|
|
|
84
84
|
| Git/source/version/module/product build facts | `dist/site/node-api-registry.json`, `dist/site/cli-registry.json`, `kungfu-buildchain-module-build-facts`, `kungfu-buildchain-product-build-facts` | [`build-facts.md`](build-facts.md) |
|
|
85
85
|
| GitHub Release passport/evidence publication | `dist/site/release-model.json`, `dist/site/artifact-schemas.json` | [`release-governance.md`](release-governance.md), [`release-candidate.md`](release-candidate.md) |
|
|
86
86
|
| GitHub ownership, effective protection, plan capability, and managed-zone governance receipts | `dist/site/node-api-registry.json`, `dist/site/cli-registry.json`, `kungfu-buildchain-github-governance-receipt` | [`github-governance-authority.md`](github-governance-authority.md) |
|
|
87
|
-
| release propagation
|
|
87
|
+
| release propagation and the unified Paper/KFD/Buildchain/Core Site agent entry | `dist/site/release-model.json`, `dist/site/cli-registry.json`, `dist/site/node-api-registry.json` | [`release-propagation.md`](release-propagation.md) |
|
|
88
88
|
| publication artifact manifests, immutable archive registries, source bundles, and paper repository workflows | `dist/site/publication-registry.json`, `dist/site/workflow-registry.json`, `dist/site/node-api-registry.json`, `kungfu-buildchain-publication-artifact-manifest`, `kungfu-buildchain-publication-artifact-registry` | [`publication-artifacts.md`](publication-artifacts.md) |
|
|
89
89
|
| Generated badge bundles, README badge blocks, and badge facts | `dist/site/node-api-registry.json`, `dist/site/manual-registry.json`, `kungfu-buildchain-badge-bundle-facts`, `kungfu-buildchain-readme-badge-facts` | [`readme-badges.md`](readme-badges.md) |
|
|
90
90
|
| Homebrew tap distribution indexes | `dist/site/node-api-registry.json`, `dist/site/buildchain-contract.json` | [`homebrew.md`](homebrew.md) |
|
|
@@ -111,6 +111,7 @@ replace them.
|
|
|
111
111
|
| Why does Buildchain use branch-driven release governance? | [`release-governance.md`](release-governance.md) | why | stable |
|
|
112
112
|
| How do protected dev branches and scheduled ready-PR merging work? | [`release-governance.md`](release-governance.md#protected-dev-branches) | use | stable |
|
|
113
113
|
| How do slow required checks land reliably on a busy dev channel? | [`release-governance.md`](release-governance.md#protected-dev-branches) + [`cli.md`](cli.md#commands) | use | preview |
|
|
114
|
+
| How do I coalesce rapid Dev changes, preserve release runner priority, and retry only transient failed jobs? | [`dev-qualification-patrol.md`](dev-qualification-patrol.md) | use/verify | preview |
|
|
114
115
|
| How do I run daily, weekly, or monthly repository patrols? | [`release-governance.md`](release-governance.md#buildchain-patrol) | use | stable |
|
|
115
116
|
| How does Buildchain decide patch, minor, and major release lines? | [`versioning.md`](versioning.md) | why | stable |
|
|
116
117
|
| What exact branch/tag state machine runs on alpha, release, and major gate? | [`release-flow.md`](release-flow.md) | verify | stable |
|
|
@@ -151,6 +152,7 @@ replace them.
|
|
|
151
152
|
| 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 |
|
|
152
153
|
| How do I deploy a site/app preview, staging, or production surface? | [`web-surface-deployments.md`](web-surface-deployments.md) | use | stable |
|
|
153
154
|
| How do I publish observed infrastructure contracts for downstream consumers? | [`infra-contract.md`](infra-contract.md) | use | preview |
|
|
155
|
+
| How do I operate a repeatable, disabled-by-default, budget-fail-closed AWS Windows JIT campaign? | [`aws-us-elastic-runner-burst-plane.md`](aws-us-elastic-runner-burst-plane.md#phase-2-operator-workflow) | use/verify | preview |
|
|
154
156
|
| 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 |
|
|
155
157
|
| 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 |
|
|
156
158
|
| 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 |
|
|
@@ -176,6 +178,8 @@ replace them.
|
|
|
176
178
|
- **protected dev branches / scheduled ready-PR merge / daily-weekly-monthly patrol** ->
|
|
177
179
|
[`release-governance.md`](release-governance.md#protected-dev-branches) and
|
|
178
180
|
[`release-governance.md`](release-governance.md#buildchain-patrol).
|
|
181
|
+
- **Dev qualification coalescing / release-priority runners / failed-job retry** ->
|
|
182
|
+
[`dev-qualification-patrol.md`](dev-qualification-patrol.md).
|
|
179
183
|
- **pnpm / npm / yarn / package-manager adapters** ->
|
|
180
184
|
[`lifecycle-protocol.md`](lifecycle-protocol.md).
|
|
181
185
|
- **pip / Conan / CMake / custom commands** -> [`lifecycle-protocol.md`](lifecycle-protocol.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-
|
|
11
|
+
last_reviewed: 2026-08-02
|
|
12
12
|
ai_provenance:
|
|
13
13
|
model_family: GPT-5
|
|
14
14
|
product: Codex
|
|
15
|
-
generated_at: 2026-
|
|
15
|
+
generated_at: 2026-08-02
|
|
16
16
|
invisible_context_boundary: No hidden model build, parameter count, or private corpus is asserted.
|
|
17
17
|
---
|
|
18
18
|
|
|
@@ -30,6 +30,84 @@ The public reusable workflow is
|
|
|
30
30
|
does not know how a Kungfu, library, service, or application artifact should be
|
|
31
31
|
interpreted. The consumer owns a small checked-in executable adapter.
|
|
32
32
|
|
|
33
|
+
For standalone binary CLIs, the higher-level first-class surface is
|
|
34
|
+
`.github/workflows/.declarative-auditable-demo.yml`. A consumer checks in only
|
|
35
|
+
`.buildchain/auditable-demo.json`, builds and uploads its exact same-run binary
|
|
36
|
+
plus metadata, and passes the producer-owned artifact name and digest to that
|
|
37
|
+
workflow. Buildchain then owns capture, Gate adaptation, independent native
|
|
38
|
+
1080p and 720p rendering, Release Passport construction, content-addressed
|
|
39
|
+
materialization, and the protected README update pull request. No
|
|
40
|
+
product-specific capture, adapter, passport, or materializer is required.
|
|
41
|
+
|
|
42
|
+
## Declarative Standalone Binary Scenarios
|
|
43
|
+
|
|
44
|
+
The schema is `contracts/auditable-demo-scenario-v1.schema.json`. One scenario
|
|
45
|
+
can declare up to eight demos, and each demo can contain up to twelve ordered
|
|
46
|
+
literal argv steps. Steps in one demo share a disposable workspace; separate
|
|
47
|
+
demos and the two rendition captures do not. Commands are never accepted as a
|
|
48
|
+
shell string. An omitted or explicit `standard` duration class remains bounded
|
|
49
|
+
to 60 seconds. A reviewed `execution.durationClass: long-form` declaration may
|
|
50
|
+
raise the scenario and literal step ceilings to 180 seconds; it does not change
|
|
51
|
+
the default. Both classes retain 4 MiB per step, a clean Home/XDG environment,
|
|
52
|
+
no inherited credentials, and a network-disabled read-only container with
|
|
53
|
+
bounded tmpfs.
|
|
54
|
+
|
|
55
|
+
The uploaded metadata must bind the executable SHA-256, declare an empty
|
|
56
|
+
runtime dependency set, and provide a bounded `executableFiles` array of exact
|
|
57
|
+
artifact-relative paths and SHA-256 digests. GitHub Artifact transport does not
|
|
58
|
+
retain Unix executable modes, so Buildchain restores mode `0755` only for this
|
|
59
|
+
digest-verified executable closure and verifies the same closure again inside
|
|
60
|
+
the network-disabled capture boundary. It never recursively changes artifact
|
|
61
|
+
modes. This metadata controls assembly only and grants no execution,
|
|
62
|
+
publication, or identity authority. Capture rejects an artifact name or upload
|
|
63
|
+
digest that does not resolve to exactly one live artifact from the current workflow run.
|
|
64
|
+
|
|
65
|
+
Consumers may also declare one bounded, non-interactive `transportSmoke` argv
|
|
66
|
+
in the same scenario and opt the reusable build into
|
|
67
|
+
`pre-upload-transport-smoke-scenario-path`. Before any GitHub Artifact or S3
|
|
68
|
+
relay upload, Buildchain copies the exact distribution directory, removes Unix
|
|
69
|
+
execute bits to simulate transport, restores only the digest-bound executable
|
|
70
|
+
closure, and runs that real binary with a clean Home/XDG environment. A missing
|
|
71
|
+
launcher, runtime, or embedded interpreter therefore fails before the expensive
|
|
72
|
+
upload begins. This is a transport diagnostic with no authority grants; the
|
|
73
|
+
later network-disabled capture and Gate remain the qualification authority.
|
|
74
|
+
It retains ANSI terminal bytes with the real PTY read timestamps, verifies
|
|
75
|
+
declared stdout and JSON file facts, enforces the total deadline while a step is
|
|
76
|
+
running, and removes the disposable workspace before emitting evidence.
|
|
77
|
+
|
|
78
|
+
Both manual validation and alpha or release refreshes call the same reusable
|
|
79
|
+
workflow. Manual callers select Gate-only or full rendering and can explicitly
|
|
80
|
+
request a materialization PR. Release callers select full rendering and the
|
|
81
|
+
same materializer automatically; there is no separate release-only recording
|
|
82
|
+
implementation. Publication requires a dedicated update token and target
|
|
83
|
+
branch. The token is an explicit bounded capability, while actor identity,
|
|
84
|
+
first-party/System classification, KFD compliance, Product System metadata,
|
|
85
|
+
package metadata, registry history, scans, and generated evidence grant no
|
|
86
|
+
authority.
|
|
87
|
+
|
|
88
|
+
```yaml
|
|
89
|
+
jobs:
|
|
90
|
+
demo:
|
|
91
|
+
needs: exact-binary
|
|
92
|
+
uses: kungfu-systems/buildchain/.github/workflows/.declarative-auditable-demo.yml@BUILDCHAIN_EXACT_SHA
|
|
93
|
+
with:
|
|
94
|
+
source-ref: ${{ github.sha }}
|
|
95
|
+
binary-artifact-name: ${{ needs.exact-binary.outputs.artifact-name }}
|
|
96
|
+
binary-artifact-digest: ${{ needs.exact-binary.outputs.artifact-digest }}
|
|
97
|
+
scenario-path: .buildchain/auditable-demo.json
|
|
98
|
+
renderer-image: ghcr.io/kungfu-systems/build-images/demo-renderer@sha256:RENDERER_DIGEST
|
|
99
|
+
render-media: true
|
|
100
|
+
media-profile: responsive-web-delivery-v1
|
|
101
|
+
materialize: true
|
|
102
|
+
materialize-base-ref: dev/v1/v1.0
|
|
103
|
+
secrets:
|
|
104
|
+
DEMO_UPDATE_TOKEN: ${{ secrets.DEMO_UPDATE_TOKEN }}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Buildchain recursively consumes this surface in
|
|
108
|
+
`.github/workflows/auditable-demo.yml` using its own exact standalone binary
|
|
109
|
+
and the beginner bootstrap scenario in `.buildchain/auditable-demo.json`.
|
|
110
|
+
|
|
33
111
|
## Authority Boundary
|
|
34
112
|
|
|
35
113
|
The retained build output is authoritative. The adapter reads that exact
|
|
@@ -42,9 +120,10 @@ scene.json
|
|
|
42
120
|
```
|
|
43
121
|
|
|
44
122
|
It may additionally emit one declared `terminal-capture.json` using
|
|
45
|
-
`kungfu.terminal-capture/v1`. The optional capture is bounded to 60 seconds
|
|
123
|
+
`kungfu.terminal-capture/v1`. The optional capture is bounded to 60 seconds by
|
|
124
|
+
default or 180 seconds only when its scene explicitly declares `long-form`,
|
|
46
125
|
fixed 80-200 by 24-80 terminal cells, 10,000 events, and 4 MiB of canonical
|
|
47
|
-
base64 bytes. It must contain a
|
|
126
|
+
base64 bytes. It must contain a qualified completion sentinel and an explicitly
|
|
48
127
|
empty authority-grant list. Existing three-file adapters remain valid.
|
|
49
128
|
|
|
50
129
|
The completion sentinel names a consumer-owned versioned schema, the exact
|
|
@@ -151,6 +230,7 @@ shell fragments, arbitrary profile paths, or transcoding instructions.
|
|
|
151
230
|
| `archive-v1` | Default compatibility contract. Retains the exact renderer outputs and classifies GIF as README compatibility evidence without making a browser-delivery claim. |
|
|
152
231
|
| `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. |
|
|
153
232
|
| `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. |
|
|
233
|
+
| `responsive-long-form-web-delivery-v1` | Extends the responsive profile for explicitly admitted long-form scenes. Its measured-baseline multipliers raise only the GIF ceiling to 8 MiB and the four video ceilings to 4 MiB; all codec, native-resolution, no-audio, duration, and authority checks remain unchanged. |
|
|
154
234
|
| `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. |
|
|
155
235
|
|
|
156
236
|
For web-delivery profiles, Buildchain runs its own fixed `ffprobe` invocation
|
|
@@ -185,8 +265,10 @@ Initial byte ceilings are derived from the checked-in
|
|
|
185
265
|
`auditable-demo-web-delivery-v1` fixture rendered by Build Images
|
|
186
266
|
`v1.3.0-alpha.16` at its exact source SHA and image digest. GIF, MP4, WebM, and
|
|
187
267
|
PNG ceilings are the next power of two above sixteen times the measured member
|
|
188
|
-
bytes. The
|
|
189
|
-
|
|
268
|
+
bytes. The explicit responsive long-form profile derives its 4 MiB video and
|
|
269
|
+
8 MiB GIF ceilings from the same observed bytes at a bounded 128-times
|
|
270
|
+
multiplier; it does not change another profile. The not-yet-produced WebP poster
|
|
271
|
+
uses eight times the measured lossless PNG as its conservative proxy. The path-scoped qualification workflow
|
|
190
272
|
regenerates the content-addressed evidence and fails on any byte or fact drift.
|
|
191
273
|
Its matrix retains the original 1280x720 web-delivery baseline on the renderer
|
|
192
274
|
that produced it and separately measures the responsive profile against a
|
|
@@ -242,7 +324,8 @@ build should always call the reusable workflow. Selection policy changes only
|
|
|
242
324
|
|
|
243
325
|
Use `web-delivery-v1` only when the rendered bundle is intended to become a
|
|
244
326
|
qualified web-delivery source. Use `site-hero-v1` when an optimized browser
|
|
245
|
-
poster is also required.
|
|
327
|
+
poster is also required. Select `responsive-long-form-web-delivery-v1` only
|
|
328
|
+
with an explicit long-form scenario. Profile qualification does not prove browser playback,
|
|
246
329
|
responsive layout, reduced-motion behavior, accessibility, or production
|
|
247
330
|
deployment; those remain site responsibilities.
|
|
248
331
|
|
|
@@ -8,7 +8,12 @@ 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
|
+
ai_provenance:
|
|
13
|
+
model_family: GPT-5
|
|
14
|
+
product: Codex
|
|
15
|
+
generated_at: 2026-08-03
|
|
16
|
+
invisible_information: No hidden model checkpoint, parameters, or private training data were available.
|
|
12
17
|
---
|
|
13
18
|
|
|
14
19
|
# AWS US elastic runner burst plane
|
|
@@ -138,14 +143,16 @@ The source-bound evidence and deterministic phase receipt are:
|
|
|
138
143
|
|
|
139
144
|
The Windows phase uses the explicit `aws-us-ec2-windows-jit` runner preset.
|
|
140
145
|
Its caller supplies one bounded label under
|
|
141
|
-
`aws-us-ec2-windows-jit-<qualification-id>`, and Buildchain
|
|
142
|
-
one Windows x64 native lane. The reusable trust gate still
|
|
143
|
-
GitHub-hosted runner before the JIT label can select EC2.
|
|
146
|
+
`aws-us-ec2-windows-jit-<campaign-id>-<qualification-id>`, and Buildchain
|
|
147
|
+
resolves exactly one Windows x64 native lane. The reusable trust gate still
|
|
148
|
+
runs on a GitHub-hosted runner before the JIT label can select EC2.
|
|
144
149
|
|
|
145
150
|
The provider creates repository-level GitHub JIT configuration for
|
|
146
151
|
`kungfu-systems/kungfu`. Its `labels` request must contain all four scheduling
|
|
147
152
|
labels: `self-hosted`, `Windows`, `X64`, and the card-scoped
|
|
148
|
-
`aws-us-ec2-windows-jit-<qualification-id>` label.
|
|
153
|
+
`aws-us-ec2-windows-jit-<campaign-id>-<qualification-id>` label. The workflow
|
|
154
|
+
display title also carries both identities, allowing the launch controller to
|
|
155
|
+
verify the queued run against its campaign plan. GitHub's JIT endpoint does
|
|
149
156
|
not infer the default OS and architecture labels when they are omitted. The
|
|
150
157
|
encoded configuration is never placed in EC2 user data, a tag, a command log,
|
|
151
158
|
or an artifact. The operator writes it to a card-scoped SSM SecureString under
|
|
@@ -168,21 +175,153 @@ Each runner uses:
|
|
|
168
175
|
security-group rule, no key pair, and no warm Auto Scaling capacity.
|
|
169
176
|
|
|
170
177
|
Runner diagnostics and a redacted lifecycle record are uploaded to the
|
|
171
|
-
provider's encrypted, private evidence bucket
|
|
172
|
-
|
|
173
|
-
|
|
178
|
+
provider's encrypted, private evidence bucket under the exact campaign, run,
|
|
179
|
+
attempt, and instance identity. The runner process exits after one job, Windows
|
|
180
|
+
shuts down, and EC2's instance-initiated shutdown behavior is set to
|
|
181
|
+
`terminate`. A five-minute reaper terminates card-owned stopped or
|
|
174
182
|
three-hour-old instances and deletes only their dedicated JIT parameter.
|
|
175
183
|
|
|
176
184
|
At the 2026-07-29 AWS Price List rate of USD 1.45 per Windows
|
|
177
|
-
`c7i.4xlarge` hour,
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
185
|
+
`c7i.4xlarge` hour, each accepted instance reserves its complete three-hour
|
|
186
|
+
USD 4.35 fail-closed lifetime before `RunInstances`. A DynamoDB transaction
|
|
187
|
+
binds the exact campaign and source, creates an idempotent run ledger entry,
|
|
188
|
+
and atomically refuses a sixth accepted instance. Five accepted instances
|
|
189
|
+
therefore reserve at most USD 21.75. The campaign also persists the
|
|
190
|
+
operator-observed spend from earlier Windows work, and refuses to arm unless
|
|
191
|
+
that baseline, all five reservations, and one USD 4.35 fail-closed race
|
|
192
|
+
allowance remain below the USD 110 phase cap.
|
|
193
|
+
|
|
194
|
+
The campaign starts unarmed and expires within 24 hours. Its `CONTROL` record
|
|
195
|
+
can be created only once: a killed or expired campaign cannot be re-armed by
|
|
196
|
+
the campaign tool. A budget notification or any instance lifetime violation
|
|
197
|
+
persists `KILLED` before cleanup, so later workflow dispatches fail before a
|
|
198
|
+
paid launch. Reservations are never refunded: a controller crash, ambiguous
|
|
199
|
+
launch, or successful launch all remain charged to the campaign, favoring a
|
|
200
|
+
false stop over an accidental budget overrun.
|
|
201
|
+
|
|
202
|
+
The 2026-08-03 timeout-only campaign decision narrows the campaign to two
|
|
203
|
+
accepted instances with one active instance at a time. The second reservation
|
|
204
|
+
is an operator-gated repair retry: it may be used only after the first attempt
|
|
205
|
+
is classified as non-counting and runner, EC2, EBS, SSM, and workflow residue
|
|
206
|
+
have returned to zero. The two-slot ledger is a maximum spend boundary, not an
|
|
207
|
+
authorization to consume both reservations.
|
|
208
|
+
|
|
209
|
+
Each stack owns a stack-scoped reaper log group, so an independent retained
|
|
210
|
+
one-shot campaign stack can be created without colliding with another
|
|
211
|
+
campaign's audit log resource.
|
|
212
|
+
|
|
213
|
+
The tag-filtered AWS Budget is defense in depth, not the authoritative launch
|
|
214
|
+
gate. It is owned by the singleton
|
|
215
|
+
`kungfu-buildchain-windows-jit-budget-guard` stack rather than any retained
|
|
216
|
+
campaign stack. This prevents Budget-name collisions and prevents a stale
|
|
217
|
+
campaign reaper from becoming the provider-wide cost authority. The Budget
|
|
218
|
+
filters exactly `user:kungfu:provider$windows-ec2-jit`; its 80% and 95% actual
|
|
219
|
+
notifications persist the provider kill sentinel, terminate every tagged
|
|
220
|
+
Windows JIT instance, and delete scoped JIT parameters. Every launch controller
|
|
221
|
+
refuses to proceed when the sentinel exists or when the Budget identity or tag
|
|
222
|
+
filter does not match.
|
|
223
|
+
|
|
224
|
+
Budget installation fails closed until the AWS Organizations management
|
|
225
|
+
account activates `kungfu:provider` and Cost Explorer returns
|
|
226
|
+
`windows-ec2-jit` for that key. A linked account cannot activate the tag. Do not
|
|
227
|
+
create an unfiltered fallback Budget or treat a tag-filtered zero as evidence.
|
|
228
|
+
The DynamoDB campaign reservation remains the atomic launch authority because
|
|
229
|
+
Cost Explorer and AWS Budgets can lag provider activity.
|
|
230
|
+
|
|
231
|
+
Qualification requires one runner-profile smoke and three trusted exact-source
|
|
232
|
+
full Windows jobs all bound to the same campaign, independent cancellation and
|
|
233
|
+
timeout cleanup exercises, and zero repository runner, EC2 instance,
|
|
234
|
+
disposable volume, min capacity, and desired capacity within 15 minutes of the
|
|
235
|
+
final job.
|
|
236
|
+
|
|
237
|
+
### Phase 2 operator workflow
|
|
238
|
+
|
|
239
|
+
`pnpm operator:windows-jit` is the reusable lifecycle entrypoint. Its default
|
|
240
|
+
mode is `plan`, which performs no AWS or GitHub call. A plan binds the account,
|
|
241
|
+
region, unique campaign and stack names, source SHA/ref, Cost Explorer window,
|
|
242
|
+
workflow id, network, OIDC provider, expiry, slot ceiling, singleton Budget
|
|
243
|
+
identity, and exact confirmation digest.
|
|
244
|
+
|
|
245
|
+
The modes are deliberately separated:
|
|
246
|
+
|
|
247
|
+
- `plan` emits the deterministic mutation boundary and digest.
|
|
248
|
+
- `audit` reads AWS and GitHub only. It verifies the account, disabled workflow,
|
|
249
|
+
singleton guard stack, exact Budget filter, SNS thresholds/subscribers,
|
|
250
|
+
provider kill sentinel, campaign stack, and zero EC2/EBS/SSM/JIT/runner
|
|
251
|
+
residue.
|
|
252
|
+
- `install-budget --execute` deploys or updates only the singleton Budget guard.
|
|
253
|
+
It refuses to mutate unless the provider tag value is visible, the Windows
|
|
254
|
+
workflow is disabled, and the account, campaign, source, Budget, and plan
|
|
255
|
+
digest confirmations match.
|
|
256
|
+
- `prepare --execute` requires the installed Budget guard, absent kill
|
|
257
|
+
sentinel, fresh Cost Explorer readback filtered by both
|
|
258
|
+
`kungfu:provider=windows-ec2-jit` and `BoxUsage:c7i.4xlarge`, zero residue, a
|
|
259
|
+
never-used campaign stack name, and the disabled workflow. The receipt binds
|
|
260
|
+
the query timestamp and exact filter identity. Preparation deploys the
|
|
261
|
+
campaign stack and atomically arms the ledger with that provider-spend
|
|
262
|
+
baseline. It never enables or dispatches the workflow and never creates EC2
|
|
263
|
+
capacity.
|
|
264
|
+
- `close --execute` disables the workflow first, persists `KILLED`, publishes
|
|
265
|
+
the campaign kill switch, and reports terminal success only after EC2, EBS,
|
|
266
|
+
SSM, JIT parameter, and GitHub runner residue is zero. It is safe to rerun
|
|
267
|
+
while the reaper settles.
|
|
268
|
+
|
|
269
|
+
All mutating modes require `--execute`, `--confirm-plan-digest`,
|
|
270
|
+
`--confirm-account-id`, `--confirm-campaign-id`, and
|
|
271
|
+
`--confirm-source-sha`. Budget installation and preparation additionally
|
|
272
|
+
require `--confirm-budget-name`. A future paid workload still requires a
|
|
273
|
+
separate exact workflow/run authorization and uses
|
|
274
|
+
`scripts/aws-windows-jit-controller.mjs`; preparation is not paid-launch
|
|
275
|
+
authority.
|
|
276
|
+
|
|
277
|
+
Start by recording one reproducible plan:
|
|
181
278
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
279
|
+
```bash
|
|
280
|
+
pnpm operator:windows-jit plan \
|
|
281
|
+
--aws-profile us \
|
|
282
|
+
--account-id 727884401362 \
|
|
283
|
+
--campaign-id win-REPLACE \
|
|
284
|
+
--source-sha REPLACE_WITH_EXACT_40_CHARACTER_SHA \
|
|
285
|
+
--source-ref refs/heads/dev/v4/v4.0 \
|
|
286
|
+
--observed-at REPLACE_WITH_ISO_TIMESTAMP \
|
|
287
|
+
--expires-at REPLACE_WITH_ISO_TIMESTAMP_WITHIN_24_HOURS \
|
|
288
|
+
--cost-start REPLACE_WITH_PHASE_START_DATE \
|
|
289
|
+
--cost-end REPLACE_WITH_EXCLUSIVE_END_DATE \
|
|
290
|
+
--max-accepted-instances 1 \
|
|
291
|
+
--workflow-id 322620360 \
|
|
292
|
+
--vpc-id REPLACE_WITH_VPC_ID \
|
|
293
|
+
--subnet-id REPLACE_WITH_SUBNET_ID \
|
|
294
|
+
--oidc-provider-arn REPLACE_WITH_GITHUB_OIDC_PROVIDER_ARN
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Reuse those exact arguments for `audit`, `install-budget`, `prepare`, or
|
|
298
|
+
`close`; never regenerate `--observed-at` between the plan and its confirmed
|
|
299
|
+
mutation. Capture stdout as the operator receipt. Do not put credentials,
|
|
300
|
+
tokens, JIT configuration, or signed URLs in arguments or receipts.
|
|
301
|
+
|
|
302
|
+
### Lower-level campaign and launch controllers
|
|
303
|
+
|
|
304
|
+
`scripts/aws-windows-jit-campaign-core.mjs` owns the pure one-shot ledger
|
|
305
|
+
contract used by the operator and launch controller. Arming creates `CONTROL`
|
|
306
|
+
and `CAMPAIGN#<id>` with `attribute_not_exists` conditions, so DynamoDB refuses
|
|
307
|
+
a second campaign in the same retained state table. There is deliberately no
|
|
308
|
+
clear or re-arm operation.
|
|
309
|
+
|
|
310
|
+
Every `scripts/aws-windows-jit-controller.mjs --execute` call must provide the
|
|
311
|
+
same `--account-id`, `--campaign-id`, `--confirm-campaign-id`, `--state-table`,
|
|
312
|
+
and `--confirm-state-table`. Before GitHub JIT material is created, the
|
|
313
|
+
controller verifies the exact provider Budget/tag filter and proves the global
|
|
314
|
+
Budget kill sentinel absent. After the GitHub, AMI, active-instance, SSM, and
|
|
315
|
+
EC2 DryRun checks pass, the controller
|
|
316
|
+
atomically reserves one run. Duplicate run-attempt-qualification identities,
|
|
317
|
+
source mismatch, expiry, `KILLED`, the sixth accepted instance, or a
|
|
318
|
+
reservation that would exceed the USD 110 ceiling after combining the persisted
|
|
319
|
+
fresh Cost Explorer baseline with all in-flight campaign reservations all fail
|
|
320
|
+
closed in one DynamoDB transaction before `RunInstances`. AWS Budget alarms are
|
|
321
|
+
defense in depth for delayed billing telemetry; the atomic ledger is the
|
|
322
|
+
authoritative launch-time guard. The operator is the only supported mutation
|
|
323
|
+
surface for campaign preparation and closeout; direct imports of the core are
|
|
324
|
+
not operator authority.
|
|
186
325
|
|
|
187
326
|
## Phase 3 contract
|
|
188
327
|
|
|
@@ -226,6 +365,32 @@ host, including at least one full run, plus proof that:
|
|
|
226
365
|
- AWS has no active campaign instance or allocated campaign host;
|
|
227
366
|
- actual incremental spend remained below USD 25.
|
|
228
367
|
|
|
368
|
+
### Phase 3 lifecycle controller
|
|
369
|
+
|
|
370
|
+
`scripts/aws-macos-jit-controller.mjs` is the operator boundary for the paid
|
|
371
|
+
campaign. It has three explicit mutation modes:
|
|
372
|
+
|
|
373
|
+
- `launch-campaign` binds the exact repository source, AMI, availability zone,
|
|
374
|
+
tagged Dedicated Host, and reusable instance. It rejects pre-existing Mac
|
|
375
|
+
capacity and requires successful `AllocateHosts` and `RunInstances` DryRuns
|
|
376
|
+
before either real call.
|
|
377
|
+
- `run-job` binds one queued exact-source GitHub job to the existing campaign
|
|
378
|
+
host and instance. It writes the repository JIT configuration through a
|
|
379
|
+
mode-0600 temporary file into a distinct SSM SecureString, sends only the
|
|
380
|
+
credential-free bootstrap through SSM, and removes the parameter plus runner
|
|
381
|
+
registration if command delivery fails.
|
|
382
|
+
- `close-campaign` refuses execution before the provider's 24-hour minimum,
|
|
383
|
+
verifies the encrypted delete-on-termination root volume, removes scoped JIT
|
|
384
|
+
residue, terminates the exact instance, and requires a `ReleaseHosts` DryRun
|
|
385
|
+
before release. If Apple host scrubbing is still in progress, it reports
|
|
386
|
+
`release-pending`; the ten-minute card-scoped reaper remains the bounded
|
|
387
|
+
retry path.
|
|
388
|
+
|
|
389
|
+
Every execute mode requires the exact source SHA and campaign id to be repeated
|
|
390
|
+
through `--confirm-source-sha` and `--confirm-campaign-id`. `run-job` also
|
|
391
|
+
requires `--confirm-run-id`. Omitting `--execute` emits a deterministic plan
|
|
392
|
+
without changing AWS or GitHub state.
|
|
393
|
+
|
|
229
394
|
## Provider lifecycle
|
|
230
395
|
|
|
231
396
|
The three infrastructure templates live under
|