@kungfu-tech/buildchain 4.1.3-alpha.3 → 4.1.3-alpha.5
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/architecture/agent-change-map.md +7 -0
- package/architecture/maintainability-debt.json +8 -1
- package/architecture/maintainability-policy.json +6 -6
- package/architecture/release-topology.json +2 -1
- package/dist/site/buildchain-contract.json +2 -2
- package/dist/site/buildchain-site.json +11 -6
- package/dist/site/kfd-claims.json +2 -2
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/page-registry.json +7 -2
- package/dist/site/public-surface-audit.json +6 -4
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +4 -4
- package/dist/site/workflow-registry.json +8 -6
- package/docs/runtime-entry.md +24 -3
- package/package.json +1 -1
- package/packages/core/consumer/contract/plan.js +5 -2
- package/packages/core/providers/github/discussions/materials.js +12 -4
- package/packages/core/providers/github/pipeline-policy.js +44 -17
- package/packages/core/providers/github/pipeline-source.js +24 -7
- package/packages/core/workflow/pipeline/build-result.js +8 -0
- package/packages/core/workflow/pipeline/channel-control.js +10 -1
- package/packages/core/workflow/pipeline/channel-source.js +53 -0
- package/packages/core/workflow/pipeline/group-control.js +2 -0
- package/packages/core/workflow/pipeline/host.js +24 -16
- package/packages/core/workflow/pipeline/selection.js +9 -4
|
@@ -137,6 +137,13 @@ Safe change route: Reduce one declared responsibility in its owning module, run
|
|
|
137
137
|
- `.github/workflows/.release-binary-assets.yml`
|
|
138
138
|
- `.github/workflows/public-ops-dev-auto-merge.yml`
|
|
139
139
|
- `tests/release-topology.test.mjs`
|
|
140
|
+
- `scripts/check-release-topology.mjs`
|
|
141
|
+
- `scripts/check-universal-workflow-bootstrap.mjs`
|
|
142
|
+
- `packages/core/providers/github/discussions/materials.js`
|
|
143
|
+
- `.github/workflows/self-build-alpha-dogfood.yml`
|
|
144
|
+
- `.github/workflows/self-build-binary-distribution.yml`
|
|
145
|
+
- `.github/workflows/self-ops-bootstrap-dogfood.yml`
|
|
146
|
+
- `packages/core/governance/buildchain-publication-authority.js`
|
|
140
147
|
|
|
141
148
|
## action-process-runtime
|
|
142
149
|
|
|
@@ -2247,7 +2247,14 @@
|
|
|
2247
2247
|
".github/workflows/self-release-promote.yml",
|
|
2248
2248
|
".github/workflows/.release-binary-assets.yml",
|
|
2249
2249
|
".github/workflows/public-ops-dev-auto-merge.yml",
|
|
2250
|
-
"tests/release-topology.test.mjs"
|
|
2250
|
+
"tests/release-topology.test.mjs",
|
|
2251
|
+
"scripts/check-release-topology.mjs",
|
|
2252
|
+
"scripts/check-universal-workflow-bootstrap.mjs",
|
|
2253
|
+
"packages/core/providers/github/discussions/materials.js",
|
|
2254
|
+
".github/workflows/self-build-alpha-dogfood.yml",
|
|
2255
|
+
".github/workflows/self-build-binary-distribution.yml",
|
|
2256
|
+
".github/workflows/self-ops-bootstrap-dogfood.yml",
|
|
2257
|
+
"packages/core/governance/buildchain-publication-authority.js"
|
|
2251
2258
|
],
|
|
2252
2259
|
"burnDownSlices": [
|
|
2253
2260
|
{
|
|
@@ -26,17 +26,17 @@
|
|
|
26
26
|
},
|
|
27
27
|
"repositoryBudgets": {
|
|
28
28
|
"baselineRevision": "9569f69c2cb609372b8a3d65ce5dec8fb7b34a84",
|
|
29
|
-
"maxHandMaintainedSourceFiles":
|
|
30
|
-
"maxHandMaintainedSourceLines":
|
|
29
|
+
"maxHandMaintainedSourceFiles": 1472,
|
|
30
|
+
"maxHandMaintainedSourceLines": 217919,
|
|
31
31
|
"maxWorkflowFiles": 73,
|
|
32
|
-
"maxWorkflowLines":
|
|
33
|
-
"latestTransition": "
|
|
34
|
-
"latestTransitionRationale": "Charge
|
|
32
|
+
"maxWorkflowLines": 10465,
|
|
33
|
+
"latestTransition": "Exact pipeline source observation and isolated delivery credential transport.",
|
|
34
|
+
"latestTransitionRationale": "Charge exactly 17 measured source lines and 8 workflow lines for stable source identity observation and canonical automation-secret forwarding across the internal delivery boundary. Existing self workflows remain until the corrected entry is published. Preserve all source/workflow file counts, per-file, function, complexity, debt and exception ceilings. This aggregate budget change remains proposed until independent protected review.",
|
|
35
35
|
"rationale": "Bounded modules separate candidate, evidence, native proof and execution, canonical failure verification, closed-set execution transfer, process-boundary verification, Warrant state and qualification, authority state, qualification, Landing acquisition, verified-attempt admission, Landing settlement and fence validation, provider attempt and heartbeat readback, sealed terminal evidence, hosted heartbeat, resume, store, options, command-specific adapters, and CLI orchestration responsibilities. The protected delivery workflow gives candidate and seal jobs no provider write credential, recursively rejects transfer drift, scopes every transfer artifact to the exact provider run attempt, chains every durable heartbeat state and receipt root on a distinct hosted runner domain, and permits qualification or exact failure settlement only after the finalizer verifies live jobs and the latest durable authority state. Public Landing admission and heartbeat always perform non-injectable fresh exact-attempt provider readback, tolerate only a not-yet-materialized seal job while retaining exact native and duplicate-job rejection, and heartbeat-loss coordination never invokes GitHub's run-scoped cancellation API where a successor rerun could race. The hosted process boundary anchors trust in the kernel-resolved versioned Runner.Worker path while accepting an equivalent argv-zero spelling with the same basename; its public boundary marker is allowed only at the one exact non-secret value, so a forged value under the same credential-like name still fails closed. The credentialless transfer seal validates the rooted native reuse decision against the Warrant-bound source, closure, dependency, toolchain, environment and command inputs; qualifiedBase stays in the proof and decision where it is rooted and later independently rechecked, rather than being assumed on the Warrant schema. V2 mutation cannot initialize a second empty authority beside a legacy ref: migration reads and roots the canonical live v1 ref, rechecks it, applies the explicit configured v2 policy, and atomically replaces its bytes through one expected-old non-force update, so old v1 controllers fail closed while the prior commit remains immutable history. Candidate ancestry classifies the GitHub artifact runtime token as credential authority. Every Landing settlement, including an unexpired fence, requires product-owned terminal readback. Terminal cleanup reads the immutable historical attempt, derives workflow and hosted Landing job identity from live run data, reads the exact protected ref head and compares containment against that immutable SHA, and seals merged only when the admitted merge-group head is contained by that protected base; a later different-head merge settles the old attempt as dequeued. Terminal normalization preserves transfer, finalizer boundary, native and seal job, admitted provider attempt, protected-base head, containment result, and terminal readback coordinates. The public reusable workflow truthfully retains its single-flight v1 authority without advertising v2 migration, while bounded v2 remains a separate opt-in CLI, Node API, and schema contract; the tracked self-caller stays on public v4-alpha with matching stable and alpha locks, and transient train selection is dispatch-only. Next-development parity adds one versioned transition authority, one durable controller, one bounded reservation adapter, and pure public-contract recovery evidence while retaining the existing thin floating-channel callers byte-for-byte. The floating-consumer gate reuses the existing contract-world evaluator so SHA drift passes only under the selected lock's compatibility policy, breaking surface drift still fails closed, and external certification reconstructs the receipt from the observed workflow SHA rather than the lock's historical evidence SHA. Tail reseal adds no Stage Capsule effect or general rebuild authority: it verifies the exact retained four-platform bytes, admits one known macOS tail failure through live provider readback, fences signing and finalization to explicit credentials and Warrant identity, and requires standard candidate Passport plus provider and protected readback. Compatibility Facts parity isolates canonical encoding, temporal verification, lifecycle validation, fixture projection, public authority projection, and CLI adaptation into bounded modules; legacy digest and proof arrays are derived only from exact current Fact lineage. Publication Rehearsal adds no production release authority: the content-addressed capsule contract binds source, candidate, manifest, config, canonical data-only provider bindings, provider policy, observations and core version separately from filesystem, runtime and rehearsal-only provider authority; simulate, replay and explicitly authorized provider rehearsal all reuse the release-tail planner, while same-commit local dogfood resolves the new reusable contract and exact current runtime before external callers remain on floating v4-alpha. Cross-runtime candidate recovery preserves original runtime and provider roots and creates resume lineage only after exact public ref, tag, ancestry, npm version and integrity readback. Adopter Delivery restores the reviewed public v3 gate, drivers, Passport binding, N-1 bootstrap and exact archive loader through one public v4 surface while keeping provider and release authority explicit non-claims. Floating Alpha bootstrap uses only the existing exact resolver and protected Alpha private shell to move an otherwise stale floating shell, retains public v4 stable promotion, and removes itself after protected readback. CI lane change-budget enforcement adds a bounded parser, evaluator, guard, and tests without creating another merge authority. Minimal consumer contract adds exactly seven bounded contract modules, one generated-contract gate and six product build/test example sources; the source-file ceiling increases by fourteen for this reviewed feature slice. Existing per-file, function, complexity and debt limits are unchanged. The final readable template sources require exact source-line and total-automation ceilings of 203394 and 224451 respectively; this charges all generated example sources rather than hiding them from measurement.",
|
|
36
36
|
"governance": "legacy-debt-sunset-2026q4",
|
|
37
37
|
"maxActionDefinitions": 283,
|
|
38
38
|
"maxActionDefinitionLines": 12399,
|
|
39
|
-
"maxAutomationImplementationLines":
|
|
39
|
+
"maxAutomationImplementationLines": 239925
|
|
40
40
|
},
|
|
41
41
|
"sourceBudgets": {
|
|
42
42
|
"newFileLines": 600,
|
|
@@ -386,6 +386,7 @@
|
|
|
386
386
|
"packages/core/workflow/pipeline/build-qualification.js",
|
|
387
387
|
"packages/core/workflow/pipeline/build.js",
|
|
388
388
|
"packages/core/workflow/pipeline/channel-control.js",
|
|
389
|
+
"packages/core/workflow/pipeline/channel-source.js",
|
|
389
390
|
"packages/core/workflow/pipeline/delivery-observation.js",
|
|
390
391
|
"packages/core/workflow/pipeline/events.js",
|
|
391
392
|
"packages/core/workflow/pipeline/fence.js",
|
|
@@ -410,7 +411,7 @@
|
|
|
410
411
|
"packages/core/workflow/pipeline/wake.js",
|
|
411
412
|
"packages/core/workflow/pipeline/web-status.js"
|
|
412
413
|
],
|
|
413
|
-
"root": "sha256:
|
|
414
|
+
"root": "sha256:b474be097d7b1455785cf78247c966601a2adfb03ff1baee9cc009f26b9c2ac1"
|
|
414
415
|
},
|
|
415
416
|
"rustWasmAuthority": {
|
|
416
417
|
"loader": "packages/core/runtime/domain-wasm.js",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"product": {
|
|
5
5
|
"name": "Buildchain",
|
|
6
6
|
"package": "@kungfu-tech/buildchain",
|
|
7
|
-
"version": "4.1.3-alpha.
|
|
7
|
+
"version": "4.1.3-alpha.5",
|
|
8
8
|
"repository": "https://github.com/kungfu-systems/buildchain"
|
|
9
9
|
},
|
|
10
10
|
"majorLine": "v4",
|
|
@@ -2410,5 +2410,5 @@
|
|
|
2410
2410
|
"compatibilityFactCutRoot": "sha256:58f33e498596505a26b6fc3c7ae5acef847ff699eee6c7e17a7b318a40bdf0d6",
|
|
2411
2411
|
"compatibilityProofRegistryRoot": "sha256:2f6477405c7891b754b33ad6515d55618bd320e7cdc59330d7cc645e17201e72",
|
|
2412
2412
|
"compatibilityDigest": "sha256:14368a3f99f38a8c9c1e053f7ec3651766e3535237f4c551cc75417cf7ef97b3",
|
|
2413
|
-
"contractDigest": "sha256:
|
|
2413
|
+
"contractDigest": "sha256:20d66ca1efc0cf0fc4d9b7636a11452646f9b67030561e33e6701e6c71ff6392"
|
|
2414
2414
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-site-bundle",
|
|
4
|
-
"generatedAt": "2026-09-
|
|
5
|
-
"publishedAt": "2026-09-
|
|
4
|
+
"generatedAt": "2026-09-13T17:39:11.000Z",
|
|
5
|
+
"publishedAt": "2026-09-13T17:39:11.000Z",
|
|
6
6
|
"reproducible": true,
|
|
7
7
|
"timestampPolicy": "ci-injected",
|
|
8
8
|
"deterministicInputs": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"declared Buildchain surface manifest contract"
|
|
20
20
|
],
|
|
21
21
|
"sourceDateEpoch": "0",
|
|
22
|
-
"sourceRevision": "
|
|
22
|
+
"sourceRevision": "5daa16d74fa52d44ae44f31d18860614d5563517",
|
|
23
23
|
"timestampPolicyDetails": {
|
|
24
24
|
"contract": "kungfu-buildchain-surface-timestamp-policy",
|
|
25
25
|
"timestampFields": [
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"package": {
|
|
39
39
|
"name": "@kungfu-tech/buildchain",
|
|
40
|
-
"version": "4.1.3-alpha.
|
|
40
|
+
"version": "4.1.3-alpha.5",
|
|
41
41
|
"versionSource": "package.json#version"
|
|
42
42
|
},
|
|
43
43
|
"source": {
|
|
@@ -4663,13 +4663,18 @@
|
|
|
4663
4663
|
],
|
|
4664
4664
|
"maturity": "stable",
|
|
4665
4665
|
"sourcePath": "docs/runtime-entry.md",
|
|
4666
|
-
"digest": "sha256:
|
|
4666
|
+
"digest": "sha256:def81825eac925b6e1ecddd36fd5f6724076f229fafb2bbf9e738dba7a8d49ec",
|
|
4667
4667
|
"headings": [
|
|
4668
4668
|
{
|
|
4669
4669
|
"level": 1,
|
|
4670
4670
|
"title": "Runtime entry contract",
|
|
4671
4671
|
"anchor": "runtime-entry-contract"
|
|
4672
4672
|
},
|
|
4673
|
+
{
|
|
4674
|
+
"level": 2,
|
|
4675
|
+
"title": "Minimal pipeline provider credentials",
|
|
4676
|
+
"anchor": "minimal-pipeline-provider-credentials"
|
|
4677
|
+
},
|
|
4673
4678
|
{
|
|
4674
4679
|
"level": 2,
|
|
4675
4680
|
"title": "Minimal pipeline recovery",
|
|
@@ -4681,7 +4686,7 @@
|
|
|
4681
4686
|
"anchor": "advanced-build-component-recovery"
|
|
4682
4687
|
}
|
|
4683
4688
|
],
|
|
4684
|
-
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: unified-runtime-entry\ndoc_type: implementation-contract\nsource_level: user-consensus\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-09-13\nai_provenance:\n model_family: GPT-6\n product: Codex\n generated_at: 2026-09-13\n visible_context: Source-bound attempt recovery implementation, published entry contract and local failure-path tests.\n invisible_context_boundary: This contract does not claim implementation or hosted qualification is complete.\n---\n\n# Runtime entry contract\n\nConsumers persist a public workflow reference at `@v4` or `@v4-alpha`.\nGitHub resolves that entry to a commit. The entry selects execution runtime X\nfrom an explicit transient parameter, the selected contract lock, or the entry\ncommit default, in that order. The entry commit and runtime commit may differ.\n\n`actions/runtime/environment/prepare` is the sole runtime preparation owner.\nSelection is resolved once per execution. Each executing job prepares that\nselected runtime through the same implementation. Business workflows and\nactions cannot acquire, replace, reselect or install their own Buildchain\nruntime. All business composites, JavaScript modules, WASM and resources come\nfrom X. Runtime identity is retained as provenance; subsequent business nodes\ndo not compare Buildchain SHAs or require equality with the workflow commit.\n\nA runtime failure can start a recovery execution through the same public\nentry with a transient repaired train branch or tag. The new execution selects\nruntime Y and retains the original task, source and evidence. Valid completed\nresults can be reused; provider effects require readback before further writes.\nSwitching runtimes does not automatically qualify all previous results for reuse.\nNeither the persisted caller nor its contract lock needs a train rewrite.\n\nAn entry failure is repaired by publishing and adopting a corrected entry and\nstarting a new provider run through the corrected floating entry. The caller files\nremain unchanged. A usable recovery entry can still recover the exact existing\nattempt; an entry failure before admission has no attempt to recover.\nBuildchain self-dogfood uses exactly the same consumer contract and has no\nrepository-specific execution or recovery route.\n\nSource checkouts are separate business inputs. Building Buildchain itself may\ncheck out its source, but that source cannot implicitly replace the selected\nexecution runtime. Source, artifact and publication-effect checks retain their\nbusiness meaning; they do not reintroduce downstream Buildchain SHA checks.\n\nAcceptance requires a complete workflow/action acquisition inventory, enforced\nsingle preparation ownership, different entry/runtime execution, train recovery,\nplatform and multi-job qualification, and validation of the published consumer\nentry. A source test or a successful package import alone is insufficient.\n\n## Minimal pipeline recovery\n\nThe minimal contract has one normal event caller and one manual recovery caller,\nplus `.buildchain/buildchain.toml`. Both callers are maintained by Buildchain's\nconsumer setup; product differences do not require additional recovery workflows.\nThe repository implementation alone does not prove the entry has been published\nor qualified in a clean consumer.\n\nThe workflow summary identifies the current attempt, its source PR, completed\nsteps and remaining work. Follow **Recover this attempt**, choose **Run workflow**,\nand paste the exact attempt. Leave `runtime-ref` empty for an ordinary retry;\nsupply a repaired runtime only when needed. The public recovery entry accepts no\nother recovery selectors. It derives configuration, producer runs, artifacts and\ntransaction coordinates from the canonical attempt history.\n\nRecovery opens a new attempt with an explicit predecessor. Successful platform\njobs and their actual retained artifacts are independently requalified; only\nmissing platforms or explicitly incompatible stage implementations are rebuilt.\nA signing failure can requalify the original sealed bytes under the repaired\npublisher. Partial publication preserves its original signed transaction and\ncompleted effects, reads providers again, and authorizes only remaining effects.\nMissing, expired or conflicting evidence stops with a diagnosis; it does not\nsilently trigger a complete rebuild or replace published bytes.\n\nA repeated request for the same predecessor and repair selects the same successor.\nIf that recovery was interrupted, select the successor shown in the summary for\nthe next recovery. An active predecessor must first finish or be cancelled using\nits ordinary GitHub execution link. A changed or superseded source cannot reuse\nan old attempt as authority for the current PR. Completed publication remains\nrecorded even when distribution or the next development version still needs work.\nCancellation stops remaining work and cannot undo published results.\n\nOnce admitted, ordinary wake events continue with the recovered attempt's exact\nruntime, even when the consumer lock still names the original runtime. A further\nruntime change requires another explicit recovery. An entry repair is distributed\nthrough the existing `@v4` or `@v4-alpha` entry; consumers do not maintain backup\nscripts, patch a job definition, or add a different recovery workflow family.\n\n## Advanced build component recovery\n\n```yaml\non:\n push:\n workflow_dispatch:\n inputs:\n runtime-ref:\n description: Optional repaired train for this execution\n default: \"\"\n type: string\n resume-run-id:\n description: Original failed build run to recover\n default: \"\"\n type: string\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v4\n with:\n runtime-ref: ${{ inputs.runtime-ref || '' }}\n resume-run-id: ${{ inputs.resume-run-id || '' }}\n```\n\nOrdinary executions use `.buildchain/contract-lock.json`; the alpha entry defaults\nto `.buildchain/alpha-contract-lock.json`. `contract-lock` selects another relative\nlock path. A missing default lock falls back to the entry commit; an invalid lock\nor an unreadable source fails preparation. A supplied runtime parameter overrides\nthe lock and requires caller repository write authority. For `workflow_dispatch`,\nGitHub enforces repository Actions write permission before creating the run,\nincluding calls using installation tokens. The entry uses that authorization;\nan installation bot does not need to be a human repository collaborator.\nOther event types retain the entry's write, maintain or admin collaborator check.\nSee GitHub's [workflow dispatch authorization](https://docs.github.com/en/rest/actions/workflows#create-a-workflow-dispatch-event).\nBranches and tags are resolved to an immutable commit during selection.\n\nFor a Buildchain runtime fault, dispatch the same consumer workflow with\n`runtime-ref: train/v4/v4.1/<repair>` and the original `resume-run-id`. The entry\nretains the original source commit and rejects unrelated workflows or fork runs.\nInstall hydrates the new workspace; completed build outputs are restored only\nwhen source, configuration, platform, tools, artifact producer and all retained\nbytes qualify. The remaining verification runs with the repaired runtime.\nExisting provider effects use their transaction evidence and live readbacks.\nA failed-job rerun cannot supply new inputs; recovery therefore starts a new run.\n\n`runtime-selection` is an internal reusable-workflow transport for an already\nselected runtime. Components forward it unchanged instead of resolving another\nreference. Consumers normally supply `runtime-ref` or a lock, not this transport.\n\nNested components preserve the selected runtime and contract metadata without\nre-reading the lock or comparing the runtime SHA. The internal transport carries\na trusted entry output; consumer source binding and override authorization remain\nentry concerns. Recovery selectors request `actions: read` to read the original\nrun in private repositories as well as public repositories.\n\nBusiness adapters also keep the runtime installation directory separate from the\nconsumer workspace. Queue reconciliation, npm preview, runner qualification and\nbinary packaging read consumer source from the workspace while executing selected\nruntime code. Directory equality is not an admission rule; source SHA and artifact\ncontainment checks still apply. The architecture gate parses business JavaScript\nand rejects direct or aliased runtime/source directory equality comparisons.\n\nPublication authority adapters take runtime repository and revision provenance\nfrom the prepared entry selection. Consumer requests provide source, artifact\nand effect authority; they do not supply or readmit a Buildchain SHA. Governance\nand sealed publication evidence retain the selected runtime as provenance while\nvalidating their own source, policy and provider bindings."
|
|
4689
|
+
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: unified-runtime-entry\ndoc_type: implementation-contract\nsource_level: user-consensus\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-09-14\nai_provenance:\n model_family: GPT-6\n product: Codex\n generated_at: 2026-09-14\n visible_context: Source-bound recovery, nested delivery credential transport, published entry contract and local failure-path tests.\n invisible_context_boundary: This contract does not claim implementation or hosted qualification is complete.\n---\n\n# Runtime entry contract\n\nConsumers persist a public workflow reference at `@v4` or `@v4-alpha`.\nGitHub resolves that entry to a commit. The entry selects execution runtime X\nfrom an explicit transient parameter, the selected contract lock, or the entry\ncommit default, in that order. The entry commit and runtime commit may differ.\n\n`actions/runtime/environment/prepare` is the sole runtime preparation owner.\nSelection is resolved once per execution. Each executing job prepares that\nselected runtime through the same implementation. Business workflows and\nactions cannot acquire, replace, reselect or install their own Buildchain\nruntime. All business composites, JavaScript modules, WASM and resources come\nfrom X. Runtime identity is retained as provenance; subsequent business nodes\ndo not compare Buildchain SHAs or require equality with the workflow commit.\n\nA runtime failure can start a recovery execution through the same public\nentry with a transient repaired train branch or tag. The new execution selects\nruntime Y and retains the original task, source and evidence. Valid completed\nresults can be reused; provider effects require readback before further writes.\nSwitching runtimes does not automatically qualify all previous results for reuse.\nNeither the persisted caller nor its contract lock needs a train rewrite.\n\nAn entry failure is repaired by publishing and adopting a corrected entry and\nstarting a new provider run through the corrected floating entry. The caller files\nremain unchanged. A usable recovery entry can still recover the exact existing\nattempt; an entry failure before admission has no attempt to recover.\nBuildchain self-dogfood uses exactly the same consumer contract and has no\nrepository-specific execution or recovery route.\n\nSource checkouts are separate business inputs. Building Buildchain itself may\ncheck out its source, but that source cannot implicitly replace the selected\nexecution runtime. Source, artifact and publication-effect checks retain their\nbusiness meaning; they do not reintroduce downstream Buildchain SHA checks.\n\nAcceptance requires a complete workflow/action acquisition inventory, enforced\nsingle preparation ownership, different entry/runtime execution, train recovery,\nplatform and multi-job qualification, and validation of the published consumer\nentry. A source test or a successful package import alone is insufficient.\n\n## Minimal pipeline provider credentials\n\nConfigure `BUILDCHAIN_AUTOMATION_TOKEN` once as a repository Actions secret when\nprotected delivery requires permissions unavailable to `GITHUB_TOKEN`. Both\ngenerated callers already inherit secrets. No token value, additional input or\nprovider orchestration belongs in the consumer TOML or workflow source.\n\nScope this credential to the consumer repository. Delivery needs Administration\nread access to inspect classic branch locks, Checks read, and Actions, Contents,\nPull requests and Commit statuses write access for its existing provider steps.\nIt does not need permission to change branch protection or bypass review. A\nmissing credential falls back to `GITHUB_TOKEN`; unreadable protection still\nfails closed before candidate reservation instead of assuming an unlocked branch.\n\nThe internal delivery edge forwards only this named secret to the credentialed\nsource, reservation, heartbeat and landing steps. Product builds, native\nexecution and native evidence sealing retain their separate read-only jobs and\nreceive no automation credential. Publication settlement uses the same canonical\nsecret as its existing fallback credential. Repairing a missing workflow secret\nedge requires a corrected published entry and a new provider run.\n\n## Minimal pipeline recovery\n\nThe minimal contract has one normal event caller and one manual recovery caller,\nplus `.buildchain/buildchain.toml`. Both callers are maintained by Buildchain's\nconsumer setup; product differences do not require additional recovery workflows.\nThe repository implementation alone does not prove the entry has been published\nor qualified in a clean consumer.\n\nThe workflow summary identifies the current attempt, its source PR, completed\nsteps and remaining work. Follow **Recover this attempt**, choose **Run workflow**,\nand paste the exact attempt. Leave `runtime-ref` empty for an ordinary retry;\nsupply a repaired runtime only when needed. The public recovery entry accepts no\nother recovery selectors. It derives configuration, producer runs, artifacts and\ntransaction coordinates from the canonical attempt history.\n\nRecovery opens a new attempt with an explicit predecessor. Successful platform\njobs and their actual retained artifacts are independently requalified; only\nmissing platforms or explicitly incompatible stage implementations are rebuilt.\nA signing failure can requalify the original sealed bytes under the repaired\npublisher. Partial publication preserves its original signed transaction and\ncompleted effects, reads providers again, and authorizes only remaining effects.\nMissing, expired or conflicting evidence stops with a diagnosis; it does not\nsilently trigger a complete rebuild or replace published bytes.\n\nA repeated request for the same predecessor and repair selects the same successor.\nIf that recovery was interrupted, select the successor shown in the summary for\nthe next recovery. An active predecessor must first finish or be cancelled using\nits ordinary GitHub execution link. A changed or superseded source cannot reuse\nan old attempt as authority for the current PR. Completed publication remains\nrecorded even when distribution or the next development version still needs work.\nCancellation stops remaining work and cannot undo published results.\n\nOnce admitted, ordinary wake events continue with the recovered attempt's exact\nruntime, even when the consumer lock still names the original runtime. A further\nruntime change requires another explicit recovery. An entry repair is distributed\nthrough the existing `@v4` or `@v4-alpha` entry; consumers do not maintain backup\nscripts, patch a job definition, or add a different recovery workflow family.\n\n## Advanced build component recovery\n\n```yaml\non:\n push:\n workflow_dispatch:\n inputs:\n runtime-ref:\n description: Optional repaired train for this execution\n default: \"\"\n type: string\n resume-run-id:\n description: Original failed build run to recover\n default: \"\"\n type: string\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v4\n with:\n runtime-ref: ${{ inputs.runtime-ref || '' }}\n resume-run-id: ${{ inputs.resume-run-id || '' }}\n```\n\nOrdinary executions use `.buildchain/contract-lock.json`; the alpha entry defaults\nto `.buildchain/alpha-contract-lock.json`. `contract-lock` selects another relative\nlock path. A missing default lock falls back to the entry commit; an invalid lock\nor an unreadable source fails preparation. A supplied runtime parameter overrides\nthe lock and requires caller repository write authority. For `workflow_dispatch`,\nGitHub enforces repository Actions write permission before creating the run,\nincluding calls using installation tokens. The entry uses that authorization;\nan installation bot does not need to be a human repository collaborator.\nOther event types retain the entry's write, maintain or admin collaborator check.\nSee GitHub's [workflow dispatch authorization](https://docs.github.com/en/rest/actions/workflows#create-a-workflow-dispatch-event).\nBranches and tags are resolved to an immutable commit during selection.\n\nFor a Buildchain runtime fault, dispatch the same consumer workflow with\n`runtime-ref: train/v4/v4.1/<repair>` and the original `resume-run-id`. The entry\nretains the original source commit and rejects unrelated workflows or fork runs.\nInstall hydrates the new workspace; completed build outputs are restored only\nwhen source, configuration, platform, tools, artifact producer and all retained\nbytes qualify. The remaining verification runs with the repaired runtime.\nExisting provider effects use their transaction evidence and live readbacks.\nA failed-job rerun cannot supply new inputs; recovery therefore starts a new run.\n\n`runtime-selection` is an internal reusable-workflow transport for an already\nselected runtime. Components forward it unchanged instead of resolving another\nreference. Consumers normally supply `runtime-ref` or a lock, not this transport.\n\nNested components preserve the selected runtime and contract metadata without\nre-reading the lock or comparing the runtime SHA. The internal transport carries\na trusted entry output; consumer source binding and override authorization remain\nentry concerns. Recovery selectors request `actions: read` to read the original\nrun in private repositories as well as public repositories.\n\nBusiness adapters also keep the runtime installation directory separate from the\nconsumer workspace. Queue reconciliation, npm preview, runner qualification and\nbinary packaging read consumer source from the workspace while executing selected\nruntime code. Directory equality is not an admission rule; source SHA and artifact\ncontainment checks still apply. The architecture gate parses business JavaScript\nand rejects direct or aliased runtime/source directory equality comparisons.\n\nPublication authority adapters take runtime repository and revision provenance\nfrom the prepared entry selection. Consumer requests provide source, artifact\nand effect authority; they do not supply or readmit a Buildchain SHA. Governance\nand sealed publication evidence retain the selected runtime as provenance while\nvalidating their own source, policy and provider bindings."
|
|
4685
4690
|
},
|
|
4686
4691
|
{
|
|
4687
4692
|
"id": "manual:runtime-train-validation",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"contract": "kungfu-buildchain-public-surface-reverse-audit",
|
|
22
22
|
"path": "dist/site/public-surface-audit.json",
|
|
23
23
|
"status": "passed",
|
|
24
|
-
"sha256": "
|
|
24
|
+
"sha256": "842f68668013209a8101ddee753c1aa614565497429f8ffde499c3c98ea61fd8",
|
|
25
25
|
"summary": {
|
|
26
26
|
"cliCommandCount": 117,
|
|
27
27
|
"workflowCount": 73,
|
|
@@ -246,7 +246,7 @@
|
|
|
246
246
|
"contract": "kungfu-buildchain-public-surface-reverse-audit",
|
|
247
247
|
"path": "dist/site/public-surface-audit.json",
|
|
248
248
|
"status": "passed",
|
|
249
|
-
"sha256": "
|
|
249
|
+
"sha256": "842f68668013209a8101ddee753c1aa614565497429f8ffde499c3c98ea61fd8",
|
|
250
250
|
"summary": {
|
|
251
251
|
"cliCommandCount": 117,
|
|
252
252
|
"workflowCount": 73,
|
|
@@ -4597,13 +4597,18 @@
|
|
|
4597
4597
|
],
|
|
4598
4598
|
"maturity": "stable",
|
|
4599
4599
|
"sourcePath": "docs/runtime-entry.md",
|
|
4600
|
-
"digest": "sha256:
|
|
4600
|
+
"digest": "sha256:def81825eac925b6e1ecddd36fd5f6724076f229fafb2bbf9e738dba7a8d49ec",
|
|
4601
4601
|
"headings": [
|
|
4602
4602
|
{
|
|
4603
4603
|
"level": 1,
|
|
4604
4604
|
"title": "Runtime entry contract",
|
|
4605
4605
|
"anchor": "runtime-entry-contract"
|
|
4606
4606
|
},
|
|
4607
|
+
{
|
|
4608
|
+
"level": 2,
|
|
4609
|
+
"title": "Minimal pipeline provider credentials",
|
|
4610
|
+
"anchor": "minimal-pipeline-provider-credentials"
|
|
4611
|
+
},
|
|
4607
4612
|
{
|
|
4608
4613
|
"level": 2,
|
|
4609
4614
|
"title": "Minimal pipeline recovery",
|
|
@@ -4615,7 +4620,7 @@
|
|
|
4615
4620
|
"anchor": "advanced-build-component-recovery"
|
|
4616
4621
|
}
|
|
4617
4622
|
],
|
|
4618
|
-
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: unified-runtime-entry\ndoc_type: implementation-contract\nsource_level: user-consensus\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-09-13\nai_provenance:\n model_family: GPT-6\n product: Codex\n generated_at: 2026-09-13\n visible_context: Source-bound attempt recovery implementation, published entry contract and local failure-path tests.\n invisible_context_boundary: This contract does not claim implementation or hosted qualification is complete.\n---\n\n# Runtime entry contract\n\nConsumers persist a public workflow reference at `@v4` or `@v4-alpha`.\nGitHub resolves that entry to a commit. The entry selects execution runtime X\nfrom an explicit transient parameter, the selected contract lock, or the entry\ncommit default, in that order. The entry commit and runtime commit may differ.\n\n`actions/runtime/environment/prepare` is the sole runtime preparation owner.\nSelection is resolved once per execution. Each executing job prepares that\nselected runtime through the same implementation. Business workflows and\nactions cannot acquire, replace, reselect or install their own Buildchain\nruntime. All business composites, JavaScript modules, WASM and resources come\nfrom X. Runtime identity is retained as provenance; subsequent business nodes\ndo not compare Buildchain SHAs or require equality with the workflow commit.\n\nA runtime failure can start a recovery execution through the same public\nentry with a transient repaired train branch or tag. The new execution selects\nruntime Y and retains the original task, source and evidence. Valid completed\nresults can be reused; provider effects require readback before further writes.\nSwitching runtimes does not automatically qualify all previous results for reuse.\nNeither the persisted caller nor its contract lock needs a train rewrite.\n\nAn entry failure is repaired by publishing and adopting a corrected entry and\nstarting a new provider run through the corrected floating entry. The caller files\nremain unchanged. A usable recovery entry can still recover the exact existing\nattempt; an entry failure before admission has no attempt to recover.\nBuildchain self-dogfood uses exactly the same consumer contract and has no\nrepository-specific execution or recovery route.\n\nSource checkouts are separate business inputs. Building Buildchain itself may\ncheck out its source, but that source cannot implicitly replace the selected\nexecution runtime. Source, artifact and publication-effect checks retain their\nbusiness meaning; they do not reintroduce downstream Buildchain SHA checks.\n\nAcceptance requires a complete workflow/action acquisition inventory, enforced\nsingle preparation ownership, different entry/runtime execution, train recovery,\nplatform and multi-job qualification, and validation of the published consumer\nentry. A source test or a successful package import alone is insufficient.\n\n## Minimal pipeline recovery\n\nThe minimal contract has one normal event caller and one manual recovery caller,\nplus `.buildchain/buildchain.toml`. Both callers are maintained by Buildchain's\nconsumer setup; product differences do not require additional recovery workflows.\nThe repository implementation alone does not prove the entry has been published\nor qualified in a clean consumer.\n\nThe workflow summary identifies the current attempt, its source PR, completed\nsteps and remaining work. Follow **Recover this attempt**, choose **Run workflow**,\nand paste the exact attempt. Leave `runtime-ref` empty for an ordinary retry;\nsupply a repaired runtime only when needed. The public recovery entry accepts no\nother recovery selectors. It derives configuration, producer runs, artifacts and\ntransaction coordinates from the canonical attempt history.\n\nRecovery opens a new attempt with an explicit predecessor. Successful platform\njobs and their actual retained artifacts are independently requalified; only\nmissing platforms or explicitly incompatible stage implementations are rebuilt.\nA signing failure can requalify the original sealed bytes under the repaired\npublisher. Partial publication preserves its original signed transaction and\ncompleted effects, reads providers again, and authorizes only remaining effects.\nMissing, expired or conflicting evidence stops with a diagnosis; it does not\nsilently trigger a complete rebuild or replace published bytes.\n\nA repeated request for the same predecessor and repair selects the same successor.\nIf that recovery was interrupted, select the successor shown in the summary for\nthe next recovery. An active predecessor must first finish or be cancelled using\nits ordinary GitHub execution link. A changed or superseded source cannot reuse\nan old attempt as authority for the current PR. Completed publication remains\nrecorded even when distribution or the next development version still needs work.\nCancellation stops remaining work and cannot undo published results.\n\nOnce admitted, ordinary wake events continue with the recovered attempt's exact\nruntime, even when the consumer lock still names the original runtime. A further\nruntime change requires another explicit recovery. An entry repair is distributed\nthrough the existing `@v4` or `@v4-alpha` entry; consumers do not maintain backup\nscripts, patch a job definition, or add a different recovery workflow family.\n\n## Advanced build component recovery\n\n```yaml\non:\n push:\n workflow_dispatch:\n inputs:\n runtime-ref:\n description: Optional repaired train for this execution\n default: \"\"\n type: string\n resume-run-id:\n description: Original failed build run to recover\n default: \"\"\n type: string\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v4\n with:\n runtime-ref: ${{ inputs.runtime-ref || '' }}\n resume-run-id: ${{ inputs.resume-run-id || '' }}\n```\n\nOrdinary executions use `.buildchain/contract-lock.json`; the alpha entry defaults\nto `.buildchain/alpha-contract-lock.json`. `contract-lock` selects another relative\nlock path. A missing default lock falls back to the entry commit; an invalid lock\nor an unreadable source fails preparation. A supplied runtime parameter overrides\nthe lock and requires caller repository write authority. For `workflow_dispatch`,\nGitHub enforces repository Actions write permission before creating the run,\nincluding calls using installation tokens. The entry uses that authorization;\nan installation bot does not need to be a human repository collaborator.\nOther event types retain the entry's write, maintain or admin collaborator check.\nSee GitHub's [workflow dispatch authorization](https://docs.github.com/en/rest/actions/workflows#create-a-workflow-dispatch-event).\nBranches and tags are resolved to an immutable commit during selection.\n\nFor a Buildchain runtime fault, dispatch the same consumer workflow with\n`runtime-ref: train/v4/v4.1/<repair>` and the original `resume-run-id`. The entry\nretains the original source commit and rejects unrelated workflows or fork runs.\nInstall hydrates the new workspace; completed build outputs are restored only\nwhen source, configuration, platform, tools, artifact producer and all retained\nbytes qualify. The remaining verification runs with the repaired runtime.\nExisting provider effects use their transaction evidence and live readbacks.\nA failed-job rerun cannot supply new inputs; recovery therefore starts a new run.\n\n`runtime-selection` is an internal reusable-workflow transport for an already\nselected runtime. Components forward it unchanged instead of resolving another\nreference. Consumers normally supply `runtime-ref` or a lock, not this transport.\n\nNested components preserve the selected runtime and contract metadata without\nre-reading the lock or comparing the runtime SHA. The internal transport carries\na trusted entry output; consumer source binding and override authorization remain\nentry concerns. Recovery selectors request `actions: read` to read the original\nrun in private repositories as well as public repositories.\n\nBusiness adapters also keep the runtime installation directory separate from the\nconsumer workspace. Queue reconciliation, npm preview, runner qualification and\nbinary packaging read consumer source from the workspace while executing selected\nruntime code. Directory equality is not an admission rule; source SHA and artifact\ncontainment checks still apply. The architecture gate parses business JavaScript\nand rejects direct or aliased runtime/source directory equality comparisons.\n\nPublication authority adapters take runtime repository and revision provenance\nfrom the prepared entry selection. Consumer requests provide source, artifact\nand effect authority; they do not supply or readmit a Buildchain SHA. Governance\nand sealed publication evidence retain the selected runtime as provenance while\nvalidating their own source, policy and provider bindings."
|
|
4623
|
+
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: unified-runtime-entry\ndoc_type: implementation-contract\nsource_level: user-consensus\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-09-14\nai_provenance:\n model_family: GPT-6\n product: Codex\n generated_at: 2026-09-14\n visible_context: Source-bound recovery, nested delivery credential transport, published entry contract and local failure-path tests.\n invisible_context_boundary: This contract does not claim implementation or hosted qualification is complete.\n---\n\n# Runtime entry contract\n\nConsumers persist a public workflow reference at `@v4` or `@v4-alpha`.\nGitHub resolves that entry to a commit. The entry selects execution runtime X\nfrom an explicit transient parameter, the selected contract lock, or the entry\ncommit default, in that order. The entry commit and runtime commit may differ.\n\n`actions/runtime/environment/prepare` is the sole runtime preparation owner.\nSelection is resolved once per execution. Each executing job prepares that\nselected runtime through the same implementation. Business workflows and\nactions cannot acquire, replace, reselect or install their own Buildchain\nruntime. All business composites, JavaScript modules, WASM and resources come\nfrom X. Runtime identity is retained as provenance; subsequent business nodes\ndo not compare Buildchain SHAs or require equality with the workflow commit.\n\nA runtime failure can start a recovery execution through the same public\nentry with a transient repaired train branch or tag. The new execution selects\nruntime Y and retains the original task, source and evidence. Valid completed\nresults can be reused; provider effects require readback before further writes.\nSwitching runtimes does not automatically qualify all previous results for reuse.\nNeither the persisted caller nor its contract lock needs a train rewrite.\n\nAn entry failure is repaired by publishing and adopting a corrected entry and\nstarting a new provider run through the corrected floating entry. The caller files\nremain unchanged. A usable recovery entry can still recover the exact existing\nattempt; an entry failure before admission has no attempt to recover.\nBuildchain self-dogfood uses exactly the same consumer contract and has no\nrepository-specific execution or recovery route.\n\nSource checkouts are separate business inputs. Building Buildchain itself may\ncheck out its source, but that source cannot implicitly replace the selected\nexecution runtime. Source, artifact and publication-effect checks retain their\nbusiness meaning; they do not reintroduce downstream Buildchain SHA checks.\n\nAcceptance requires a complete workflow/action acquisition inventory, enforced\nsingle preparation ownership, different entry/runtime execution, train recovery,\nplatform and multi-job qualification, and validation of the published consumer\nentry. A source test or a successful package import alone is insufficient.\n\n## Minimal pipeline provider credentials\n\nConfigure `BUILDCHAIN_AUTOMATION_TOKEN` once as a repository Actions secret when\nprotected delivery requires permissions unavailable to `GITHUB_TOKEN`. Both\ngenerated callers already inherit secrets. No token value, additional input or\nprovider orchestration belongs in the consumer TOML or workflow source.\n\nScope this credential to the consumer repository. Delivery needs Administration\nread access to inspect classic branch locks, Checks read, and Actions, Contents,\nPull requests and Commit statuses write access for its existing provider steps.\nIt does not need permission to change branch protection or bypass review. A\nmissing credential falls back to `GITHUB_TOKEN`; unreadable protection still\nfails closed before candidate reservation instead of assuming an unlocked branch.\n\nThe internal delivery edge forwards only this named secret to the credentialed\nsource, reservation, heartbeat and landing steps. Product builds, native\nexecution and native evidence sealing retain their separate read-only jobs and\nreceive no automation credential. Publication settlement uses the same canonical\nsecret as its existing fallback credential. Repairing a missing workflow secret\nedge requires a corrected published entry and a new provider run.\n\n## Minimal pipeline recovery\n\nThe minimal contract has one normal event caller and one manual recovery caller,\nplus `.buildchain/buildchain.toml`. Both callers are maintained by Buildchain's\nconsumer setup; product differences do not require additional recovery workflows.\nThe repository implementation alone does not prove the entry has been published\nor qualified in a clean consumer.\n\nThe workflow summary identifies the current attempt, its source PR, completed\nsteps and remaining work. Follow **Recover this attempt**, choose **Run workflow**,\nand paste the exact attempt. Leave `runtime-ref` empty for an ordinary retry;\nsupply a repaired runtime only when needed. The public recovery entry accepts no\nother recovery selectors. It derives configuration, producer runs, artifacts and\ntransaction coordinates from the canonical attempt history.\n\nRecovery opens a new attempt with an explicit predecessor. Successful platform\njobs and their actual retained artifacts are independently requalified; only\nmissing platforms or explicitly incompatible stage implementations are rebuilt.\nA signing failure can requalify the original sealed bytes under the repaired\npublisher. Partial publication preserves its original signed transaction and\ncompleted effects, reads providers again, and authorizes only remaining effects.\nMissing, expired or conflicting evidence stops with a diagnosis; it does not\nsilently trigger a complete rebuild or replace published bytes.\n\nA repeated request for the same predecessor and repair selects the same successor.\nIf that recovery was interrupted, select the successor shown in the summary for\nthe next recovery. An active predecessor must first finish or be cancelled using\nits ordinary GitHub execution link. A changed or superseded source cannot reuse\nan old attempt as authority for the current PR. Completed publication remains\nrecorded even when distribution or the next development version still needs work.\nCancellation stops remaining work and cannot undo published results.\n\nOnce admitted, ordinary wake events continue with the recovered attempt's exact\nruntime, even when the consumer lock still names the original runtime. A further\nruntime change requires another explicit recovery. An entry repair is distributed\nthrough the existing `@v4` or `@v4-alpha` entry; consumers do not maintain backup\nscripts, patch a job definition, or add a different recovery workflow family.\n\n## Advanced build component recovery\n\n```yaml\non:\n push:\n workflow_dispatch:\n inputs:\n runtime-ref:\n description: Optional repaired train for this execution\n default: \"\"\n type: string\n resume-run-id:\n description: Original failed build run to recover\n default: \"\"\n type: string\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v4\n with:\n runtime-ref: ${{ inputs.runtime-ref || '' }}\n resume-run-id: ${{ inputs.resume-run-id || '' }}\n```\n\nOrdinary executions use `.buildchain/contract-lock.json`; the alpha entry defaults\nto `.buildchain/alpha-contract-lock.json`. `contract-lock` selects another relative\nlock path. A missing default lock falls back to the entry commit; an invalid lock\nor an unreadable source fails preparation. A supplied runtime parameter overrides\nthe lock and requires caller repository write authority. For `workflow_dispatch`,\nGitHub enforces repository Actions write permission before creating the run,\nincluding calls using installation tokens. The entry uses that authorization;\nan installation bot does not need to be a human repository collaborator.\nOther event types retain the entry's write, maintain or admin collaborator check.\nSee GitHub's [workflow dispatch authorization](https://docs.github.com/en/rest/actions/workflows#create-a-workflow-dispatch-event).\nBranches and tags are resolved to an immutable commit during selection.\n\nFor a Buildchain runtime fault, dispatch the same consumer workflow with\n`runtime-ref: train/v4/v4.1/<repair>` and the original `resume-run-id`. The entry\nretains the original source commit and rejects unrelated workflows or fork runs.\nInstall hydrates the new workspace; completed build outputs are restored only\nwhen source, configuration, platform, tools, artifact producer and all retained\nbytes qualify. The remaining verification runs with the repaired runtime.\nExisting provider effects use their transaction evidence and live readbacks.\nA failed-job rerun cannot supply new inputs; recovery therefore starts a new run.\n\n`runtime-selection` is an internal reusable-workflow transport for an already\nselected runtime. Components forward it unchanged instead of resolving another\nreference. Consumers normally supply `runtime-ref` or a lock, not this transport.\n\nNested components preserve the selected runtime and contract metadata without\nre-reading the lock or comparing the runtime SHA. The internal transport carries\na trusted entry output; consumer source binding and override authorization remain\nentry concerns. Recovery selectors request `actions: read` to read the original\nrun in private repositories as well as public repositories.\n\nBusiness adapters also keep the runtime installation directory separate from the\nconsumer workspace. Queue reconciliation, npm preview, runner qualification and\nbinary packaging read consumer source from the workspace while executing selected\nruntime code. Directory equality is not an admission rule; source SHA and artifact\ncontainment checks still apply. The architecture gate parses business JavaScript\nand rejects direct or aliased runtime/source directory equality comparisons.\n\nPublication authority adapters take runtime repository and revision provenance\nfrom the prepared entry selection. Consumer requests provide source, artifact\nand effect authority; they do not supply or readmit a Buildchain SHA. Governance\nand sealed publication evidence retain the selected runtime as provenance while\nvalidating their own source, policy and provider bindings."
|
|
4619
4624
|
},
|
|
4620
4625
|
{
|
|
4621
4626
|
"id": "manual:runtime-train-validation",
|
|
@@ -753,8 +753,10 @@
|
|
|
753
753
|
"runtime-selection"
|
|
754
754
|
],
|
|
755
755
|
"inputCount": 2,
|
|
756
|
-
"secrets": [
|
|
757
|
-
|
|
756
|
+
"secrets": [
|
|
757
|
+
"BUILDCHAIN_AUTOMATION_TOKEN"
|
|
758
|
+
],
|
|
759
|
+
"secretCount": 1,
|
|
758
760
|
"outputs": [],
|
|
759
761
|
"outputCount": 0
|
|
760
762
|
},
|
|
@@ -11128,8 +11130,8 @@
|
|
|
11128
11130
|
"workflowRegistryPath": "dist/site/workflow-registry.json",
|
|
11129
11131
|
"pageRegistryPath": "dist/site/page-registry.json",
|
|
11130
11132
|
"cliRegistryDigest": "e43fdb0289df88871f3f0febbe04dcb9311a252a2b1df9b3a83a2d10c9d4a70f",
|
|
11131
|
-
"workflowRegistryDigest": "
|
|
11132
|
-
"pageRegistryDigest": "
|
|
11133
|
+
"workflowRegistryDigest": "d52b008d8113340194ec1e074870b71b83392a914536e2ef830c10abee0756d6",
|
|
11134
|
+
"pageRegistryDigest": "a2631ef693dd1f1a6df3b42f31c5113b242368b7680343e5ff7cd94222d30d3d"
|
|
11133
11135
|
},
|
|
11134
11136
|
"comparison": {
|
|
11135
11137
|
"missingCliRegistry": [],
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-publication-release-registry",
|
|
4
|
-
"generatedAt": "2026-09-
|
|
5
|
-
"publishedAt": "2026-09-
|
|
4
|
+
"generatedAt": "2026-09-13T17:39:11.000Z",
|
|
5
|
+
"publishedAt": "2026-09-13T17:39:11.000Z",
|
|
6
6
|
"reproducible": true,
|
|
7
7
|
"timestampPolicy": "ci-injected",
|
|
8
8
|
"deterministicInputs": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"declared Buildchain surface manifest contract"
|
|
20
20
|
],
|
|
21
21
|
"sourceDateEpoch": "0",
|
|
22
|
-
"sourceRevision": "
|
|
22
|
+
"sourceRevision": "5daa16d74fa52d44ae44f31d18860614d5563517",
|
|
23
23
|
"timestampPolicyDetails": {
|
|
24
24
|
"contract": "kungfu-buildchain-surface-timestamp-policy",
|
|
25
25
|
"timestampFields": [
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"package": {
|
|
34
34
|
"name": "@kungfu-tech/buildchain",
|
|
35
|
-
"version": "4.1.3-alpha.
|
|
35
|
+
"version": "4.1.3-alpha.5",
|
|
36
36
|
"versionSource": "package.json#version"
|
|
37
37
|
},
|
|
38
38
|
"sourceKind": "package-site-bundle",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-site-manifest",
|
|
4
|
-
"generatedAt": "2026-09-
|
|
5
|
-
"publishedAt": "2026-09-
|
|
4
|
+
"generatedAt": "2026-09-13T17:39:11.000Z",
|
|
5
|
+
"publishedAt": "2026-09-13T17:39:11.000Z",
|
|
6
6
|
"reproducible": true,
|
|
7
7
|
"timestampPolicy": "ci-injected",
|
|
8
8
|
"deterministicInputs": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"declared Buildchain surface manifest contract"
|
|
20
20
|
],
|
|
21
21
|
"sourceDateEpoch": "0",
|
|
22
|
-
"sourceRevision": "
|
|
22
|
+
"sourceRevision": "5daa16d74fa52d44ae44f31d18860614d5563517",
|
|
23
23
|
"timestampPolicyDetails": {
|
|
24
24
|
"contract": "kungfu-buildchain-surface-timestamp-policy",
|
|
25
25
|
"timestampFields": [
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"package": {
|
|
39
39
|
"name": "@kungfu-tech/buildchain",
|
|
40
|
-
"version": "4.1.3-alpha.
|
|
40
|
+
"version": "4.1.3-alpha.5",
|
|
41
41
|
"versionSource": "package.json#version"
|
|
42
42
|
},
|
|
43
43
|
"entrypoint": "buildchain-site.json",
|
|
@@ -233,8 +233,10 @@
|
|
|
233
233
|
"runtime-selection"
|
|
234
234
|
],
|
|
235
235
|
"inputCount": 2,
|
|
236
|
-
"secrets": [
|
|
237
|
-
|
|
236
|
+
"secrets": [
|
|
237
|
+
"BUILDCHAIN_AUTOMATION_TOKEN"
|
|
238
|
+
],
|
|
239
|
+
"secretCount": 1,
|
|
238
240
|
"outputs": [],
|
|
239
241
|
"outputCount": 0,
|
|
240
242
|
"taxonomy": {
|
|
@@ -1201,7 +1203,7 @@
|
|
|
1201
1203
|
"status": "preview",
|
|
1202
1204
|
"owner": "buildchain-workflows",
|
|
1203
1205
|
"maturity": "preview",
|
|
1204
|
-
"introducedVersion": "4.1.3-alpha.
|
|
1206
|
+
"introducedVersion": "4.1.3-alpha.5",
|
|
1205
1207
|
"compatibilityPromise": "current-contract-only",
|
|
1206
1208
|
"deprecationReplacement": "",
|
|
1207
1209
|
"sunsetCondition": "explicit-contract-change-review",
|
|
@@ -2699,7 +2701,7 @@
|
|
|
2699
2701
|
"status": "preview",
|
|
2700
2702
|
"owner": "buildchain-workflows",
|
|
2701
2703
|
"maturity": "preview",
|
|
2702
|
-
"introducedVersion": "4.1.3-alpha.
|
|
2704
|
+
"introducedVersion": "4.1.3-alpha.5",
|
|
2703
2705
|
"compatibilityPromise": "current-contract-only",
|
|
2704
2706
|
"deprecationReplacement": "",
|
|
2705
2707
|
"sunsetCondition": "explicit-contract-change-review",
|
|
@@ -2729,7 +2731,7 @@
|
|
|
2729
2731
|
"status": "preview",
|
|
2730
2732
|
"owner": "buildchain-workflows",
|
|
2731
2733
|
"maturity": "preview",
|
|
2732
|
-
"introducedVersion": "4.1.3-alpha.
|
|
2734
|
+
"introducedVersion": "4.1.3-alpha.5",
|
|
2733
2735
|
"compatibilityPromise": "current-contract-only",
|
|
2734
2736
|
"deprecationReplacement": "",
|
|
2735
2737
|
"sunsetCondition": "explicit-contract-change-review",
|
|
@@ -2759,7 +2761,7 @@
|
|
|
2759
2761
|
"status": "preview",
|
|
2760
2762
|
"owner": "buildchain-workflows",
|
|
2761
2763
|
"maturity": "preview",
|
|
2762
|
-
"introducedVersion": "4.1.3-alpha.
|
|
2764
|
+
"introducedVersion": "4.1.3-alpha.5",
|
|
2763
2765
|
"compatibilityPromise": "current-contract-only",
|
|
2764
2766
|
"deprecationReplacement": "",
|
|
2765
2767
|
"sunsetCondition": "explicit-contract-change-review",
|
package/docs/runtime-entry.md
CHANGED
|
@@ -8,12 +8,12 @@ confidence: high
|
|
|
8
8
|
sensitivity: public
|
|
9
9
|
evidence_grade: B
|
|
10
10
|
review_state: unreviewed
|
|
11
|
-
last_reviewed: 2026-09-
|
|
11
|
+
last_reviewed: 2026-09-14
|
|
12
12
|
ai_provenance:
|
|
13
13
|
model_family: GPT-6
|
|
14
14
|
product: Codex
|
|
15
|
-
generated_at: 2026-09-
|
|
16
|
-
visible_context: Source-bound
|
|
15
|
+
generated_at: 2026-09-14
|
|
16
|
+
visible_context: Source-bound recovery, nested delivery credential transport, published entry contract and local failure-path tests.
|
|
17
17
|
invisible_context_boundary: This contract does not claim implementation or hosted qualification is complete.
|
|
18
18
|
---
|
|
19
19
|
|
|
@@ -56,6 +56,27 @@ single preparation ownership, different entry/runtime execution, train recovery,
|
|
|
56
56
|
platform and multi-job qualification, and validation of the published consumer
|
|
57
57
|
entry. A source test or a successful package import alone is insufficient.
|
|
58
58
|
|
|
59
|
+
## Minimal pipeline provider credentials
|
|
60
|
+
|
|
61
|
+
Configure `BUILDCHAIN_AUTOMATION_TOKEN` once as a repository Actions secret when
|
|
62
|
+
protected delivery requires permissions unavailable to `GITHUB_TOKEN`. Both
|
|
63
|
+
generated callers already inherit secrets. No token value, additional input or
|
|
64
|
+
provider orchestration belongs in the consumer TOML or workflow source.
|
|
65
|
+
|
|
66
|
+
Scope this credential to the consumer repository. Delivery needs Administration
|
|
67
|
+
read access to inspect classic branch locks, Checks read, and Actions, Contents,
|
|
68
|
+
Pull requests and Commit statuses write access for its existing provider steps.
|
|
69
|
+
It does not need permission to change branch protection or bypass review. A
|
|
70
|
+
missing credential falls back to `GITHUB_TOKEN`; unreadable protection still
|
|
71
|
+
fails closed before candidate reservation instead of assuming an unlocked branch.
|
|
72
|
+
|
|
73
|
+
The internal delivery edge forwards only this named secret to the credentialed
|
|
74
|
+
source, reservation, heartbeat and landing steps. Product builds, native
|
|
75
|
+
execution and native evidence sealing retain their separate read-only jobs and
|
|
76
|
+
receive no automation credential. Publication settlement uses the same canonical
|
|
77
|
+
secret as its existing fallback credential. Repairing a missing workflow secret
|
|
78
|
+
edge requires a corrected published entry and a new provider run.
|
|
79
|
+
|
|
59
80
|
## Minimal pipeline recovery
|
|
60
81
|
|
|
61
82
|
The minimal contract has one normal event caller and one manual recovery caller,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungfu-tech/buildchain",
|
|
3
|
-
"version": "4.1.3-alpha.
|
|
3
|
+
"version": "4.1.3-alpha.5",
|
|
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",
|
|
@@ -30,7 +30,7 @@ function compileChannels(values) {
|
|
|
30
30
|
text(
|
|
31
31
|
value.from,
|
|
32
32
|
`${field}.from`,
|
|
33
|
-
/^(?:feature|dev|alpha|release)\/[A-Za-z0-9/*._-]+$/u,
|
|
33
|
+
/^(?:feature|fix|chore|docs|ci|refactor|dev|alpha|release)\/[A-Za-z0-9/*._-]+$/u,
|
|
34
34
|
);
|
|
35
35
|
text(
|
|
36
36
|
value.to,
|
|
@@ -45,7 +45,10 @@ function compileChannels(values) {
|
|
|
45
45
|
const source = value.from.split("/")[0],
|
|
46
46
|
target = value.to.split("/")[0];
|
|
47
47
|
const legal = {
|
|
48
|
-
develop:
|
|
48
|
+
develop:
|
|
49
|
+
["feature", "fix", "chore", "docs", "ci", "refactor"].includes(
|
|
50
|
+
source,
|
|
51
|
+
) && target === "dev",
|
|
49
52
|
alpha: source === "dev" && target === "alpha",
|
|
50
53
|
stable: source === "alpha" && target === "release",
|
|
51
54
|
major: source === "release" && value.to === "publish-gate/major",
|
|
@@ -10,10 +10,13 @@ export function discussionMaterials({
|
|
|
10
10
|
octokit,
|
|
11
11
|
repository,
|
|
12
12
|
intentId,
|
|
13
|
+
partition = "",
|
|
13
14
|
authorityDescription = "The associated Discussion owns transaction state.",
|
|
14
15
|
}) {
|
|
15
16
|
const [owner, repo] = repository.split("/");
|
|
16
|
-
|
|
17
|
+
if (partition && !/^[1-9][0-9]*-[1-9][0-9]*-[1-9][0-9]*$/u.test(partition))
|
|
18
|
+
throw new Error("Invalid material archive writer partition");
|
|
19
|
+
const tag = `buildchain-records/${intentId.replace("sha256:", "")}${partition ? `/${partition}` : ""}`;
|
|
17
20
|
const repos = octokit.rest.repos;
|
|
18
21
|
let retainedArchive;
|
|
19
22
|
async function findArchive() {
|
|
@@ -32,8 +35,7 @@ export function discussionMaterials({
|
|
|
32
35
|
throw new Error("Ambiguous transaction material archive");
|
|
33
36
|
return matches[0];
|
|
34
37
|
}
|
|
35
|
-
async function
|
|
36
|
-
if (retainedArchive) return retainedArchive;
|
|
38
|
+
async function createArchive() {
|
|
37
39
|
let release = await findArchive();
|
|
38
40
|
if (!release) {
|
|
39
41
|
try {
|
|
@@ -60,9 +62,15 @@ export function discussionMaterials({
|
|
|
60
62
|
}
|
|
61
63
|
if (!release.draft || release.tag_name !== tag)
|
|
62
64
|
throw new Error("Transaction material archive identity mismatch");
|
|
63
|
-
retainedArchive = release;
|
|
64
65
|
return release;
|
|
65
66
|
}
|
|
67
|
+
function archive() {
|
|
68
|
+
// Concurrent puts in one writer share the same creation, including readback.
|
|
69
|
+
return (retainedArchive ||= createArchive().catch((error) => {
|
|
70
|
+
retainedArchive = undefined;
|
|
71
|
+
throw error;
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
66
74
|
async function read(handle) {
|
|
67
75
|
const response = await repos.getReleaseAsset({
|
|
68
76
|
owner,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { recordDigest } from "../../release/discussion/envelope.js";
|
|
2
2
|
|
|
3
3
|
const QUERY = `query PipelinePolicy($owner:String!,$name:String!,$number:Int!){repository(owner:$owner,name:$name){pullRequest(number:$number){id number headRefOid baseRefName isDraft reviewDecision author{login}}}}`;
|
|
4
|
-
const BRANCH_QUERY = `query PipelineBranchPolicy($owner:String!,$name:String!,$branch:String!,$ref:String!){repository(owner:$owner,name:$name){ref(qualifiedName:$ref){
|
|
4
|
+
const BRANCH_QUERY = `query PipelineBranchPolicy($owner:String!,$name:String!,$branch:String!,$ref:String!){repository(owner:$owner,name:$name){ref(qualifiedName:$ref){refUpdateRule{requiredApprovingReviewCount requiresCodeOwnerReviews requiredStatusCheckContexts}}mergeQueue(branch:$branch){id}}}`;
|
|
5
5
|
|
|
6
6
|
async function classicPolicy(request, owner, name, branch) {
|
|
7
|
-
//
|
|
8
|
-
//
|
|
7
|
+
// Read viewer-enforced rules and the ordinary Contents:read branch projection.
|
|
8
|
+
// Administrative branchProtectionRule and /protection queries are not needed.
|
|
9
9
|
const result = await request("/graphql", {
|
|
10
10
|
method: "POST",
|
|
11
11
|
body: {
|
|
@@ -14,23 +14,50 @@ async function classicPolicy(request, owner, name, branch) {
|
|
|
14
14
|
},
|
|
15
15
|
});
|
|
16
16
|
const repository = result.data?.repository;
|
|
17
|
-
if (!repository)
|
|
18
|
-
|
|
17
|
+
if (!repository?.ref)
|
|
18
|
+
throw new Error("Protected branch metadata is unavailable");
|
|
19
|
+
const rule = repository.ref.refUpdateRule;
|
|
20
|
+
const observed = await request(
|
|
21
|
+
`/repos/${owner}/${name}/branches/${encodeURIComponent(branch)}`,
|
|
22
|
+
);
|
|
23
|
+
const status = observed.protection?.required_status_checks;
|
|
24
|
+
const contexts = status?.contexts;
|
|
25
|
+
const checks = status?.checks;
|
|
26
|
+
if (
|
|
27
|
+
observed.name !== branch ||
|
|
28
|
+
!Array.isArray(contexts) ||
|
|
29
|
+
!Array.isArray(checks) ||
|
|
30
|
+
checks.some(
|
|
31
|
+
(check) =>
|
|
32
|
+
typeof check.context !== "string" ||
|
|
33
|
+
!check.context ||
|
|
34
|
+
!Object.hasOwn(check, "app_id") ||
|
|
35
|
+
!(
|
|
36
|
+
check.app_id === null ||
|
|
37
|
+
check.app_id === -1 ||
|
|
38
|
+
(Number.isSafeInteger(check.app_id) && check.app_id > 0)
|
|
39
|
+
),
|
|
40
|
+
) ||
|
|
41
|
+
contexts.some(
|
|
42
|
+
(context) => !checks.some((check) => check.context === context),
|
|
43
|
+
) ||
|
|
44
|
+
checks.some((check) => !contexts.includes(check.context)) ||
|
|
45
|
+
(rule?.requiredStatusCheckContexts || []).some(
|
|
46
|
+
(context) => !contexts.includes(context),
|
|
47
|
+
)
|
|
48
|
+
)
|
|
49
|
+
throw new Error("Protected branch check identity metadata is incomplete");
|
|
19
50
|
return {
|
|
20
51
|
required_merge_queue: Boolean(repository.mergeQueue?.id),
|
|
21
|
-
required_pull_request_reviews:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
52
|
+
required_pull_request_reviews:
|
|
53
|
+
rule?.requiredApprovingReviewCount > 0
|
|
54
|
+
? {
|
|
55
|
+
require_code_owner_reviews: rule.requiresCodeOwnerReviews,
|
|
56
|
+
required_approving_review_count: rule.requiredApprovingReviewCount,
|
|
57
|
+
}
|
|
58
|
+
: null,
|
|
27
59
|
required_status_checks: {
|
|
28
|
-
checks
|
|
29
|
-
? (rule.requiredStatusChecks || []).map((check) => ({
|
|
30
|
-
context: check.context,
|
|
31
|
-
app_id: check.app?.databaseId || null,
|
|
32
|
-
}))
|
|
33
|
-
: [],
|
|
60
|
+
checks,
|
|
34
61
|
},
|
|
35
62
|
};
|
|
36
63
|
}
|
|
@@ -10,17 +10,34 @@ function exactSha(value) {
|
|
|
10
10
|
return value;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
function sourceRefBinding(reference) {
|
|
14
|
+
return {
|
|
15
|
+
ref: reference?.ref ?? null,
|
|
16
|
+
sha: reference?.sha ?? null,
|
|
17
|
+
repository: {
|
|
18
|
+
id: reference?.repo?.id ?? null,
|
|
19
|
+
nodeId: reference?.repo?.node_id ?? null,
|
|
20
|
+
fullName: reference?.repo?.full_name ?? null,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function mergedCommit(pr) {
|
|
26
|
+
return pr.merged === true ? pr.merge_commit_sha : null;
|
|
27
|
+
}
|
|
28
|
+
|
|
13
29
|
function pullRequestBinding(pr) {
|
|
30
|
+
// Provider timestamps and repository metadata can change during our own
|
|
31
|
+
// evidence writes. Bind source and delivery state, not those unrelated fields.
|
|
14
32
|
return {
|
|
15
33
|
number: pr.number,
|
|
16
34
|
state: pr.state,
|
|
17
35
|
merged: pr.merged,
|
|
18
|
-
mergeCommit: pr
|
|
19
|
-
head: pr.head,
|
|
20
|
-
base: pr.base,
|
|
36
|
+
mergeCommit: mergedCommit(pr),
|
|
37
|
+
head: sourceRefBinding(pr.head),
|
|
38
|
+
base: sourceRefBinding(pr.base),
|
|
21
39
|
draft: pr.draft,
|
|
22
|
-
|
|
23
|
-
updatedAt: pr.updated_at,
|
|
40
|
+
ready: pr.labels.some((label) => label.name === "ready"),
|
|
24
41
|
};
|
|
25
42
|
}
|
|
26
43
|
|
|
@@ -113,7 +130,7 @@ export function githubPipelineSource(request, repository) {
|
|
|
113
130
|
baseCommit,
|
|
114
131
|
state: pr.state,
|
|
115
132
|
merged: pr.merged === true,
|
|
116
|
-
mergeCommit: pr
|
|
133
|
+
mergeCommit: mergedCommit(pr),
|
|
117
134
|
draft: pr.draft === true,
|
|
118
135
|
ready: pr.labels.some((label) => label.name === "ready"),
|
|
119
136
|
},
|
|
@@ -141,7 +158,7 @@ export function githubPipelineSource(request, repository) {
|
|
|
141
158
|
targetBranch: pr.base.ref,
|
|
142
159
|
state: pr.state,
|
|
143
160
|
merged: pr.merged === true,
|
|
144
|
-
mergeCommit: pr
|
|
161
|
+
mergeCommit: mergedCommit(pr),
|
|
145
162
|
source: sameHead ? generation.source : null,
|
|
146
163
|
baseCommit: null,
|
|
147
164
|
ready: pr.labels.some((label) => label.name === "ready"),
|
|
@@ -37,6 +37,14 @@ export async function retainPipelineBuildResult(
|
|
|
37
37
|
session,
|
|
38
38
|
host,
|
|
39
39
|
) {
|
|
40
|
+
if (
|
|
41
|
+
readback.outcome === "success" &&
|
|
42
|
+
session.intent.expectedNodes.includes("publish")
|
|
43
|
+
)
|
|
44
|
+
await host.qualifyChannel(
|
|
45
|
+
context.source,
|
|
46
|
+
session.intent.source.targetBranch,
|
|
47
|
+
);
|
|
40
48
|
const reference = await resultReference(context, readback, session, host);
|
|
41
49
|
await session.progress.progress({
|
|
42
50
|
attempt: context.attempt,
|
|
@@ -68,6 +68,10 @@ export async function controlPipelineChannel(session, admission, inputs, host) {
|
|
|
68
68
|
}
|
|
69
69
|
if (host.terminalOnly)
|
|
70
70
|
return { operation: "wait", reason: "terminal-event-cannot-execute" };
|
|
71
|
+
const qualification = await host.qualifyChannel(
|
|
72
|
+
live.source,
|
|
73
|
+
live.targetBranch,
|
|
74
|
+
);
|
|
71
75
|
const build = await pipelineBuildEvidence(session, host);
|
|
72
76
|
if (!build) return { operation: "build", admission };
|
|
73
77
|
if (build.run.status !== "completed" || build.run.conclusion !== "success")
|
|
@@ -97,7 +101,12 @@ export async function controlPipelineChannel(session, admission, inputs, host) {
|
|
|
97
101
|
session,
|
|
98
102
|
"merge",
|
|
99
103
|
"waiting",
|
|
100
|
-
{
|
|
104
|
+
{
|
|
105
|
+
schema: "buildchain.pipeline-channel-enqueue/v1",
|
|
106
|
+
qualification,
|
|
107
|
+
policy,
|
|
108
|
+
queue,
|
|
109
|
+
},
|
|
101
110
|
host,
|
|
102
111
|
);
|
|
103
112
|
const again = await host.source.observeIntent(
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { recordDigest } from "../../release/discussion/envelope.js";
|
|
2
|
+
import { selectProductPublicationIntent } from "../../release/product-publication.js";
|
|
3
|
+
import { pipelineExpectedProducts } from "../../publication/pipeline/plan.js";
|
|
4
|
+
import { githubPipelineVersion } from "../../providers/github/pipeline-version.js";
|
|
5
|
+
|
|
6
|
+
// This read-only qualification must precede both required checks and queue
|
|
7
|
+
// admission. Publication repeats the Rust-owned decision after protected merge.
|
|
8
|
+
export async function qualifyPipelineChannelSource(source, branch, host) {
|
|
9
|
+
if (branch.startsWith("dev/")) return null;
|
|
10
|
+
const admitted = await host.source.source(source.commit, source.configPath);
|
|
11
|
+
if (recordDigest(admitted.identity) !== recordDigest(source))
|
|
12
|
+
throw new Error("Channel qualification source identity drift");
|
|
13
|
+
const { plan } = admitted;
|
|
14
|
+
const routes = plan.channels.filter(
|
|
15
|
+
(route) => route.to === branch && route.operation !== "develop",
|
|
16
|
+
);
|
|
17
|
+
if (routes.length !== 1)
|
|
18
|
+
throw new Error("Channel qualification requires one publication route");
|
|
19
|
+
const route = routes[0];
|
|
20
|
+
const from = `${route.operation === "alpha" ? "dev" : "alpha"}/${branch.split("/").slice(1).join("/")}`;
|
|
21
|
+
if (["alpha", "stable"].includes(route.operation) && route.from !== from)
|
|
22
|
+
throw new Error("Channel source and target version lines must match");
|
|
23
|
+
const version = await githubPipelineVersion(
|
|
24
|
+
host.request,
|
|
25
|
+
host.repository,
|
|
26
|
+
).inspect(source, plan.version);
|
|
27
|
+
const selection = selectProductPublicationIntent({
|
|
28
|
+
channel: route.operation === "alpha" ? "alpha" : "stable",
|
|
29
|
+
targetRef: branch,
|
|
30
|
+
sourceSha: source.commit,
|
|
31
|
+
sourceTimestamp: version.sourceTimestamp,
|
|
32
|
+
repository: source.repository,
|
|
33
|
+
artifactKind: "custom",
|
|
34
|
+
requiredArtifactsRoot: recordDigest(pipelineExpectedProducts(plan)),
|
|
35
|
+
candidateVersion: version.version,
|
|
36
|
+
observedVersions: [],
|
|
37
|
+
});
|
|
38
|
+
if (
|
|
39
|
+
plan.version.strategy === "anchored" &&
|
|
40
|
+
selection.version !== version.version
|
|
41
|
+
)
|
|
42
|
+
throw new Error("Anchored channel source requires a materialized version");
|
|
43
|
+
const body = {
|
|
44
|
+
schema: "buildchain.pipeline-channel-source-qualification/v1",
|
|
45
|
+
source,
|
|
46
|
+
route,
|
|
47
|
+
contractRoot: recordDigest(plan),
|
|
48
|
+
version: version.version,
|
|
49
|
+
versionFilesRoot: recordDigest(version.files),
|
|
50
|
+
selection,
|
|
51
|
+
};
|
|
52
|
+
return { ...body, root: recordDigest(body) };
|
|
53
|
+
}
|
|
@@ -36,6 +36,8 @@ export async function recordPipelineGroup(context, host) {
|
|
|
36
36
|
context.source,
|
|
37
37
|
context.platforms.map((platform) => platform.platform),
|
|
38
38
|
);
|
|
39
|
+
if (readback.outcome === "success")
|
|
40
|
+
await host.qualifyChannel(context.source, context.branch);
|
|
39
41
|
await host.request(`/repos/${host.repository}/check-runs`, {
|
|
40
42
|
method: "POST",
|
|
41
43
|
body: {
|
|
@@ -17,6 +17,7 @@ import { GitHubClient } from "../../dev-delivery/admission/github-client.js";
|
|
|
17
17
|
import { githubPipelineIntegration } from "../../providers/github/pipeline-integration.js";
|
|
18
18
|
import { recordPipelineGroup } from "./group-control.js";
|
|
19
19
|
import { controlPipelineChannel } from "./channel-control.js";
|
|
20
|
+
import { qualifyPipelineChannelSource } from "./channel-source.js";
|
|
20
21
|
import { settlePipeline } from "./settlement.js";
|
|
21
22
|
import { pipelineProjection } from "./projection.js";
|
|
22
23
|
import { resumePipelineNotifications } from "./notifications.js";
|
|
@@ -48,6 +49,24 @@ export async function pipelineHost(core, env, jobName) {
|
|
|
48
49
|
const writer = await runs.writer(runId, runAttempt, jobName);
|
|
49
50
|
const source = githubPipelineSource(request, repository);
|
|
50
51
|
const [owner, repo] = repository.split("/");
|
|
52
|
+
const archives = new Map();
|
|
53
|
+
function archive(session) {
|
|
54
|
+
if (!archives.has(session.intent.id))
|
|
55
|
+
archives.set(
|
|
56
|
+
session.intent.id,
|
|
57
|
+
discussionMaterials({
|
|
58
|
+
octokit: github,
|
|
59
|
+
repository,
|
|
60
|
+
intentId: session.intent.id,
|
|
61
|
+
// Storage is partitioned by verified provider job, not attempt authority.
|
|
62
|
+
// Journal references still select exact immutable asset IDs and digests.
|
|
63
|
+
partition: `${writer.runId}-${writer.runAttempt}-${writer.jobId}`,
|
|
64
|
+
authorityDescription:
|
|
65
|
+
"The canonical Buildchain intent Git journal owns transaction state.",
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
return archives.get(session.intent.id);
|
|
69
|
+
}
|
|
51
70
|
const host = {
|
|
52
71
|
repository,
|
|
53
72
|
token,
|
|
@@ -70,6 +89,8 @@ export async function pipelineHost(core, env, jobName) {
|
|
|
70
89
|
groupRecord: (context) => recordPipelineGroup(context, host),
|
|
71
90
|
channel: (session, admission, inputs) =>
|
|
72
91
|
controlPipelineChannel(session, admission, inputs, host),
|
|
92
|
+
qualifyChannel: (source, branch) =>
|
|
93
|
+
qualifyPipelineChannelSource(source, branch, host),
|
|
73
94
|
settle: (session, fresh, delivery) =>
|
|
74
95
|
settlePipeline(session, fresh, delivery, host),
|
|
75
96
|
project: (session) =>
|
|
@@ -81,24 +102,11 @@ export async function pipelineHost(core, env, jobName) {
|
|
|
81
102
|
recoverPublication: (session, admitted) =>
|
|
82
103
|
inspectRecoveryPublication(session, admitted, host),
|
|
83
104
|
materialStore: (session) =>
|
|
84
|
-
pipelineMaterials(
|
|
85
|
-
discussionMaterials({
|
|
86
|
-
octokit: github,
|
|
87
|
-
repository,
|
|
88
|
-
intentId: session.intent.id,
|
|
89
|
-
authorityDescription:
|
|
90
|
-
"The canonical Buildchain intent Git journal owns transaction state.",
|
|
91
|
-
}),
|
|
92
|
-
{ repository, attempt: session.observed.history.at(-1).identity },
|
|
93
|
-
),
|
|
94
|
-
productArchive: (session) =>
|
|
95
|
-
discussionMaterials({
|
|
96
|
-
octokit: github,
|
|
105
|
+
pipelineMaterials(archive(session), {
|
|
97
106
|
repository,
|
|
98
|
-
|
|
99
|
-
authorityDescription:
|
|
100
|
-
"The canonical Buildchain intent Git journal owns transaction state.",
|
|
107
|
+
attempt: session.observed.history.at(-1).identity,
|
|
101
108
|
}),
|
|
109
|
+
productArchive: archive,
|
|
102
110
|
wake: async (attempt) => {
|
|
103
111
|
await index.resolve(attempt);
|
|
104
112
|
await request(`/repos/${repository}/dispatches`, {
|
|
@@ -10,8 +10,12 @@ async function successorSelection(
|
|
|
10
10
|
inputs,
|
|
11
11
|
host,
|
|
12
12
|
) {
|
|
13
|
+
const failedBuild =
|
|
14
|
+
session.observed.status === "failure" &&
|
|
15
|
+
session.observed.phases.build?.payload.state === "failure";
|
|
13
16
|
if (
|
|
14
|
-
!
|
|
17
|
+
(!failedBuild &&
|
|
18
|
+
!["superseded", "cancelled"].includes(session.observed.status)) ||
|
|
15
19
|
event.terminalOnly ||
|
|
16
20
|
admission.live.state !== "open" ||
|
|
17
21
|
admission.live.targetBranch !== session.intent.source.targetBranch
|
|
@@ -27,9 +31,10 @@ async function successorSelection(
|
|
|
27
31
|
.id !== session.observed.generation;
|
|
28
32
|
if (
|
|
29
33
|
!changed &&
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
(failedBuild ||
|
|
35
|
+
!["reopened", "enqueued", "ready_for_review", "labeled"].includes(
|
|
36
|
+
payload.action,
|
|
37
|
+
))
|
|
33
38
|
)
|
|
34
39
|
return { session, admission };
|
|
35
40
|
await host.notifyTerminal?.(session);
|