@kungfu-tech/buildchain 4.1.3-alpha.4 → 4.1.3-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +41 -75
- package/CONTRIBUTING.md +19 -26
- package/architecture/agent-change-map.md +8 -12
- package/architecture/capability-state-machine-manifest.json +1 -4
- package/architecture/ci-lane-change-budget.json +35 -1026
- package/architecture/core-mechanisms.json +3 -6
- package/architecture/internal-capabilities.json +1 -5
- package/architecture/maintainability-debt.json +44 -36
- package/architecture/maintainability-policy.json +8 -8
- package/architecture/minimal-consumer-migration.json +80 -1977
- package/architecture/platform-stage-checkpoints.json +31 -7
- package/architecture/release-topology.json +64 -84
- package/architecture/stage-capsule-qualification.json +3 -1
- package/architecture/universal-workflow-bootstrap.json +3 -1
- package/architecture/universal-workflow-capability-policy.json +4 -4
- package/architecture/universal-workflow-fault-campaign.json +3 -1
- package/architecture/workflow-taxonomy.json +24 -341
- package/dist/site/buildchain-contract.json +13 -67
- package/dist/site/buildchain-site.json +33 -23
- package/dist/site/capability-registry.json +2 -2
- package/dist/site/controller-registry.json +1 -47
- package/dist/site/kfd-claims.json +78 -448
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +3 -3
- package/dist/site/node-api-registry.json +24 -24
- package/dist/site/page-registry.json +26 -16
- package/dist/site/public-surface-audit.json +35 -349
- package/dist/site/publication-authority-registry.json +51 -511
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +7 -7
- package/dist/site/workflow-registry.json +263 -1128
- package/docs/code-organization.md +9 -6
- package/docs/node-api-reference.md +57 -57
- package/docs/release-governance.md +10 -12
- package/docs/runtime-entry.md +31 -3
- package/docs/runtime-train-validation.md +39 -11
- package/docs/stable-candidate-patrol.md +6 -5
- package/docs/workflow-catalog.md +3 -32
- package/package.json +1 -1
- package/packages/core/adoption/buildchain-kfd-claims.js +7 -7
- package/packages/core/dev-delivery/dev-delivery-provider-heartbeat.js +18 -15
- package/packages/core/dev-delivery/native/actions.js +2 -0
- package/packages/core/dev-delivery/native/process-entry.js +19 -0
- package/packages/core/dev-delivery/queue/landing-action.js +49 -1
- package/packages/core/dev-delivery/warrant/failure-settlement.js +8 -6
- package/packages/core/dev-delivery/warrant/service.js +7 -0
- package/packages/core/governance/buildchain-publication-authority.js +2 -23
- package/packages/core/governance/github-governance-authority.js +1 -0
- package/packages/core/observability/controller-evidence.js +0 -8
- package/packages/core/providers/github/pipeline-entry-runs.js +8 -1
- package/packages/core/providers/github/pipeline-events.js +79 -0
- package/packages/core/providers/github/pipeline-source.js +24 -7
- package/packages/core/publication/pipeline/pack.js +31 -8
- package/packages/core/workflow/pipeline/actions.js +0 -23
- package/packages/core/workflow/pipeline/build-evidence.js +123 -5
- package/packages/core/workflow/pipeline/build-result.js +1 -0
- package/packages/core/workflow/pipeline/channel-control.js +25 -4
- package/packages/core/workflow/pipeline/controller.js +9 -1
- package/packages/core/workflow/pipeline/delivery-control.js +54 -9
- package/packages/core/workflow/pipeline/delivery-observation.js +16 -10
- package/packages/core/workflow/pipeline/group-control.js +1 -0
- package/packages/core/workflow/pipeline/guard-build.js +37 -0
- package/packages/core/workflow/pipeline/guard.js +4 -2
- package/packages/core/workflow/pipeline/host.js +23 -1
- package/packages/core/workflow/pipeline/integration-status.js +113 -0
- package/packages/core/workflow/pipeline/record-action.js +27 -0
- package/packages/core/workflow/pipeline/recorder-status.js +69 -0
- package/packages/core/workflow/workflow-taxonomy.mjs +67 -47
- package/scripts/check-inventory.mjs +7 -70
- package/scripts/check-pipeline-publication-topology.mjs +2 -0
- package/scripts/check-public-dogfood-contract.mjs +38 -51
- package/scripts/check-release-topology.mjs +8 -7
- package/scripts/check-self-consumer-contract.mjs +133 -0
- package/scripts/check-universal-workflow-bootstrap.mjs +4 -6
- package/scripts/generate-minimal-consumer-contract.mjs +1 -1
- package/scripts/inventory/binary.mjs +9 -19
- package/scripts/inventory/promotion.mjs +2 -13
- package/scripts/prepare-product-toolchain.mjs +10 -0
- package/scripts/verify-product-platform.mjs +65 -0
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,34 @@ 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. Development
|
|
70
|
+
admission can fall back to `GITHUB_TOKEN`; unreadable protection still fails
|
|
71
|
+
closed before candidate reservation instead of assuming an unlocked branch.
|
|
72
|
+
Channel enqueue requires an explicit automation credential or an App installation
|
|
73
|
+
credential because `GITHUB_TOKEN` suppresses the required `merge_group` workflow.
|
|
74
|
+
Both central entries select that credential through the shared token provider;
|
|
75
|
+
queue reads and journal writes retain their existing workflow credential. An App
|
|
76
|
+
uses `BUILDCHAIN_APP_CLIENT_ID` and `BUILDCHAIN_APP_PRIVATE_KEY`, scoped to the
|
|
77
|
+
consumer repository with Pull requests write access. Missing or incomplete queue
|
|
78
|
+
credentials fail closed before enqueue.
|
|
79
|
+
|
|
80
|
+
The internal delivery edge forwards only this named secret to the credentialed
|
|
81
|
+
source, reservation, heartbeat and landing steps. Product builds, native
|
|
82
|
+
execution and native evidence sealing retain their separate read-only jobs and
|
|
83
|
+
receive no automation credential. Publication settlement uses the same canonical
|
|
84
|
+
secret as its existing fallback credential. Repairing a missing workflow secret
|
|
85
|
+
edge requires a corrected published entry and a new provider run.
|
|
86
|
+
|
|
59
87
|
## Minimal pipeline recovery
|
|
60
88
|
|
|
61
89
|
The minimal contract has one normal event caller and one manual recovery caller,
|
|
@@ -8,27 +8,30 @@ 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
|
-
|
|
15
|
+
generated_at: 2026-09-14
|
|
16
|
+
visible_context: Source-bound caller installation, pipeline wake implementation and GitHub event documentation.
|
|
17
|
+
invisible_context_boundary: No unobserved provider execution or publication authority is claimed.
|
|
17
18
|
---
|
|
18
19
|
|
|
19
20
|
# Runtime Train Validation
|
|
20
21
|
|
|
21
22
|
A train repairs the execution runtime without changing the consumer's durable
|
|
22
23
|
public entry. All public workflows, including ordinary builds, use the same
|
|
23
|
-
[Runtime entry contract](runtime-entry.md). The transient runtime parameter
|
|
24
|
-
|
|
24
|
+
[Runtime entry contract](runtime-entry.md). The recovery entry accepts a transient runtime parameter, which wins over the
|
|
25
|
+
consumer lock. The normal minimal pipeline accepts only an optional config path.
|
|
26
|
+
Buildchain dogfood follows the same two-entry contract.
|
|
25
27
|
|
|
26
28
|
## Validate a runtime change
|
|
27
29
|
|
|
28
30
|
1. Commit the candidate with its action bundles, WASM and runtime contract.
|
|
29
31
|
2. Publish the candidate at `train/v4/v4.1/<capability>`.
|
|
30
|
-
3.
|
|
31
|
-
train. Record the selected runtime, consumer
|
|
32
|
+
3. Recover the exact retained attempt through `buildchain-recover.yml`, with
|
|
33
|
+
`runtime-ref` set to that train. Record the attempt, selected runtime, consumer
|
|
34
|
+
source and resulting evidence.
|
|
32
35
|
4. After checks and independent review, merge into protected Dev and publish
|
|
33
36
|
the requested Alpha. Qualify the published entry before Stable promotion.
|
|
34
37
|
|
|
@@ -38,13 +41,38 @@ provider credentials, capability constraints and readback requirements.
|
|
|
38
41
|
|
|
39
42
|
## Recover a runtime failure
|
|
40
43
|
|
|
41
|
-
Start a new dispatch through
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
Y while the task keeps its original source and valid completed evidence.
|
|
44
|
+
Start a new dispatch through `buildchain-recover.yml` with the exact attempt
|
|
45
|
+
and the repaired train. The runtime selects the retained source and completed
|
|
46
|
+
evidence; the consumer does not provide candidate, run or transaction selectors.
|
|
45
47
|
A GitHub failed-job rerun does not change its inputs and cannot select a new
|
|
46
48
|
runtime. Do not persist the train into the caller workflow or contract lock.
|
|
47
49
|
|
|
48
50
|
If the public entry itself is defective, publish and adopt the corrected entry
|
|
49
51
|
and start a full run. Copied consumer recovery packages and alternate recovery
|
|
50
52
|
workflows are not part of the runtime contract.
|
|
53
|
+
|
|
54
|
+
## Protected minimal-entry installation
|
|
55
|
+
|
|
56
|
+
Install both generated callers, `buildchain.yml` and `buildchain-recover.yml`,
|
|
57
|
+
on the protected default branch before retiring the previous delivery controller.
|
|
58
|
+
Read back both files at the exact protected commit and verify their provider
|
|
59
|
+
workflow registrations. A workflow registered from a task branch does not prove
|
|
60
|
+
that its event receiver is installed on the default branch. GitHub requires that
|
|
61
|
+
location for [repository dispatch events](https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#repository_dispatch).
|
|
62
|
+
|
|
63
|
+
Recovery preserves source and completed artifacts, then emits a repository
|
|
64
|
+
wake for the remaining pipeline work. That wake requires the normal caller on
|
|
65
|
+
the default branch; installing only the manual recovery caller leaves this
|
|
66
|
+
continuation receiver absent. Verify the complete pair before the first recovery.
|
|
67
|
+
|
|
68
|
+
During this bounded migration, pause the normal pipeline before enabling the
|
|
69
|
+
previous protected delivery controller. After the installation merge, wait for
|
|
70
|
+
its runs and Warrant to become terminal, then pause that controller and enable
|
|
71
|
+
the normal pipeline before recovering a current admitted attempt. An installation
|
|
72
|
+
merge advances the protected base, so an older unmerged source attempt must be
|
|
73
|
+
re-admitted on the current base before recovery.
|
|
74
|
+
|
|
75
|
+
Both callers are byte-identical to the generated consumer entries and call the
|
|
76
|
+
published `@v4-alpha` public workflows. Recovery accepts only `attempt` and
|
|
77
|
+
optional `runtime-ref`; the normal caller retains its protected config path.
|
|
78
|
+
This installation order does not qualify the full self cutover or Stable release.
|
|
@@ -8,12 +8,12 @@ confidence: high
|
|
|
8
8
|
sensitivity: public
|
|
9
9
|
evidence_grade: A
|
|
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:
|
|
15
|
+
generated_at: 2026-09-14
|
|
16
|
+
visible_context: User-directed zero-delay self release policy, required provider evidence and regression tests.
|
|
17
17
|
invisible_context_boundary: No credentials, private logs, or unpublished consumer content were used.
|
|
18
18
|
---
|
|
19
19
|
|
|
@@ -52,7 +52,8 @@ It writes `buildchain-canary/buildchain-zero-input` on the qualified runtime SHA
|
|
|
52
52
|
as `github-actions[bot]`. The consumer source SHA may differ from that runtime.
|
|
53
53
|
|
|
54
54
|
The repository Patrol policy requires the alpha Release and this qualification
|
|
55
|
-
status.
|
|
55
|
+
status. Its minimum soak and stable publication interval are both zero.
|
|
56
|
+
The publication transaction still requires
|
|
56
57
|
its sealed release candidate and protected branch checks. Qualification produces
|
|
57
58
|
evidence; it does not publish or merge a candidate.
|
|
58
59
|
|
|
@@ -78,7 +79,7 @@ Declare the default once in `.buildchain/buildchain.toml`:
|
|
|
78
79
|
strategy = "latest-qualified-alpha"
|
|
79
80
|
timezone = "Asia/Shanghai"
|
|
80
81
|
publish_at = "03:00"
|
|
81
|
-
minimum_soak_seconds =
|
|
82
|
+
minimum_soak_seconds = 0
|
|
82
83
|
required_checks = [
|
|
83
84
|
"alpha-release",
|
|
84
85
|
"workflow:Build",
|
package/docs/workflow-catalog.md
CHANGED
|
@@ -23,7 +23,7 @@ Generated from `architecture/workflow-taxonomy.json`. Every workflow has one can
|
|
|
23
23
|
|
|
24
24
|
Public workflows own the consumer API. Component workflows own reusable multi-job topology. Self workflows own Buildchain repository automation. Actions own execution steps; JS adapters and Rust/WASM own implementation.
|
|
25
25
|
|
|
26
|
-
Names use `public-<category>-<purpose>.yml`, `.<category>-<purpose>.yml`, and `
|
|
26
|
+
Names use `public-<category>-<purpose>.yml`, `.<category>-<purpose>.yml`, and the generated self callers `buildchain.yml` and `buildchain-recover.yml`, with categories `build`, `release`, and `ops`. The primary build API and backbone use `build.yml` and `.build.yml`.
|
|
27
27
|
|
|
28
28
|
Register ownership before adding a workflow. `pnpm run check:workflows` validates source, calls, required CI integration and independent review ownership. `pnpm run generate:workflows` regenerates this catalog.
|
|
29
29
|
|
|
@@ -83,34 +83,5 @@ Register ownership before adding a workflow. `pnpm run check:workflows` validate
|
|
|
83
83
|
|
|
84
84
|
| Workflow | Category | Invocation | Status | Purpose |
|
|
85
85
|
| --- | --- | --- | --- | --- |
|
|
86
|
-
| [
|
|
87
|
-
| [
|
|
88
|
-
| [self-build-binary-distribution.yml](../.github/workflows/self-build-binary-distribution.yml) | build | repository | active | Binary Distribution |
|
|
89
|
-
| [self-build-channel-verify.yml](../.github/workflows/self-build-channel-verify.yml) | build | repository | active | Release - Verify |
|
|
90
|
-
| [self-build-demo-dogfood.yml](../.github/workflows/self-build-demo-dogfood.yml) | build | repository | active | Buildchain Declarative Demo Dogfood |
|
|
91
|
-
| [self-build-demo-media-qualification.yml](../.github/workflows/self-build-demo-media-qualification.yml) | build | repository | active | Auditable Demo Media Profile Qualification |
|
|
92
|
-
| [self-build-fixture.yml](../.github/workflows/self-build-fixture.yml) | build | repository | active | Build Surface Fixture |
|
|
93
|
-
| [self-build-public-consumer-dogfood.yml](../.github/workflows/self-build-public-consumer-dogfood.yml) | build | repository | active | V4 Public Consumer Dogfood |
|
|
94
|
-
| [self-build-stable-candidate-qualification.yml](../.github/workflows/self-build-stable-candidate-qualification.yml) | build | repository | active | Buildchain Stable Candidate Qualification |
|
|
95
|
-
| [self-build-stable-dogfood.yml](../.github/workflows/self-build-stable-dogfood.yml) | build | repository | active | Buildchain Stable Self-Dogfood |
|
|
96
|
-
| [self-build-verify.yml](../.github/workflows/self-build-verify.yml) | build | repository | active | Verify |
|
|
97
|
-
| [self-ops-bootstrap-dogfood.yml](../.github/workflows/self-ops-bootstrap-dogfood.yml) | ops | repository | active | Universal Bootstrap Train-First Self-Dogfood |
|
|
98
|
-
| [self-ops-dev-delivery.yml](../.github/workflows/self-ops-dev-delivery.yml) | ops | repository | active | Buildchain Dev Delivery |
|
|
99
|
-
| [self-ops-governance-audit.yml](../.github/workflows/self-ops-governance-audit.yml) | ops | repository | active | GitHub Governance Authority Audit |
|
|
100
|
-
| [self-ops-housekeeping-daily.yml](../.github/workflows/self-ops-housekeeping-daily.yml) | ops | repository | active | Engineering Housekeeper Daily |
|
|
101
|
-
| [self-ops-housekeeping-monthly.yml](../.github/workflows/self-ops-housekeeping-monthly.yml) | ops | repository | active | Engineering Housekeeper Monthly |
|
|
102
|
-
| [self-ops-housekeeping-weekly.yml](../.github/workflows/self-ops-housekeeping-weekly.yml) | ops | repository | active | Engineering Housekeeper Weekly |
|
|
103
|
-
| [self-ops-merge-queue.yml](../.github/workflows/self-ops-merge-queue.yml) | ops | repository | active | Dev Merge Queue Governance |
|
|
104
|
-
| [self-ops-patrol-daily.yml](../.github/workflows/self-ops-patrol-daily.yml) | ops | repository | active | Buildchain Dogfood Patrol Daily |
|
|
105
|
-
| [self-ops-patrol-monthly.yml](../.github/workflows/self-ops-patrol-monthly.yml) | ops | repository | active | Buildchain Dogfood Patrol Monthly |
|
|
106
|
-
| [self-ops-patrol-weekly.yml](../.github/workflows/self-ops-patrol-weekly.yml) | ops | repository | active | Buildchain Dogfood Patrol Weekly |
|
|
107
|
-
| [self-ops-promotion-recovery.yml](../.github/workflows/self-ops-promotion-recovery.yml) | ops | repository | active | Buildchain Ref Promotion Recovery |
|
|
108
|
-
| [self-ops-runner-smoke.yml](../.github/workflows/self-ops-runner-smoke.yml) | ops | repository | active | Self-hosted Runner Smoke |
|
|
109
|
-
| [self-ops-stable-candidate-patrol.yml](../.github/workflows/self-ops-stable-candidate-patrol.yml) | ops | repository | active | Buildchain Dogfood Stable Candidate Patrol |
|
|
110
|
-
| [self-release-binary-assets.yml](../.github/workflows/self-release-binary-assets.yml) | release | repository | active | Binary Release Assets |
|
|
111
|
-
| [self-release-line-open.yml](../.github/workflows/self-release-line-open.yml) | release | repository | active | Release Line Bootstrap |
|
|
112
|
-
| [self-release-next-development.yml](../.github/workflows/self-release-next-development.yml) | release | repository | active | Next Development Review |
|
|
113
|
-
| [self-release-npm-dry-run.yml](../.github/workflows/self-release-npm-dry-run.yml) | release | repository | active | Publish npm package |
|
|
114
|
-
| [self-release-promote.yml](../.github/workflows/self-release-promote.yml) | release | repository | active | Buildchain Ref Promotion |
|
|
115
|
-
| [self-release-rehearsal-dogfood.yml](../.github/workflows/self-release-rehearsal-dogfood.yml) | release | repository | active | V4 Publication Rehearsal Dogfood |
|
|
116
|
-
| [self-release-tail-dogfood.yml](../.github/workflows/self-release-tail-dogfood.yml) | release | repository | active | V4 Declarative Release Tail Dogfood |
|
|
86
|
+
| [buildchain-recover.yml](../.github/workflows/buildchain-recover.yml) | ops | repository | active | Buildchain recovery |
|
|
87
|
+
| [buildchain.yml](../.github/workflows/buildchain.yml) | ops | repository | active | Buildchain pipeline |
|
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.6",
|
|
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",
|
|
@@ -58,7 +58,10 @@ const WORKFLOW_AND_ACTION_FILES = Object.freeze([
|
|
|
58
58
|
".github/workflows/.build.yml",
|
|
59
59
|
".github/workflows/.release-promote.yml",
|
|
60
60
|
".github/workflows/public-release-promote.yml",
|
|
61
|
-
".github/workflows/
|
|
61
|
+
".github/workflows/buildchain.yml",
|
|
62
|
+
".github/workflows/buildchain-recover.yml",
|
|
63
|
+
".github/workflows/public-ops-pipeline.yml",
|
|
64
|
+
".github/workflows/public-ops-recover.yml",
|
|
62
65
|
".github/workflows/public-release-artifact-attestation.yml",
|
|
63
66
|
"actions/build/artifact/prepare-attestation/action.yml",
|
|
64
67
|
"actions/build/artifact/prepare-attestation/index.js",
|
|
@@ -75,7 +78,6 @@ const EXTRA_KFD1_FILES = Object.freeze([
|
|
|
75
78
|
"packages/core/index.js",
|
|
76
79
|
"packages/core/build/homebrew.js",
|
|
77
80
|
"packages/core/build/build-facts.js",
|
|
78
|
-
"packages/core/adoption/kfd3-surface-register.js",
|
|
79
81
|
"packages/core/release/release-propagation.js",
|
|
80
82
|
"scripts/generate-site-bundle.mjs",
|
|
81
83
|
"packages/core/release/commands/ensure-github-release.mjs",
|
|
@@ -446,7 +448,7 @@ export function createBuildchainKfdSurfaceRegistry({ root = process.cwd() } = {}
|
|
|
446
448
|
{
|
|
447
449
|
name: "Buildchain standalone binary distribution",
|
|
448
450
|
artifactPath: "dist/binary",
|
|
449
|
-
evidencePath: ".github/workflows
|
|
451
|
+
evidencePath: ".github/workflows/.release-pipeline-products.yml",
|
|
450
452
|
distribution: normalizeKfd3DistributionDeclaration({
|
|
451
453
|
registrar: "shifu",
|
|
452
454
|
tasks: ["binary:build"],
|
|
@@ -529,7 +531,6 @@ export function createBuildchainKfdClaimRegistry({ root = process.cwd(), sourceS
|
|
|
529
531
|
|
|
530
532
|
export function createBuildchainKfd1Witness({ root = process.cwd(), sourceSha = "" } = {}) {
|
|
531
533
|
const registry = createBuildchainKfdClaimRegistry({ root, sourceSha });
|
|
532
|
-
const registrySha256 = sha256Json(registry);
|
|
533
534
|
const paths = uniquePaths([
|
|
534
535
|
...publicDocumentationFiles(root),
|
|
535
536
|
...SCHEMA_AND_STANDARD_FILES,
|
|
@@ -545,7 +546,7 @@ export function createBuildchainKfd1Witness({ root = process.cwd(), sourceSha =
|
|
|
545
546
|
contractWorld: {
|
|
546
547
|
id: "buildchain-runtime-contract-world",
|
|
547
548
|
schemaId: "kungfu-buildchain-runtime-contract-world",
|
|
548
|
-
digest: `sha256:${
|
|
549
|
+
digest: `sha256:${sha256Json(registry)}`,
|
|
549
550
|
owner: "Buildchain maintainers",
|
|
550
551
|
selfHosted: true,
|
|
551
552
|
},
|
|
@@ -584,7 +585,6 @@ export function createBuildchainKfd3PrebuildWitness({ root = process.cwd(), sour
|
|
|
584
585
|
const registry = createBuildchainKfdClaimRegistry({ root, sourceSha });
|
|
585
586
|
const surfaces = createBuildchainKfdSurfaceRegistry({ root });
|
|
586
587
|
const reverseAudit = publicSurfaceAuditEvidence(root);
|
|
587
|
-
const digest = `sha256:${sha256Json(registry)}`;
|
|
588
588
|
return {
|
|
589
589
|
schemaVersion: 1,
|
|
590
590
|
id: "buildchain-collaboration-interface",
|
|
@@ -596,7 +596,7 @@ export function createBuildchainKfd3PrebuildWitness({ root = process.cwd(), sour
|
|
|
596
596
|
path: "dist/site/kfd-claims.json",
|
|
597
597
|
sha256: fileExists(root, "dist/site/kfd-claims.json") ? sha256File(root, "dist/site/kfd-claims.json") : "",
|
|
598
598
|
},
|
|
599
|
-
collaborationInterfaceDigest:
|
|
599
|
+
collaborationInterfaceDigest: `sha256:${sha256Json(registry)}`,
|
|
600
600
|
collaborationInterface: {
|
|
601
601
|
schemaVersion: 1,
|
|
602
602
|
contract: BUILDCHAIN_KFD_COLLABORATION_INTERFACE_CONTRACT,
|
|
@@ -207,29 +207,32 @@ export async function runDevDeliveryProviderHeartbeat(
|
|
|
207
207
|
const startedAt = timestamp(now(), "provider heartbeat startedAt");
|
|
208
208
|
let previousStateRoot = initial.stateRoot;
|
|
209
209
|
const heartbeats = [];
|
|
210
|
+
let untilHeartbeat = 0;
|
|
210
211
|
let jobs;
|
|
211
212
|
try {
|
|
212
213
|
while (true) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
214
|
+
if (untilHeartbeat === 0) {
|
|
215
|
+
const result = await heartbeat({
|
|
216
|
+
expectedOldStateRoot: previousStateRoot,
|
|
217
|
+
fencingToken: initial.fencingToken,
|
|
218
|
+
leaseGeneration: initial.generation,
|
|
219
|
+
leaseSeconds: duration,
|
|
220
|
+
});
|
|
221
|
+
const entry = heartbeatEntry(result, previousStateRoot);
|
|
222
|
+
heartbeats.push(entry);
|
|
223
|
+
previousStateRoot = entry.nextStateRoot;
|
|
224
|
+
untilHeartbeat = cadence * 1000;
|
|
225
|
+
}
|
|
222
226
|
jobs = providerJobs(
|
|
223
227
|
await readJobs(),
|
|
224
228
|
{ nativeJobName, sealJobName },
|
|
225
229
|
{ allowMissingSeal: true },
|
|
226
230
|
);
|
|
227
|
-
if (
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
await wait(cadence * 1000);
|
|
231
|
+
if (jobs && terminal(jobs.native) && terminal(jobs.seal)) break;
|
|
232
|
+
// Terminal detection must not wait for the next durable lease renewal.
|
|
233
|
+
const interval = Math.min(untilHeartbeat, 5000);
|
|
234
|
+
await wait(interval);
|
|
235
|
+
untilHeartbeat -= interval;
|
|
233
236
|
}
|
|
234
237
|
} catch (error) {
|
|
235
238
|
await onHeartbeatLoss({
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "./transactions.js";
|
|
7
7
|
import { admitProviderFinalizer } from "./finalizer-admission.js";
|
|
8
8
|
import { guardPipelineAdmission } from "../../workflow/pipeline/guard.js";
|
|
9
|
+
import { replaceNativeActionProcess } from "./process-entry.js";
|
|
9
10
|
function request(core, env) {
|
|
10
11
|
const candidate = JSON.parse(
|
|
11
12
|
core.getInput("request-json", { required: true }),
|
|
@@ -23,6 +24,7 @@ function outputs(core, result) {
|
|
|
23
24
|
core.setOutput(name, value);
|
|
24
25
|
}
|
|
25
26
|
export async function executeDeliveryNativeAction(core, env) {
|
|
27
|
+
replaceNativeActionProcess();
|
|
26
28
|
const context = deliveryActionContext(core, env);
|
|
27
29
|
const input = request(core, env);
|
|
28
30
|
outputs(
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Node Actions receive artifact/OIDC authority even without token inputs.
|
|
2
|
+
// Replace the process before candidate work so the original environment is
|
|
3
|
+
// absent from /proc, memory and ancestry. A scrubbed child would retain it.
|
|
4
|
+
export function replaceNativeActionProcess(host = process) {
|
|
5
|
+
const injected = ["ACTIONS_RUNTIME_TOKEN", "ACTIONS_ID_TOKEN_REQUEST_TOKEN"];
|
|
6
|
+
if (!injected.some((name) => host.env[name])) return;
|
|
7
|
+
if (host.platform !== "linux" || typeof host.execve !== "function") {
|
|
8
|
+
throw new Error("credentialless native action requires Linux execve");
|
|
9
|
+
}
|
|
10
|
+
const environment = { ...host.env };
|
|
11
|
+
for (const name of injected) delete environment[name];
|
|
12
|
+
// Other credential-like variables remain subject to the ancestry guard.
|
|
13
|
+
host.execve(
|
|
14
|
+
host.execPath,
|
|
15
|
+
[host.execPath, ...host.execArgv, ...host.argv.slice(1)],
|
|
16
|
+
environment,
|
|
17
|
+
);
|
|
18
|
+
throw new Error("credentialless native process replacement returned");
|
|
19
|
+
}
|
|
@@ -4,12 +4,29 @@ import { admissionPolicyRequest } from "../admission/request.js";
|
|
|
4
4
|
import { runAdmissionTransaction } from "../admission/transaction.js";
|
|
5
5
|
import { enforceLanding } from "./completion.js";
|
|
6
6
|
import { guardPipelineAdmission } from "../../workflow/pipeline/guard.js";
|
|
7
|
+
import { githubJsonClient } from "../../providers/github/json-client.js";
|
|
8
|
+
import { publishPipelineBuildStatus } from "../../workflow/pipeline/guard-build.js";
|
|
9
|
+
import { publishIntegratedPipelineStatus } from "../../workflow/pipeline/integration-status.js";
|
|
10
|
+
import { githubPipelineIntegration } from "../../providers/github/pipeline-integration.js";
|
|
11
|
+
import { githubPipelineSource } from "../../providers/github/pipeline-source.js";
|
|
12
|
+
import { githubPipelineRuns } from "../../providers/github/pipeline-runs.js";
|
|
13
|
+
import { GitHubClient } from "../admission/github-client.js";
|
|
7
14
|
export async function admitLandingAction(core, env) {
|
|
8
15
|
const context = deliveryActionContext(core, env);
|
|
9
16
|
const request = JSON.parse(core.getInput("request-json", { required: true }));
|
|
10
|
-
await guardPipelineAdmission(request, {
|
|
17
|
+
const admitted = await guardPipelineAdmission(request, {
|
|
11
18
|
repository: env.GITHUB_REPOSITORY,
|
|
12
19
|
token: core.getInput("token", { required: true }),
|
|
20
|
+
publishBuildStatus: (build) =>
|
|
21
|
+
publishPipelineBuildStatus(
|
|
22
|
+
request,
|
|
23
|
+
build,
|
|
24
|
+
githubJsonClient({
|
|
25
|
+
token: core.getInput("status-token", { required: true }),
|
|
26
|
+
userAgent: "buildchain-qualified-status",
|
|
27
|
+
}),
|
|
28
|
+
env.GITHUB_REPOSITORY,
|
|
29
|
+
),
|
|
13
30
|
});
|
|
14
31
|
const result = await runAdmissionTransaction(
|
|
15
32
|
{
|
|
@@ -45,6 +62,37 @@ export async function admitLandingAction(core, env) {
|
|
|
45
62
|
await core.summary.addRaw(result.summary).write();
|
|
46
63
|
if (!result.ok)
|
|
47
64
|
throw new Error("Targeted PR was not admitted at its expected head");
|
|
65
|
+
if (admitted) {
|
|
66
|
+
const repository = env.GITHUB_REPOSITORY;
|
|
67
|
+
const token = core.getInput("token", { required: true });
|
|
68
|
+
const read = githubJsonClient({
|
|
69
|
+
token,
|
|
70
|
+
userAgent: "buildchain-integration-status",
|
|
71
|
+
});
|
|
72
|
+
const [owner, repo] = repository.split("/");
|
|
73
|
+
const queue = new GitHubClient({ repository: { owner, repo }, token });
|
|
74
|
+
await publishIntegratedPipelineStatus(
|
|
75
|
+
{
|
|
76
|
+
...admitted.history.at(-1),
|
|
77
|
+
intent: admitted.intent,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
repository,
|
|
81
|
+
request: read,
|
|
82
|
+
queue: (branch) => queue.getMergeQueueState(branch),
|
|
83
|
+
integration: githubPipelineIntegration(
|
|
84
|
+
read,
|
|
85
|
+
repository,
|
|
86
|
+
githubPipelineSource(read, repository),
|
|
87
|
+
githubPipelineRuns(read, repository),
|
|
88
|
+
),
|
|
89
|
+
status: githubJsonClient({
|
|
90
|
+
token: core.getInput("status-token", { required: true }),
|
|
91
|
+
userAgent: "buildchain-qualified-integration-status",
|
|
92
|
+
}),
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
}
|
|
48
96
|
}
|
|
49
97
|
export function completeDeliveryAction(core) {
|
|
50
98
|
enforceLanding({
|
|
@@ -11,13 +11,15 @@ export function verifyFailureSettlement(result, settlement, stateRoot) {
|
|
|
11
11
|
result.receipt.evidenceRoot === settlement.evidenceRoot,
|
|
12
12
|
"Failure settlement receipt does not bind its exact evidence and prior state",
|
|
13
13
|
);
|
|
14
|
-
const candidate = result.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
const candidate = result.terminalCandidate;
|
|
15
|
+
requireValue(
|
|
16
|
+
candidate?.candidateId === result.receipt.candidateId &&
|
|
17
|
+
candidate?.pullRequestNumber === settlement.pullRequestNumber &&
|
|
18
|
+
candidate?.sourceHead === settlement.sourceHead &&
|
|
19
|
+
candidate?.status === "terminal-failure" &&
|
|
20
|
+
candidate?.terminal?.evidenceRoot === settlement.evidenceRoot,
|
|
21
|
+
"Failure settlement terminal candidate is missing",
|
|
19
22
|
);
|
|
20
|
-
requireValue(candidate, "Failure settlement terminal candidate is missing");
|
|
21
23
|
for (const key of [
|
|
22
24
|
"transferRoot",
|
|
23
25
|
"finalizerBoundaryRoot",
|
|
@@ -104,6 +104,13 @@ export async function runDevDeliveryCommand(optionsInput = {}, clientInput) {
|
|
|
104
104
|
concurrencyRecovery,
|
|
105
105
|
receipt: persisted.changed.receipt,
|
|
106
106
|
receiptRoot: persisted.changed.receiptRoot,
|
|
107
|
+
terminalCandidate:
|
|
108
|
+
options.command === "settle"
|
|
109
|
+
? persisted.changed.queue.candidates.find(
|
|
110
|
+
(candidate) =>
|
|
111
|
+
candidate.candidateId === persisted.changed.receipt.candidateId,
|
|
112
|
+
) || null
|
|
113
|
+
: null,
|
|
107
114
|
warrant:
|
|
108
115
|
persisted.changed.warrant ||
|
|
109
116
|
persisted.changed.queue.activeWarrant ||
|
|
@@ -4,6 +4,8 @@ import path from "node:path";
|
|
|
4
4
|
import { createPublicationAuthorityRegistry } from "../publication/publication-authority.js";
|
|
5
5
|
|
|
6
6
|
const DESCRIPTORS = Object.freeze([
|
|
7
|
+
[".github/workflows/buildchain.yml", "product-publication", true, ["npm-publish", "github-release", "channel-ref"], "trusted-publishing", "none", "fixed", "fixed", ".github/workflows/.release-pipeline-products.yml"],
|
|
8
|
+
[".github/workflows/buildchain-recover.yml", "product-publication", true, ["npm-publish", "github-release", "channel-ref"], "trusted-publishing", "none", "fixed", "fixed", ".github/workflows/.release-pipeline-products.yml"],
|
|
7
9
|
[".github/workflows/public-release-oci-compose-preview.yml", "product-publication", true, ["oci-compose-preview"], "caller-secrets", "none", "fixed", "caller-bound"],
|
|
8
10
|
[".github/workflows/.build-demo-adapter.yml", "non-publication-oidc"],
|
|
9
11
|
[".github/workflows/public-build-demo.yml", "governance-write"],
|
|
@@ -16,28 +18,14 @@ const DESCRIPTORS = Object.freeze([
|
|
|
16
18
|
[".github/workflows/public-release-web.yml", "product-publication", true, ["web-production"], "oidc", "consumer-defined", "caller-bound", "caller-bound"],
|
|
17
19
|
[".github/workflows/.build-wheel-verify-compat.yml", "retired-deny"],
|
|
18
20
|
[".github/workflows/.release-binary-assets.yml", "product-publication", true, ["github-release"], "github-token", "buildchain-release-assets"],
|
|
19
|
-
[".github/workflows/self-build-binary-distribution.yml", "evidence-publication"],
|
|
20
|
-
[".github/workflows/self-release-binary-assets.yml", "governance-write"],
|
|
21
21
|
[".github/workflows/public-release-signing-authority.yml", "evidence-publication"],
|
|
22
|
-
[".github/workflows/self-build-demo-dogfood.yml", "governance-write"],
|
|
23
|
-
[".github/workflows/self-build-fixture.yml", "non-publication-oidc"],
|
|
24
22
|
[".github/workflows/build.yml", "non-publication-oidc"],
|
|
25
23
|
[".github/workflows/public-ops-bootstrap.yml", "product-publication", true, ["universal-candidate-execution"], "caller-secrets", "none", "fixed", "caller-bound"],
|
|
26
|
-
[".github/workflows/self-build-alpha-dogfood.yml", "non-publication-oidc"],
|
|
27
|
-
[".github/workflows/self-build-stable-dogfood.yml", "non-publication-oidc"],
|
|
28
|
-
[".github/workflows/self-ops-dev-delivery.yml", "governance-write"],
|
|
29
|
-
[".github/workflows/self-ops-patrol-daily.yml", "governance-write"],
|
|
30
|
-
[".github/workflows/self-ops-patrol-monthly.yml", "governance-write"],
|
|
31
|
-
[".github/workflows/self-ops-patrol-weekly.yml", "governance-write"],
|
|
32
24
|
[".github/workflows/public-ops-patrol.yml", "governance-write"],
|
|
33
|
-
[".github/workflows/self-ops-promotion-recovery.yml", "governance-write"],
|
|
34
|
-
[".github/workflows/self-release-promote.yml", "governance-write"],
|
|
35
|
-
[".github/workflows/self-ops-stable-candidate-patrol.yml", "governance-write"],
|
|
36
25
|
[".github/workflows/public-ops-dev-qualification-patrol.yml", "governance-write"],
|
|
37
26
|
[".github/workflows/public-ops-alpha-candidate-patrol.yml", "governance-write"],
|
|
38
27
|
[".github/workflows/public-ops-warrant-close.yml", "governance-write"],
|
|
39
28
|
[".github/workflows/public-ops-warrant-cancel.yml", "governance-write"],
|
|
40
|
-
[".github/workflows/self-ops-merge-queue.yml", "governance-write"],
|
|
41
29
|
[".github/workflows/public-ops-dev-auto-merge.yml", "governance-write"],
|
|
42
30
|
[".github/workflows/public-ops-pipeline.yml", "product-publication", true, ["npm-publish", "github-release", "channel-ref"], "trusted-publishing", "none", "fixed", "fixed", ".github/workflows/.release-pipeline-products.yml"],
|
|
43
31
|
[".github/workflows/public-ops-recover.yml", "product-publication", true, ["npm-publish", "github-release", "channel-ref"], "trusted-publishing", "none", "fixed", "fixed", ".github/workflows/.release-pipeline-products.yml"],
|
|
@@ -45,13 +33,8 @@ const DESCRIPTORS = Object.freeze([
|
|
|
45
33
|
[".github/workflows/.release-pipeline-products.yml", "product-publication", true, ["npm-publish", "github-release", "channel-ref"], "trusted-publishing", "none", "fixed", "fixed"],
|
|
46
34
|
[".github/workflows/.release-pipeline-version.yml", "governance-write"],
|
|
47
35
|
[".github/workflows/.ops-pipeline-delivery.yml", "governance-write"],
|
|
48
|
-
[".github/workflows/self-ops-housekeeping-daily.yml", "governance-write"],
|
|
49
|
-
[".github/workflows/self-ops-housekeeping-monthly.yml", "governance-write"],
|
|
50
|
-
[".github/workflows/self-ops-housekeeping-weekly.yml", "governance-write"],
|
|
51
36
|
[".github/workflows/public-ops-housekeeping.yml", "governance-write"],
|
|
52
|
-
[".github/workflows/self-ops-governance-audit.yml", "governance-write"],
|
|
53
37
|
[".github/workflows/public-release-artifact-attestation.yml", "evidence-publication", true, ["github-artifact-attestation"], "oidc", "consumer-defined", "caller-bound", "caller-bound"],
|
|
54
|
-
[".github/workflows/self-release-npm-dry-run.yml", "dry-run-only"],
|
|
55
38
|
[".github/workflows/public-release-paper.yml", "product-publication", true, ["npm-publish", "github-release"], "trusted-publishing", "none", "fixed", "caller-bound"],
|
|
56
39
|
[".github/workflows/public-ops-patrol-daily.yml", "governance-write"],
|
|
57
40
|
[".github/workflows/public-ops-patrol-monthly.yml", "governance-write"],
|
|
@@ -59,13 +42,9 @@ const DESCRIPTORS = Object.freeze([
|
|
|
59
42
|
[".github/workflows/public-ops-patrol-weekly.yml", "governance-write"],
|
|
60
43
|
[".github/workflows/public-build-publication.yml", "evidence-publication"],
|
|
61
44
|
[".github/workflows/public-release-promote.yml", "product-publication", true, ["npm-publish", "github-release", "channel-ref"], "trusted-publishing", "none", "fixed", "caller-bound"],
|
|
62
|
-
[".github/workflows/self-release-line-open.yml", "governance-write"],
|
|
63
45
|
[".github/workflows/public-release-propagation.yml", "governance-write"],
|
|
64
46
|
[".github/workflows/public-release-tail.yml", "product-publication", true, ["artifact.publish", "signed-channel.commit", "release.activate", "released-evidence.synthesize"], "caller-secrets", "caller-bound", "caller-bound", "fixed"],
|
|
65
|
-
[".github/workflows/self-build-release-verify-compat.yml", "governance-write"],
|
|
66
47
|
[".github/workflows/public-ops-stable-candidate-patrol.yml", "governance-write"],
|
|
67
|
-
[".github/workflows/self-ops-bootstrap-dogfood.yml", "product-publication", true, ["universal-candidate-execution"], "caller-secrets", "none", "fixed", "caller-bound"],
|
|
68
|
-
[".github/workflows/self-release-tail-dogfood.yml", "product-publication", true, ["artifact.publish", "signed-channel.commit", "release.activate", "released-evidence.synthesize"], "caller-secrets", "none", "fixed", "fixed"],
|
|
69
48
|
]);
|
|
70
49
|
|
|
71
50
|
export function buildchainPublicationAuthorityDescriptors({ root = process.cwd() } = {}) {
|
|
@@ -1257,6 +1257,7 @@ export function createGithubRulesetGovernanceRolloutPlan({
|
|
|
1257
1257
|
dismiss_stale_reviews_on_push: true,
|
|
1258
1258
|
require_code_owner_review: true,
|
|
1259
1259
|
require_last_push_approval: true,
|
|
1260
|
+
require_extra_approval_for_unattributed_changes: true,
|
|
1260
1261
|
required_approving_review_count: requiredApprovals,
|
|
1261
1262
|
required_review_thread_resolution: true,
|
|
1262
1263
|
},
|
|
@@ -124,14 +124,6 @@ const CONTROLLER_SPECS = [
|
|
|
124
124
|
],
|
|
125
125
|
evidence: ["propagation-plan", "propagation-lock", "controller-receipt"],
|
|
126
126
|
},
|
|
127
|
-
{
|
|
128
|
-
id: "binary-distribution",
|
|
129
|
-
workflowId: "binary-distribution",
|
|
130
|
-
version: 1,
|
|
131
|
-
capabilities: ["standalone-binary-build", "release-evidence-bundle", "artifact-admission"],
|
|
132
|
-
stages: ["resolve-runtime", "build", "verify", "bundle", "aggregate"],
|
|
133
|
-
evidence: ["release-evidence-bundle", "release-passport", "controller-receipt"],
|
|
134
|
-
},
|
|
135
127
|
];
|
|
136
128
|
|
|
137
129
|
function stableJson(value) {
|
|
@@ -167,8 +167,15 @@ export async function pipelineEntryCheck(run, host) {
|
|
|
167
167
|
|
|
168
168
|
function exactCheck(checks, run, repository) {
|
|
169
169
|
const url = `https://github.com/${repository}/actions/runs/${run.id}/attempts/${run.run_attempt}`;
|
|
170
|
+
// Actions may replace details_url with the check's own provider URL. Its
|
|
171
|
+
// exact external execution identity still binds the original native receipt.
|
|
170
172
|
const matches = checks.filter(
|
|
171
|
-
(check) =>
|
|
173
|
+
(check) =>
|
|
174
|
+
check.name === "check" &&
|
|
175
|
+
(check.details_url === url ||
|
|
176
|
+
(check.details_url ===
|
|
177
|
+
`https://github.com/${repository}/runs/${check.id}` &&
|
|
178
|
+
check.external_id?.endsWith(`:${run.id}:${run.run_attempt}`))),
|
|
172
179
|
);
|
|
173
180
|
if (!matches.length) return null;
|
|
174
181
|
const values = matches.map((check) => {
|