@kungfu-tech/buildchain 4.0.2-alpha.37 → 4.0.2-alpha.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/architecture/agent-change-map.md +2 -2
- package/architecture/internal-capabilities.json +2 -2
- package/architecture/maintainability-debt.json +3 -3
- package/architecture/maintainability-policy.json +3 -3
- package/architecture/v4-cross-platform-adopter-qualification.json +1 -1
- package/architecture/v4-floating-consumer-policy.json +1 -1
- package/architecture/v4-next-development-parity.json +2 -2
- package/architecture/v4-release-topology.json +0 -1
- package/architecture/v4-stage-capsule-qualification.json +1 -1
- package/architecture/v4-tail-reseal-parity.json +8 -6
- package/architecture/v4-universal-workflow-train-admission.json +1 -1
- package/architecture/workflow-taxonomy.json +18 -15
- package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
- package/dist/site/buildchain-contract.json +4 -4
- package/dist/site/buildchain-site.json +58 -17
- package/dist/site/capability-registry.json +2 -2
- package/dist/site/kfd-claims.json +19 -73
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +2 -2
- package/dist/site/node-api-registry.json +1 -1
- package/dist/site/page-registry.json +52 -11
- package/dist/site/public-surface-audit.json +8 -67
- package/dist/site/publication-authority-registry.json +1 -16
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +6 -6
- package/dist/site/workflow-registry.json +5 -125
- package/docs/next-development-transition.md +1 -1
- package/docs/v4-adopter-delivery.md +1 -1
- package/docs/v4-stage-capsule.md +1 -1
- package/docs/v4-tail-reseal.md +1 -1
- package/docs/workflow-catalog.md +5 -3
- package/docs/workflow-path-migration.md +109 -0
- package/package.json +1 -1
- package/packages/core/next-development-projection.js +1 -1
- package/scripts/check-v4-floating-consumer-policy-contract.mjs +1 -1
- package/scripts/check-v4-public-dogfood-contract.mjs +4 -4
- package/scripts/check-v4-universal-workflow-bootstrap.mjs +3 -3
- package/scripts/generate-v4-universal-workflow-facades.mjs +4 -3
- package/scripts/v4-universal-workflow-engine.mjs +2 -1
- package/scripts/workflow-taxonomy.mjs +50 -11
|
@@ -2746,7 +2746,7 @@
|
|
|
2746
2746
|
"status": "preview",
|
|
2747
2747
|
"owner": "buildchain-workflows",
|
|
2748
2748
|
"maturity": "preview",
|
|
2749
|
-
"introducedVersion": "4.0.2-alpha.
|
|
2749
|
+
"introducedVersion": "4.0.2-alpha.38",
|
|
2750
2750
|
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
2751
2751
|
"deprecationReplacement": "",
|
|
2752
2752
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
@@ -3943,7 +3943,7 @@
|
|
|
3943
3943
|
"status": "preview",
|
|
3944
3944
|
"owner": "buildchain-workflows",
|
|
3945
3945
|
"maturity": "preview",
|
|
3946
|
-
"introducedVersion": "4.0.2-alpha.
|
|
3946
|
+
"introducedVersion": "4.0.2-alpha.38",
|
|
3947
3947
|
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
3948
3948
|
"deprecationReplacement": "",
|
|
3949
3949
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
@@ -5970,7 +5970,7 @@
|
|
|
5970
5970
|
"status": "preview",
|
|
5971
5971
|
"owner": "buildchain-workflows",
|
|
5972
5972
|
"maturity": "preview",
|
|
5973
|
-
"introducedVersion": "4.0.2-alpha.
|
|
5973
|
+
"introducedVersion": "4.0.2-alpha.38",
|
|
5974
5974
|
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
5975
5975
|
"deprecationReplacement": "",
|
|
5976
5976
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
@@ -6001,7 +6001,7 @@
|
|
|
6001
6001
|
"status": "preview",
|
|
6002
6002
|
"owner": "buildchain-workflows",
|
|
6003
6003
|
"maturity": "preview",
|
|
6004
|
-
"introducedVersion": "4.0.2-alpha.
|
|
6004
|
+
"introducedVersion": "4.0.2-alpha.38",
|
|
6005
6005
|
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
6006
6006
|
"deprecationReplacement": "",
|
|
6007
6007
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
@@ -6032,7 +6032,7 @@
|
|
|
6032
6032
|
"status": "preview",
|
|
6033
6033
|
"owner": "buildchain-workflows",
|
|
6034
6034
|
"maturity": "preview",
|
|
6035
|
-
"introducedVersion": "4.0.2-alpha.
|
|
6035
|
+
"introducedVersion": "4.0.2-alpha.38",
|
|
6036
6036
|
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
6037
6037
|
"deprecationReplacement": "",
|
|
6038
6038
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
@@ -6628,126 +6628,6 @@
|
|
|
6628
6628
|
"deprecationReplacement": "",
|
|
6629
6629
|
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
6630
6630
|
"nonDuplicationRationale": "Existing workflow identity retained for caller compatibility and repository orchestration."
|
|
6631
|
-
},
|
|
6632
|
-
{
|
|
6633
|
-
"id": "v4-adopter-delivery",
|
|
6634
|
-
"path": ".github/workflows/v4-adopter-delivery.yml",
|
|
6635
|
-
"reusable": true,
|
|
6636
|
-
"inputs": [
|
|
6637
|
-
"archive-path",
|
|
6638
|
-
"bootstrap-path",
|
|
6639
|
-
"consumer",
|
|
6640
|
-
"consumer-ref",
|
|
6641
|
-
"consumer-repository",
|
|
6642
|
-
"input-path",
|
|
6643
|
-
"invocation-source-path",
|
|
6644
|
-
"node-version",
|
|
6645
|
-
"universal-request-json"
|
|
6646
|
-
],
|
|
6647
|
-
"inputCount": 9,
|
|
6648
|
-
"secrets": [],
|
|
6649
|
-
"secretCount": 0,
|
|
6650
|
-
"outputs": [],
|
|
6651
|
-
"outputCount": 0,
|
|
6652
|
-
"taxonomy": {
|
|
6653
|
-
"id": "v4-adopter-delivery",
|
|
6654
|
-
"role": "public",
|
|
6655
|
-
"category": "build",
|
|
6656
|
-
"purpose": "adopter-qualification",
|
|
6657
|
-
"status": "active",
|
|
6658
|
-
"canonicalPath": ".github/workflows/public-build-adopter-qualification.yml",
|
|
6659
|
-
"compatibilityAlias": true
|
|
6660
|
-
},
|
|
6661
|
-
"surface": "repository-workflow",
|
|
6662
|
-
"capabilityGroup": "api-cli-reference",
|
|
6663
|
-
"status": "active",
|
|
6664
|
-
"owner": "buildchain-workflows",
|
|
6665
|
-
"maturity": "active",
|
|
6666
|
-
"introducedVersion": "pre-3.0.2-alpha.4",
|
|
6667
|
-
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
6668
|
-
"deprecationReplacement": "",
|
|
6669
|
-
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
6670
|
-
"nonDuplicationRationale": "Existing workflow identity retained for caller compatibility and repository orchestration."
|
|
6671
|
-
},
|
|
6672
|
-
{
|
|
6673
|
-
"id": "v4-stage-capsule-canary",
|
|
6674
|
-
"path": ".github/workflows/v4-stage-capsule-canary.yml",
|
|
6675
|
-
"reusable": true,
|
|
6676
|
-
"inputs": [
|
|
6677
|
-
"build-artifact-path",
|
|
6678
|
-
"consumer",
|
|
6679
|
-
"go-version",
|
|
6680
|
-
"install-artifact-path",
|
|
6681
|
-
"node-version",
|
|
6682
|
-
"universal-request-json",
|
|
6683
|
-
"verify-artifact-path"
|
|
6684
|
-
],
|
|
6685
|
-
"inputCount": 7,
|
|
6686
|
-
"secrets": [],
|
|
6687
|
-
"secretCount": 0,
|
|
6688
|
-
"outputs": [],
|
|
6689
|
-
"outputCount": 0,
|
|
6690
|
-
"taxonomy": {
|
|
6691
|
-
"id": "v4-stage-capsule-canary",
|
|
6692
|
-
"role": "public",
|
|
6693
|
-
"category": "build",
|
|
6694
|
-
"purpose": "stage-capsule-canary",
|
|
6695
|
-
"status": "active",
|
|
6696
|
-
"canonicalPath": ".github/workflows/public-build-stage-capsule-canary.yml",
|
|
6697
|
-
"compatibilityAlias": true
|
|
6698
|
-
},
|
|
6699
|
-
"surface": "repository-workflow",
|
|
6700
|
-
"capabilityGroup": "api-cli-reference",
|
|
6701
|
-
"status": "active",
|
|
6702
|
-
"owner": "buildchain-workflows",
|
|
6703
|
-
"maturity": "active",
|
|
6704
|
-
"introducedVersion": "pre-3.0.2-alpha.4",
|
|
6705
|
-
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
6706
|
-
"deprecationReplacement": "",
|
|
6707
|
-
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
6708
|
-
"nonDuplicationRationale": "Existing workflow identity retained for caller compatibility and repository orchestration."
|
|
6709
|
-
},
|
|
6710
|
-
{
|
|
6711
|
-
"id": "v4-tail-reseal",
|
|
6712
|
-
"path": ".github/workflows/v4-tail-reseal.yml",
|
|
6713
|
-
"reusable": true,
|
|
6714
|
-
"inputs": [
|
|
6715
|
-
"artifact-retention-days",
|
|
6716
|
-
"consumer-policy-receipt-json",
|
|
6717
|
-
"macos-finalization-command",
|
|
6718
|
-
"request-json",
|
|
6719
|
-
"universal-request-json"
|
|
6720
|
-
],
|
|
6721
|
-
"inputCount": 5,
|
|
6722
|
-
"secrets": [
|
|
6723
|
-
"BUILDCHAIN_EVIDENCE_READ_TOKEN",
|
|
6724
|
-
"BUILDCHAIN_SIGNING_TOKEN"
|
|
6725
|
-
],
|
|
6726
|
-
"secretCount": 2,
|
|
6727
|
-
"outputs": [
|
|
6728
|
-
"release-candidate-passport-json",
|
|
6729
|
-
"tail-reseal-receipt-root"
|
|
6730
|
-
],
|
|
6731
|
-
"outputCount": 2,
|
|
6732
|
-
"taxonomy": {
|
|
6733
|
-
"id": "v4-tail-reseal",
|
|
6734
|
-
"role": "public",
|
|
6735
|
-
"category": "ops",
|
|
6736
|
-
"purpose": "tail-reseal",
|
|
6737
|
-
"status": "active",
|
|
6738
|
-
"canonicalPath": ".github/workflows/public-ops-tail-reseal.yml",
|
|
6739
|
-
"compatibilityAlias": true
|
|
6740
|
-
},
|
|
6741
|
-
"surface": "repository-workflow",
|
|
6742
|
-
"capabilityGroup": "api-cli-reference",
|
|
6743
|
-
"status": "active",
|
|
6744
|
-
"owner": "buildchain-workflows",
|
|
6745
|
-
"maturity": "active",
|
|
6746
|
-
"introducedVersion": "pre-3.0.2-alpha.4",
|
|
6747
|
-
"compatibilityPromise": "preserved-through-the-v3-major-line",
|
|
6748
|
-
"deprecationReplacement": "",
|
|
6749
|
-
"sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
|
|
6750
|
-
"nonDuplicationRationale": "Existing workflow identity retained for caller compatibility and repository orchestration."
|
|
6751
6631
|
}
|
|
6752
6632
|
],
|
|
6753
6633
|
"actionSource": "actions/*/action.yml reverse input enumeration",
|
|
@@ -77,7 +77,7 @@ invalid.
|
|
|
77
77
|
## Public self-dogfood and adoption
|
|
78
78
|
|
|
79
79
|
`.github/workflows/self-build-public-consumer-dogfood.yml` remains the exact thin
|
|
80
|
-
consumer of the public `
|
|
80
|
+
consumer of the public `public-build-stage-capsule-canary.yml@v4-alpha` contract. Its
|
|
81
81
|
declared `lifecycle.verify` runs `pnpm run check`, so the same public path
|
|
82
82
|
executes pure recovery tests that inject a transient durable-state write
|
|
83
83
|
failure, restore the adapter operation on a fresh runner, supersede stale work
|
|
@@ -110,7 +110,7 @@ artifact_profile_selector = "package"
|
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
The public reusable workflow is
|
|
113
|
-
`kungfu-systems/buildchain/.github/workflows/
|
|
113
|
+
`kungfu-systems/buildchain/.github/workflows/public-build-adopter-qualification.yml@v4` for
|
|
114
114
|
stable use and `@v4-alpha` during prerelease evaluation. It resolves the exact
|
|
115
115
|
called-workflow SHA, enforces floating selector plus dual-lock consumer
|
|
116
116
|
admission, and runs the same CLI on Linux, macOS, and Windows. Buildchain
|
package/docs/v4-stage-capsule.md
CHANGED
|
@@ -136,7 +136,7 @@ shadow-only: it does not skip a v3 production stage or move v3 authority.
|
|
|
136
136
|
`architecture/v4-stage-capsule-qualification.json` closes the Wave 2
|
|
137
137
|
qualification boundary. Buildchain and external repositories use the same
|
|
138
138
|
Buildchain-owned public reusable workflow,
|
|
139
|
-
`.github/workflows/
|
|
139
|
+
`.github/workflows/public-build-stage-capsule-canary.yml`. Buildchain's caller is the thin
|
|
140
140
|
`.github/workflows/self-build-public-consumer-dogfood.yml`; it has no steps, copied
|
|
141
141
|
orchestration, local action, direct qualification invocation, or private
|
|
142
142
|
consumer profile. Candidate recursion is resolved only by publishing the exact
|
package/docs/v4-tail-reseal.md
CHANGED
|
@@ -56,7 +56,7 @@ receipt creation and verification.
|
|
|
56
56
|
## Reusable workflow
|
|
57
57
|
|
|
58
58
|
Consumers invoke
|
|
59
|
-
`kungfu-systems/buildchain/.github/workflows/
|
|
59
|
+
`kungfu-systems/buildchain/.github/workflows/public-ops-tail-reseal.yml@v4-alpha` from a
|
|
60
60
|
trusted, same-repository workflow. The caller supplies the rooted request, the
|
|
61
61
|
original candidate consumer-policy receipt, a reviewed macOS finalization
|
|
62
62
|
command, and the explicitly named signing secret. The command must write:
|
package/docs/workflow-catalog.md
CHANGED
|
@@ -56,6 +56,8 @@ must explain its scope in review. New aliases cannot be invented: compatibility
|
|
|
56
56
|
must name an exact migration source with a reason and removal condition.
|
|
57
57
|
The policy, generator, checker, tests, required CI chain and CODEOWNERS require
|
|
58
58
|
independent `kungfu-origin` review. No wildcard compatibility admission is allowed.
|
|
59
|
+
Workflow filenames cannot contain version tokens such as `v4` or `v5`.
|
|
60
|
+
Retired aliases cannot be recreated or called; see [path migration](workflow-path-migration.md).
|
|
59
61
|
|
|
60
62
|
A role, category or implementation edit must preserve or deliberately update
|
|
61
63
|
all related declarations. Run `pnpm run generate:workflows` and
|
|
@@ -65,12 +67,12 @@ all related declarations. Run `pnpm run generate:workflows` and
|
|
|
65
67
|
|
|
66
68
|
| Canonical workflow | Category | Invocation | Status | Purpose | Compatibility path |
|
|
67
69
|
| --- | --- | --- | --- | --- | --- |
|
|
68
|
-
| [public-build-adopter-qualification.yml](../.github/workflows/public-build-adopter-qualification.yml) | build | reusable | active | V4 Adopter Delivery |
|
|
70
|
+
| [public-build-adopter-qualification.yml](../.github/workflows/public-build-adopter-qualification.yml) | build | reusable | active | V4 Adopter Delivery | — |
|
|
69
71
|
| [public-build-candidate.yml](../.github/workflows/public-build-candidate.yml) | build | reusable | active | Buildchain Channel Build | `build.yml` |
|
|
70
72
|
| [public-build-check.yml](../.github/workflows/public-build-check.yml) | build | reusable | active | Buildchain Check | `check.yml` |
|
|
71
73
|
| [public-build-demo.yml](../.github/workflows/public-build-demo.yml) | build | reusable | active | Buildchain Declarative Binary Auditable Demo | `.declarative-auditable-demo.yml` |
|
|
72
74
|
| [public-build-publication.yml](../.github/workflows/public-build-publication.yml) | build | reusable | active | Buildchain Publication Artifact | `publication-artifact.yml` |
|
|
73
|
-
| [public-build-stage-capsule-canary.yml](../.github/workflows/public-build-stage-capsule-canary.yml) | build | reusable | active | V4 Stage Capsule Canary |
|
|
75
|
+
| [public-build-stage-capsule-canary.yml](../.github/workflows/public-build-stage-capsule-canary.yml) | build | reusable | active | V4 Stage Capsule Canary | — |
|
|
74
76
|
| [public-ops-alpha-candidate-patrol.yml](../.github/workflows/public-ops-alpha-candidate-patrol.yml) | ops | reusable | active | Buildchain Dev to Alpha Candidate Patrol | `dev-alpha-candidate-patrol.yml` |
|
|
75
77
|
| [public-ops-bootstrap-recovery.yml](../.github/workflows/public-ops-bootstrap-recovery.yml) | ops | reusable | active | Universal Buildchain Bootstrap Recovery | `universal-bootstrap-recovery.yml` |
|
|
76
78
|
| [public-ops-bootstrap.yml](../.github/workflows/public-ops-bootstrap.yml) | ops | reusable | active | Buildchain Universal Bootstrap | `bootstrap.yml` |
|
|
@@ -84,7 +86,7 @@ all related declarations. Run `pnpm run generate:workflows` and
|
|
|
84
86
|
| [public-ops-patrol.yml](../.github/workflows/public-ops-patrol.yml) | ops | reusable | active | Buildchain Patrol | `buildchain-patrol.yml` |
|
|
85
87
|
| [public-ops-release-governance.yml](../.github/workflows/public-ops-release-governance.yml) | ops | reusable | active | Release Governance Reconcile | `release-governance-reconcile.yml` |
|
|
86
88
|
| [public-ops-stable-candidate-patrol.yml](../.github/workflows/public-ops-stable-candidate-patrol.yml) | ops | reusable | active | Buildchain Stable Candidate Patrol | `stable-candidate-patrol.yml` |
|
|
87
|
-
| [public-ops-tail-reseal.yml](../.github/workflows/public-ops-tail-reseal.yml) | ops | reusable | active | V4 Retained Candidate Tail Reseal |
|
|
89
|
+
| [public-ops-tail-reseal.yml](../.github/workflows/public-ops-tail-reseal.yml) | ops | reusable | active | V4 Retained Candidate Tail Reseal | — |
|
|
88
90
|
| [public-ops-warrant-cancel.yml](../.github/workflows/public-ops-warrant-cancel.yml) | ops | reusable | active | Dev Delivery Warrant Queued Candidate Cancel | `dev-delivery-warrant-cancel.yml` |
|
|
89
91
|
| [public-ops-warrant-close.yml](../.github/workflows/public-ops-warrant-close.yml) | ops | reusable | active | Dev Delivery Warrant Close | `dev-delivery-warrant-close.yml` |
|
|
90
92
|
| [public-release-artifact-attestation.yml](../.github/workflows/public-release-artifact-attestation.yml) | release | reusable | active | Buildchain GitHub Artifact Attestation | `github-artifact-attestation.yml` |
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: draft
|
|
3
|
+
period: ongoing
|
|
4
|
+
theme: workflow-path-migration
|
|
5
|
+
doc_type: migration-guide
|
|
6
|
+
source_level: local-files
|
|
7
|
+
confidence: high
|
|
8
|
+
sensitivity: public
|
|
9
|
+
evidence_grade: B
|
|
10
|
+
review_state: unreviewed
|
|
11
|
+
last_reviewed: 2026-09-06
|
|
12
|
+
ai_provenance:
|
|
13
|
+
model_family: GPT-6
|
|
14
|
+
product: Codex
|
|
15
|
+
generated_at: 2026-09-05
|
|
16
|
+
visible_context: Exact GitHub channel refs and workflow files on 23 organization default branches
|
|
17
|
+
invisible_context_boundary: Other branches, private or unlisted consumers and future floating ref updates were not established by this audit
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Version-prefixed workflow path migration
|
|
21
|
+
|
|
22
|
+
This source change retires three filenames. Their reusable capabilities, inputs,
|
|
23
|
+
outputs, jobs and permission envelopes remain at the canonical paths below.
|
|
24
|
+
Keep the existing channel selector and dual contract-lock policy when migrating.
|
|
25
|
+
|
|
26
|
+
| Retired path | Canonical path |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| `v4-adopter-delivery.yml` | `public-build-adopter-qualification.yml` |
|
|
29
|
+
| `v4-stage-capsule-canary.yml` | `public-build-stage-capsule-canary.yml` |
|
|
30
|
+
| `v4-tail-reseal.yml` | `public-ops-tail-reseal.yml` |
|
|
31
|
+
|
|
32
|
+
All paths are beneath `.github/workflows/`. The taxonomy gate rejects version
|
|
33
|
+
segments in filenames and calls to version-prefixed Buildchain workflows. An
|
|
34
|
+
explicit retirement record keeps the original migration identity for historical
|
|
35
|
+
metrics and frozen facade source; generators resolve that identity to the
|
|
36
|
+
canonical implementation and cannot recreate the removed file.
|
|
37
|
+
|
|
38
|
+
## Development merge and channel rollout
|
|
39
|
+
|
|
40
|
+
The development change retires these filenames on `dev/v4/v4.0`, updates the
|
|
41
|
+
Buildchain-owned callers, and enforces the canonical paths through generators
|
|
42
|
+
and required checks. Its delivery boundary is the protected development merge.
|
|
43
|
+
External-repository migration and stable publication are separate follow-up
|
|
44
|
+
work and do not block this development merge.
|
|
45
|
+
|
|
46
|
+
The published channel boundary still requires the following rollout order:
|
|
47
|
+
|
|
48
|
+
1. Publish and verify the canonical entries on every affected channel while the
|
|
49
|
+
old entries remain available. The admission identity must match the actual
|
|
50
|
+
invoked canonical workflow, rather than its previous filename.
|
|
51
|
+
2. Migrate consumers on their existing floating channels, refresh locks through
|
|
52
|
+
the supported contract acceptance path if required, and verify real consumer
|
|
53
|
+
runs. Stable callers remain on stable; alpha callers remain on alpha.
|
|
54
|
+
3. Before publishing the retirement into a channel, recheck its live consumers
|
|
55
|
+
and resolve any remaining old-path calls. A protected development merge does
|
|
56
|
+
not by itself establish this channel readiness.
|
|
57
|
+
|
|
58
|
+
## Initial consumer readback
|
|
59
|
+
|
|
60
|
+
On 2026-09-05, all workflow files from 23 accessible `kungfu-systems` repository
|
|
61
|
+
_default branches_ were read at their returned Git revisions. Five calls were
|
|
62
|
+
found in three repositories. This is a bounded inventory, not evidence that
|
|
63
|
+
unknown or non-default-branch consumers do not exist.
|
|
64
|
+
|
|
65
|
+
| Repository and observed revision | Caller | Existing selector |
|
|
66
|
+
| --- | --- | --- |
|
|
67
|
+
| Buildchain `d434a73d2d4fb010ee80fede2bf3ce872b1d04c8` | `self-build-adopter-dogfood.yml` | `v4-alpha` |
|
|
68
|
+
| Buildchain `d434a73d2d4fb010ee80fede2bf3ce872b1d04c8` | `self-build-public-consumer-dogfood.yml` | `v4-alpha` |
|
|
69
|
+
| agent-hub-demo `3f5de882b63464d70c50df0fd7ca418f487b794b` | `v4-adopter-delivery-qualification.yml` | `v4-alpha` |
|
|
70
|
+
| agent-hub-demo `3f5de882b63464d70c50df0fd7ca418f487b794b` | `v4-stage-capsule-canary.yml` | `v4` |
|
|
71
|
+
| taolu `6dcccdc3bd2c8b1801c7f6decea08ae7877aac2b` | `verify.yml` | `v4-alpha` |
|
|
72
|
+
|
|
73
|
+
The initial published channel readback was `v4` at
|
|
74
|
+
`da5e2db8384313e899eace87aea0a1a8e28c0aa8` and `v4-alpha` at
|
|
75
|
+
`dd87f43f7122b41c4ce7f1f6d1888521cc7f892f`. Neither contained the three canonical
|
|
76
|
+
filenames at that initial readback. The later evidence below records progress
|
|
77
|
+
without changing the scope or revisions of that initial inventory.
|
|
78
|
+
|
|
79
|
+
## Rollout evidence as of 2026-09-06
|
|
80
|
+
|
|
81
|
+
The canonical invocation-identity preparation was merged in
|
|
82
|
+
[Buildchain PR 3508](https://github.com/kungfu-systems/buildchain/pull/3508).
|
|
83
|
+
All three canonical paths are available in the immutable `v4.0.2-alpha.35`
|
|
84
|
+
release (`feab078f5d7c9927a3525154003e321700e8ca30`) and the later
|
|
85
|
+
`v4.0.2-alpha.37` release (`f5fa1a4a3e8d83eccee79c077e5f48417760c9df`).
|
|
86
|
+
The floating `v4-alpha` readback selects alpha.37.
|
|
87
|
+
|
|
88
|
+
[Taolu PR 30](https://github.com/kungfu-systems/taolu/pull/30) migrated its
|
|
89
|
+
Stage Capsule call on `@v4-alpha`, preserving the existing dual locks.
|
|
90
|
+
Its exact source `b3f4c12578d733ff44165ff1acafe131251b8907` passed
|
|
91
|
+
[consumer Verify](https://github.com/kungfu-systems/taolu/actions/runs/33975786413)
|
|
92
|
+
on all declared platforms and
|
|
93
|
+
[native delivery](https://github.com/kungfu-systems/taolu/actions/runs/34005576362).
|
|
94
|
+
The protected dev landing is `7e15123733110ad8ce484241934bbf0ef99fbb45`.
|
|
95
|
+
|
|
96
|
+
The stable `v4` readback remains
|
|
97
|
+
`da5e2db8384313e899eace87aea0a1a8e28c0aa8`, which does not contain the canonical
|
|
98
|
+
paths. Stable publication and the agent-hub-demo migration remain **pending**
|
|
99
|
+
outside this development change's completion boundary. The alpha.35
|
|
100
|
+
[Build Surface Fixture](https://github.com/kungfu-systems/buildchain/actions/runs/34005360217)
|
|
101
|
+
passed, but this individual result does not establish complete stable
|
|
102
|
+
qualification or authorize moving the stable channel.
|
|
103
|
+
|
|
104
|
+
## Recovery
|
|
105
|
+
|
|
106
|
+
Before channel retirement, revert consumer changes to the still-available old
|
|
107
|
+
paths if verification fails. After retirement, restore the exact previous
|
|
108
|
+
provider implementation through a reviewed corrective commit and normal
|
|
109
|
+
publication; do not rewrite immutable release tags or bypass admission checks.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungfu-tech/buildchain",
|
|
3
|
-
"version": "4.0.2-alpha.
|
|
3
|
+
"version": "4.0.2-alpha.38",
|
|
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",
|
|
@@ -244,7 +244,7 @@ invalid.
|
|
|
244
244
|
## Public self-dogfood and adoption
|
|
245
245
|
|
|
246
246
|
\`.github/workflows/self-build-public-consumer-dogfood.yml\` remains the exact thin
|
|
247
|
-
consumer of the public \`
|
|
247
|
+
consumer of the public \`public-build-stage-capsule-canary.yml@v4-alpha\` contract. Its
|
|
248
248
|
declared \`lifecycle.verify\` runs \`pnpm run check\`, so the same public path
|
|
249
249
|
executes pure recovery tests that inject a transient durable-state write
|
|
250
250
|
failure, restore the adapter operation on a fresh runner, supersede stale work
|
|
@@ -148,7 +148,7 @@ export function checkV4FloatingConsumerPolicyContract() {
|
|
|
148
148
|
"Resolve controller identities",
|
|
149
149
|
"Install Buildchain runtime dependencies",
|
|
150
150
|
]);
|
|
151
|
-
const stageCanary = read(".github/workflows/
|
|
151
|
+
const stageCanary = read(".github/workflows/public-build-stage-capsule-canary.yml");
|
|
152
152
|
if (
|
|
153
153
|
!stageCanary.includes("consumer-admission:") ||
|
|
154
154
|
!stageCanary.includes("needs: consumer-admission")
|
|
@@ -10,7 +10,7 @@ const DEFAULT_ROOT = path.resolve(
|
|
|
10
10
|
"..",
|
|
11
11
|
);
|
|
12
12
|
const CALLER_PATH = ".github/workflows/self-build-public-consumer-dogfood.yml";
|
|
13
|
-
const REUSABLE_PATH = ".github/workflows/
|
|
13
|
+
const REUSABLE_PATH = ".github/workflows/public-build-stage-capsule-canary.yml";
|
|
14
14
|
export const V4_PUBLIC_DOGFOOD_ALPHA_REF = "v4-alpha";
|
|
15
15
|
const PRIVATE_CONSUMER = ["buildchain", "self", "dogfood"].join("-");
|
|
16
16
|
const PRIVATE_SHADOW = ["kungfu", "shadow"].join("-");
|
|
@@ -27,7 +27,7 @@ permissions:
|
|
|
27
27
|
|
|
28
28
|
jobs:
|
|
29
29
|
dogfood:
|
|
30
|
-
uses: kungfu-systems/buildchain/.github/workflows/
|
|
30
|
+
uses: kungfu-systems/buildchain/.github/workflows/public-build-stage-capsule-canary.yml@${validationRef}
|
|
31
31
|
with:
|
|
32
32
|
consumer: buildchain
|
|
33
33
|
node-version: "24"
|
|
@@ -114,7 +114,7 @@ function assertWorkflowInventory(root) {
|
|
|
114
114
|
fail(`${relative} invokes the private qualification script directly`);
|
|
115
115
|
if (
|
|
116
116
|
relative !== CALLER_PATH &&
|
|
117
|
-
text.includes(".github/workflows/
|
|
117
|
+
text.includes(".github/workflows/public-build-stage-capsule-canary.yml@")
|
|
118
118
|
)
|
|
119
119
|
fail(`${relative} creates a second v4 dogfood caller`);
|
|
120
120
|
if (relative !== REUSABLE_PATH && relative !== CALLER_PATH)
|
|
@@ -162,7 +162,7 @@ function assertArchitecture(root) {
|
|
|
162
162
|
!dogfood ||
|
|
163
163
|
dogfood.callerWorkflow !== CALLER_PATH ||
|
|
164
164
|
dogfood.reusableWorkflow !==
|
|
165
|
-
"kungfu-systems/buildchain/.github/workflows/
|
|
165
|
+
"kungfu-systems/buildchain/.github/workflows/public-build-stage-capsule-canary.yml" ||
|
|
166
166
|
dogfood.runtimeBinding !== "job.workflow_sha" ||
|
|
167
167
|
dogfood.consumerSourceBinding !== "github.sha" ||
|
|
168
168
|
JSON.stringify(dogfood.executableStages) !==
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
|
-
import { projectWorkflowIdentities } from "./workflow-taxonomy.mjs";
|
|
2
|
+
import { currentWorkflowPath, projectWorkflowIdentities } from "./workflow-taxonomy.mjs";
|
|
3
3
|
import crypto from "node:crypto";
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
@@ -48,7 +48,7 @@ assert.deepEqual(
|
|
|
48
48
|
);
|
|
49
49
|
for (const relative of contract.inventoryWorkflows)
|
|
50
50
|
assert.ok(
|
|
51
|
-
fs.statSync(path.join(root, relative)).isFile(),
|
|
51
|
+
fs.statSync(path.join(root, currentWorkflowPath(root, relative))).isFile(),
|
|
52
52
|
`inventoried workflow is unavailable: ${relative}`,
|
|
53
53
|
);
|
|
54
54
|
assert.deepEqual(
|
|
@@ -87,7 +87,7 @@ for (const relative of contract.bootstrapGovernedWorkflows) {
|
|
|
87
87
|
contract.inventoryWorkflows.includes(relative),
|
|
88
88
|
`Bootstrap-governed workflow is outside the inventory: ${relative}`,
|
|
89
89
|
);
|
|
90
|
-
const source = fs.readFileSync(path.join(root, relative), "utf8");
|
|
90
|
+
const source = fs.readFileSync(path.join(root, currentWorkflowPath(root, relative)), "utf8");
|
|
91
91
|
assert.ok(
|
|
92
92
|
relative === contract.bootstrap.publicWorkflow ||
|
|
93
93
|
/uses:\s+(?:\.\/)?\.github\/workflows\/bootstrap\.yml/u.test(source) ||
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import crypto from "node:crypto";
|
|
4
|
-
import { writeWorkflowSource, rewriteRepositoryWorkflowPaths } from "./workflow-taxonomy.mjs";
|
|
4
|
+
import { currentWorkflowPath, writeWorkflowSource, rewriteRepositoryWorkflowPaths } from "./workflow-taxonomy.mjs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { execFileSync } from "node:child_process";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
@@ -426,14 +426,15 @@ function main() {
|
|
|
426
426
|
);
|
|
427
427
|
}
|
|
428
428
|
for (const relative of activeFacadePaths()) {
|
|
429
|
-
const
|
|
429
|
+
const current = currentWorkflowPath(root, relative);
|
|
430
|
+
const target = path.join(root, current);
|
|
430
431
|
const source = fresh
|
|
431
432
|
? frozenFacadeSource(relative)
|
|
432
433
|
: fs.readFileSync(target, "utf8");
|
|
433
434
|
if (check) verify(source, relative);
|
|
434
435
|
else
|
|
435
436
|
writeWorkflowSource(
|
|
436
|
-
root,
|
|
437
|
+
root, current,
|
|
437
438
|
migrateV4UniversalWorkflowFacade(source, relative),
|
|
438
439
|
);
|
|
439
440
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import crypto from "node:crypto";
|
|
3
3
|
import fs from "node:fs";
|
|
4
|
+
import { currentWorkflowPath } from "./workflow-taxonomy.mjs";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import { execFileSync } from "node:child_process";
|
|
6
7
|
import {
|
|
@@ -192,7 +193,7 @@ function executeBootstrapConformance(request, admission) {
|
|
|
192
193
|
fail("candidate Bootstrap conformance does not close execution semantics");
|
|
193
194
|
for (const relative of architecture.bootstrapGovernedWorkflows) {
|
|
194
195
|
const source = fs.readFileSync(
|
|
195
|
-
|
|
196
|
+
path.join(path.resolve(import.meta.dirname, ".."), currentWorkflowPath(path.resolve(import.meta.dirname, ".."), relative)),
|
|
196
197
|
"utf8",
|
|
197
198
|
);
|
|
198
199
|
if (
|
|
@@ -12,6 +12,7 @@ const ROLES = ["public", "component", "self"];
|
|
|
12
12
|
const CATEGORIES = ["build", "release", "ops"];
|
|
13
13
|
const SLUG = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
|
14
14
|
const WORKFLOW = /^\.github\/workflows\/[.a-z0-9-]+\.ya?ml$/u;
|
|
15
|
+
const VERSION_TOKEN = /(?:^|[.-])v\d+(?:[.-]|$)/iu;
|
|
15
16
|
const PROTECTED = [
|
|
16
17
|
TAXONOMY_PATH,
|
|
17
18
|
"scripts/workflow-taxonomy.mjs",
|
|
@@ -40,6 +41,10 @@ function validateEntryRole(entry, errors) {
|
|
|
40
41
|
errors.push(`${entry.id}: invalid category`);
|
|
41
42
|
if (!SLUG.test(entry.purpose || ""))
|
|
42
43
|
errors.push(`${entry.id}: invalid purpose slug`);
|
|
44
|
+
if (VERSION_TOKEN.test(path.posix.basename(workflowPath(entry))))
|
|
45
|
+
errors.push(
|
|
46
|
+
`${entry.id}: workflow filenames cannot contain version tokens`,
|
|
47
|
+
);
|
|
43
48
|
for (const field of ["summary", "owner", "rationale"]) {
|
|
44
49
|
if (typeof entry[field] !== "string" || !entry[field].trim())
|
|
45
50
|
errors.push(`${entry.id}: missing ${field}`);
|
|
@@ -57,6 +62,15 @@ function validateEntryRole(entry, errors) {
|
|
|
57
62
|
}
|
|
58
63
|
|
|
59
64
|
function validateMigration(policy, entry, declared, errors) {
|
|
65
|
+
if (entry.retiredAlias) {
|
|
66
|
+
if (
|
|
67
|
+
entry.compatibility ||
|
|
68
|
+
entry.retiredAlias.path !== entry.migration?.previousPath ||
|
|
69
|
+
!entry.retiredAlias.reason?.trim() ||
|
|
70
|
+
entry.retiredAlias.migrationGuide !== "docs/workflow-path-migration.md"
|
|
71
|
+
)
|
|
72
|
+
errors.push(`${entry.id}: invalid alias retirement record`);
|
|
73
|
+
}
|
|
60
74
|
if (entry.migration) {
|
|
61
75
|
if (
|
|
62
76
|
!WORKFLOW.test(entry.migration.previousPath || "") ||
|
|
@@ -73,6 +87,10 @@ function validateMigration(policy, entry, declared, errors) {
|
|
|
73
87
|
}
|
|
74
88
|
if (entry.compatibility) {
|
|
75
89
|
const alias = entry.compatibility;
|
|
90
|
+
if (VERSION_TOKEN.test(path.posix.basename(alias.path || "")))
|
|
91
|
+
errors.push(
|
|
92
|
+
`${entry.id}: version-prefixed compatibility aliases are retired`,
|
|
93
|
+
);
|
|
76
94
|
if (entry.role === "self")
|
|
77
95
|
errors.push(
|
|
78
96
|
`${entry.id}: repository event wrappers cannot have duplicate aliases`,
|
|
@@ -167,6 +185,14 @@ function validateWorkflow(root, entry, declared, errors) {
|
|
|
167
185
|
const absolute = path.join(root, file);
|
|
168
186
|
if (!fs.existsSync(absolute) || !fs.lstatSync(absolute).isFile()) return;
|
|
169
187
|
const text = fs.readFileSync(absolute, "utf8");
|
|
188
|
+
if (
|
|
189
|
+
entry.retiredAlias &&
|
|
190
|
+
text.includes("BUILDCHAIN_INVOKED_WORKFLOW:") &&
|
|
191
|
+
!text.includes(`BUILDCHAIN_INVOKED_WORKFLOW: ${file}\n`)
|
|
192
|
+
)
|
|
193
|
+
errors.push(
|
|
194
|
+
`${file}: consumer admission must bind the canonical invoked workflow`,
|
|
195
|
+
);
|
|
170
196
|
const document = parseWorkflowDocument(text);
|
|
171
197
|
if (entry.role === "self")
|
|
172
198
|
validateRepositoryReferences(file, document, text, declared, errors);
|
|
@@ -195,6 +221,13 @@ function validateWorkflow(root, entry, declared, errors) {
|
|
|
195
221
|
);
|
|
196
222
|
}
|
|
197
223
|
for (const call of parseYamlUses(text)) {
|
|
224
|
+
const remote = call.value.match(
|
|
225
|
+
/^kungfu-systems\/buildchain\/(\.github\/workflows\/[^@]+)@/u,
|
|
226
|
+
);
|
|
227
|
+
if (remote && VERSION_TOKEN.test(path.posix.basename(remote[1])))
|
|
228
|
+
errors.push(
|
|
229
|
+
`${file}:${call.line}: retired version-prefixed workflow call ${remote[1]}`,
|
|
230
|
+
);
|
|
198
231
|
const local = call.value.match(/^\.\/(\.github\/workflows\/[^@]+)$/u);
|
|
199
232
|
if (local && !declared.has(local[1]))
|
|
200
233
|
errors.push(
|
|
@@ -276,6 +309,8 @@ export function checkWorkflowTaxonomy(
|
|
|
276
309
|
);
|
|
277
310
|
const observed = new Set(discoverWorkflowFiles(root));
|
|
278
311
|
for (const file of observed) {
|
|
312
|
+
if (VERSION_TOKEN.test(path.posix.basename(file)))
|
|
313
|
+
errors.push(`workflow filenames cannot contain version tokens: ${file}`);
|
|
279
314
|
if (!declared.has(file)) errors.push(`unregistered workflow: ${file}`);
|
|
280
315
|
if (!fs.lstatSync(path.join(root, file)).isFile())
|
|
281
316
|
errors.push(`workflow must be a regular file: ${file}`);
|
|
@@ -334,6 +369,8 @@ export function writeWorkflowSource(root, relative, text) {
|
|
|
334
369
|
(item) =>
|
|
335
370
|
workflowPath(item) === relative || item.compatibility?.path === relative,
|
|
336
371
|
);
|
|
372
|
+
if (policy?.entries.some((item) => item.retiredAlias?.path === relative))
|
|
373
|
+
throw new Error(`${relative}: cannot regenerate a retired workflow alias`);
|
|
337
374
|
const outputs = entry
|
|
338
375
|
? [
|
|
339
376
|
workflowPath(entry),
|
|
@@ -345,19 +382,10 @@ export function writeWorkflowSource(root, relative, text) {
|
|
|
345
382
|
|
|
346
383
|
export function rewriteRepositoryWorkflowPaths(root, text) {
|
|
347
384
|
for (const entry of readWorkflowTaxonomy(root)?.entries || []) {
|
|
348
|
-
if (
|
|
349
|
-
["v4-adopter-delivery", "v4-stage-capsule-canary"].includes(entry.id) &&
|
|
350
|
-
entry.compatibility
|
|
351
|
-
) {
|
|
352
|
-
const canonical = workflowPath(entry);
|
|
353
|
-
const legacy = entry.compatibility.path;
|
|
354
|
-
text = text.replaceAll(
|
|
355
|
-
`BUILDCHAIN_INVOKED_WORKFLOW: ${legacy}\n`,
|
|
356
|
-
`BUILDCHAIN_INVOKED_WORKFLOW: \${{ startsWith(job.workflow_ref, 'kungfu-systems/buildchain/${canonical}@') && '${canonical}' || '${legacy}' }}\n`,
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
385
|
if (entry.role === "self" && entry.migration)
|
|
360
386
|
text = text.replaceAll(entry.migration.previousPath, workflowPath(entry));
|
|
387
|
+
if (entry.retiredAlias)
|
|
388
|
+
text = text.replaceAll(entry.retiredAlias.path, workflowPath(entry));
|
|
361
389
|
if (entry.id === "build-surface-fixture")
|
|
362
390
|
text = text.replaceAll(
|
|
363
391
|
"build-surface-fixture.yml",
|
|
@@ -367,6 +395,15 @@ export function rewriteRepositoryWorkflowPaths(root, text) {
|
|
|
367
395
|
return text;
|
|
368
396
|
}
|
|
369
397
|
|
|
398
|
+
// Historical inventories and debt ledgers retain their original identity. File
|
|
399
|
+
// access resolves only explicitly retired aliases to the registered implementation.
|
|
400
|
+
export function currentWorkflowPath(root, relative) {
|
|
401
|
+
const entry = readWorkflowTaxonomy(root)?.entries.find(
|
|
402
|
+
(item) => item.retiredAlias?.path === relative,
|
|
403
|
+
);
|
|
404
|
+
return entry ? workflowPath(entry) : relative;
|
|
405
|
+
}
|
|
406
|
+
|
|
370
407
|
export function workflowCompatibilityIdentity(root, relative, text) {
|
|
371
408
|
const entry = readWorkflowTaxonomy(root)?.entries.find(
|
|
372
409
|
(item) => workflowPath(item) === relative && item.compatibility,
|
|
@@ -441,6 +478,8 @@ export function renderWorkflowCatalog(policy) {
|
|
|
441
478
|
"must name an exact migration source with a reason and removal condition.",
|
|
442
479
|
"The policy, generator, checker, tests, required CI chain and CODEOWNERS require",
|
|
443
480
|
"independent `kungfu-origin` review. No wildcard compatibility admission is allowed.",
|
|
481
|
+
"Workflow filenames cannot contain version tokens such as `v4` or `v5`.",
|
|
482
|
+
"Retired aliases cannot be recreated or called; see [path migration](workflow-path-migration.md).",
|
|
444
483
|
"",
|
|
445
484
|
"A role, category or implementation edit must preserve or deliberately update",
|
|
446
485
|
"all related declarations. Run `pnpm run generate:workflows` and",
|