@kungfu-tech/buildchain 2.14.18-alpha.1 → 2.14.18-alpha.11

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.
Files changed (43) hide show
  1. package/README.md +1 -0
  2. package/actions/promote-buildchain-ref/README.md +33 -30
  3. package/bin/buildchain.mjs +16 -4
  4. package/dist/site/buildchain-contract.json +86 -31
  5. package/dist/site/buildchain-site.json +88 -27
  6. package/dist/site/capability-registry.json +6 -5
  7. package/dist/site/cli-registry.json +12 -0
  8. package/dist/site/controller-registry.json +50 -6
  9. package/dist/site/kfd-claims.json +110 -21
  10. package/dist/site/kfd-upstream-aggregate.json +1 -1
  11. package/dist/site/manual-registry.json +21 -6
  12. package/dist/site/node-api-registry.json +19 -6
  13. package/dist/site/page-registry.json +70 -17
  14. package/dist/site/public-surface-audit.json +130 -23
  15. package/dist/site/publication-authority-registry.json +21 -1
  16. package/dist/site/publication-registry.json +4 -4
  17. package/dist/site/release-provenance.json +1 -0
  18. package/dist/site/site-manifest.json +18 -10
  19. package/dist/site/workflow-registry.json +62 -16
  20. package/docs/MAP.md +3 -1
  21. package/docs/github-governance-authority.md +267 -0
  22. package/docs/lifecycle-protocol.md +10 -10
  23. package/docs/publish-transaction.md +73 -4
  24. package/docs/release-governance.md +38 -24
  25. package/docs/reusable-build-surface.md +29 -11
  26. package/docs/web-surface-deployments.md +46 -0
  27. package/package.json +2 -1
  28. package/packages/core/buildchain-kfd-claims.js +2 -0
  29. package/packages/core/buildchain-publication-authority.js +1 -0
  30. package/packages/core/controller-evidence.js +1 -1
  31. package/packages/core/github-governance-authority.js +1312 -0
  32. package/packages/core/index.js +22 -0
  33. package/packages/core/publication-control-plane-audit.js +4 -1
  34. package/scripts/audit-github-governance.mjs +474 -0
  35. package/scripts/audit-publication-control-plane.mjs +41 -5
  36. package/scripts/check-inventory.mjs +8 -0
  37. package/scripts/generate-channel-promotion-workflow.mjs +3 -0
  38. package/scripts/generate-site-bundle.mjs +5 -0
  39. package/scripts/installer-publication.mjs +351 -0
  40. package/scripts/publication-commit-evidence.mjs +158 -0
  41. package/scripts/reconcile-github-governance.mjs +549 -0
  42. package/scripts/release-candidate-resolver.mjs +53 -0
  43. package/scripts/web-surface-core.mjs +127 -14
@@ -363,6 +363,73 @@ When publish transactions are enabled, promotion order is:
363
363
  7. move floating tags and channel refs;
364
364
  8. mark the transaction `complete`.
365
365
 
366
+ When a protected channel requires a generated version-state pull request, the
367
+ first run can stop at `finalizing` after registry publication. If the reviewed
368
+ merge commit later contains that exact transaction release material but the
369
+ exact tag is still absent, a retry performs finalization only: it reloads the
370
+ same durable source, release material, tooling, evidence, version, and target
371
+ bindings; creates the exact and floating tags at the transaction release SHA;
372
+ and completes the passport from the transaction source tree. It does not rerun
373
+ the provider mutation and does not authorize the newer composite channel tree
374
+ as published material. A different source tree still requires a new version and
375
+ a fresh release candidate.
376
+
377
+ Deferred binary dispatch, controller-evidence bundling, and any consumer
378
+ publication commit are skipped while `finalization-needed=true`. They run only
379
+ after the exact public tag and complete release passport exist.
380
+
381
+ Consumer products that expose a signed well-known channel can opt into one
382
+ additional, deliberately final step with `publication-commit-command`. Before
383
+ that command runs, Buildchain has already completed the transaction, created
384
+ the public GitHub Release, and uploaded every release-passport file plus the
385
+ explicit PR-stage payload files selected by
386
+ `github-release-payload-patterns`. The command is therefore a commit point for
387
+ discovery authority, not another artifact publisher.
388
+
389
+ The command receives the exact version, source SHA, release SHA, release tag,
390
+ release passport path, and downloaded payload directory through
391
+ `BUILDCHAIN_PUBLICATION_COMMIT_*`. Optional consumer-owned dispatch/API
392
+ credentials and private signing material are exposed separately as
393
+ `BUILDCHAIN_PUBLICATION_COMMIT_TOKEN` and
394
+ `BUILDCHAIN_PUBLICATION_COMMIT_SIGNING_KEY`; Buildchain never logs, persists,
395
+ or interprets either value. The command must write
396
+ `.buildchain/publication-commit/evidence.json` (or another declared path below
397
+ `.buildchain/`) with this contract:
398
+
399
+ ```json
400
+ {
401
+ "schema": "kungfu-buildchain-publication-commit-evidence/v1",
402
+ "status": "passed",
403
+ "identity": {
404
+ "version": "4.0.0-alpha.2",
405
+ "sourceSha": "<source-sha>",
406
+ "releaseSha": "<release-sha>",
407
+ "releaseTag": "v4.0.0-alpha.2"
408
+ },
409
+ "publication": {
410
+ "url": "https://example.test/.well-known/product/alpha.json",
411
+ "payloadRoot": "sha256:<64-lowercase-hex>"
412
+ },
413
+ "readback": {
414
+ "status": "passed",
415
+ "url": "https://example.test/.well-known/product/alpha.json",
416
+ "payloadRoot": "sha256:<same-root>"
417
+ },
418
+ "recovery": {
419
+ "previousAuthority": "preserved",
420
+ "rollbackReference": "sha256:<previous-root>"
421
+ }
422
+ }
423
+ ```
424
+
425
+ Buildchain rejects stale evidence, identity drift, non-public or mutable URLs,
426
+ read-back root drift, and missing recovery evidence. It also rejects
427
+ `standalone-binary-distribution=true` with a final commit command because that
428
+ would queue product mutations after the authority moved. On any command or
429
+ read-back failure, the consumer must leave the previous well-known document
430
+ authoritative; Buildchain does not retry the command behind a successful
431
+ receipt.
432
+
366
433
  If protected branch finalization is interrupted after publish evidence is
367
434
  valid, the transaction can stop in `finalizing` and output
368
435
  `finalization-needed=true`. A later run resumes from the same transaction state
@@ -374,10 +441,12 @@ the exact generated version-state commit so branch protection can
374
441
  validate the automation path without a second build, then uses the generated
375
442
  ref update token for the protected ref PATCH. If release finalization
376
443
  bookkeeping is still rejected, Buildchain creates or reuses a same-repository
377
- `buildchain/version-state/*` PR based on the current target channel head and
378
- leaves the transaction resumable with `finalization-needed=true`. Strict alpha
379
- bookkeeping remains fail-fast. The reusable wrapper defaults that token to
380
- `secrets.BUILDCHAIN_PROMOTION_TOKEN || github.token`.
444
+ `buildchain/version-state/*` PR and leaves the transaction resumable with
445
+ `finalization-needed=true`. Strict alpha uses the same protected PR fallback
446
+ for both its target channel and subsequent dev reconciliation. A later
447
+ idempotent run continues only after the provider shows that the PR reached the
448
+ protected branch. The reusable wrapper binds that token to the run-scoped
449
+ `github.token` and rejects user, team, or alternate App bypass actors.
381
450
 
382
451
  If finalization fails after an exact Git tag, a channel branch, or dev/alpha
383
452
  sync ref has already moved, the next run reads the durable `finalizing` state
@@ -703,29 +703,28 @@ same material binding.
703
703
  Protected release-line branches keep their normal human review gate. Managed
704
704
  `dev/vN/vN.M`, `alpha/vN/vN.M`, and `release/vN/vN.M` branches are configured
705
705
  with one required approving review, required GitHub Actions checks, administrator
706
- enforcement, conversation resolution, no force pushes, and no deletions. Dev
707
- keeps its repository-selected strict or merge-queue policy. Alpha and release
708
- require both `check` and the pair-specific `verify` aggregate without requiring
709
- the source branch to contain the target's generated bookkeeping history. The
706
+ enforcement, conversation resolution, no force pushes, and no deletions. Each
707
+ target uses the exact check set, GitHub App identity, and strictness declared by
708
+ the governance authority descriptor. The
710
709
  reusable `release-candidate-promote.yml` wrapper defaults
711
710
  `branch-protection-bypass-apps` to `github-actions`, which lets the workflow's
712
711
  automation identity apply generated version-state or post-publish channel
713
712
  bookkeeping after the reviewed channel PR has merged. Direct
714
- `promote-buildchain-ref` callers must opt into the same controlled bypass with
715
- `branch-protection-bypass-apps`, `branch-protection-bypass-users`, or
716
- `branch-protection-bypass-teams`; the action also adds the current promotion
717
- token's authenticated user or app to the managed bypass allowlist. Before
713
+ `promote-buildchain-ref` callers may opt into that one controlled bypass with
714
+ `branch-protection-bypass-apps: github-actions`; every other App slug and all
715
+ user or team bypass actors are rejected. Before
718
716
  patching a protected generated bookkeeping ref, the action creates the
719
717
  full configured required-check set on the exact generated version-state commit, so strict
720
718
  status checks are satisfied by machine-verifiable Buildchain evidence rather
721
719
  than a human PR. The protected ref PATCH itself uses the generated ref update
722
- token; the reusable wrapper defaults it to
723
- `secrets.BUILDCHAIN_PROMOTION_TOKEN || github.token`. If direct generated
720
+ token; the reusable wrapper binds it to the run-scoped `github.token`. If direct generated
724
721
  release finalization bookkeeping is still rejected, Buildchain creates or
725
- reuses a same-repository `buildchain/version-state/*` PR based on the current
726
- target channel head and records `finalization-needed=true` in the durable
727
- transaction output. Strict alpha bookkeeping still fails with a
728
- token/protection diagnostic instead of creating a post-publish PR.
722
+ reuses a same-repository `buildchain/version-state/*` PR and records
723
+ `finalization-needed=true` in the durable transaction output. Strict alpha
724
+ follows the same provider-enforced PR path for its alpha and dev bookkeeping.
725
+ The PR remains subject to the declared review, required checks, and merge-queue
726
+ policy; publication resumes idempotently after that protected transaction
727
+ lands.
729
728
 
730
729
  For a stable release, the wrapper also checks out the exact current development
731
730
  channel into `.buildchain/reconciliation/dev`. When the prepared next-alpha
@@ -734,16 +733,14 @@ promotion action applies the next version to that checkout, regenerates every
734
733
  declared derived version-state file, reruns the verification lifecycle, and
735
734
  only then creates the two-parent reconciliation commit. A checkout/current-ref
736
735
  SHA mismatch blocks reconciliation instead of committing stale projections.
737
- Buildchain's own promotion workflow reads `BUILDCHAIN_PROMOTION_BYPASS_APPS`,
738
- `BUILDCHAIN_PROMOTION_BYPASS_USERS`, and
739
- `BUILDCHAIN_PROMOTION_BYPASS_TEAMS` repository variables so the declared bypass
740
- identity can match the actual `BUILDCHAIN_PROMOTION_TOKEN` actor, but consumers
741
- do not need to duplicate that actor manually when the token identity is
742
- discoverable. Buildchain's release-line bootstrap applies the same declared
743
- allowances when it creates new `dev`, `alpha`, and `release` branch protection,
744
- and fails closed before changing protection when no promotion authority is
745
- declared. This keeps a new minor line publishable without weakening its normal
746
- human review gate.
736
+ Buildchain's own promotion workflow accepts only
737
+ `BUILDCHAIN_PROMOTION_BYPASS_APPS=github-actions`, defaulting to that exact App
738
+ when the variable is absent. Buildchain's release-line bootstrap uses the
739
+ administrator-scoped promotion token only to configure protection; branch
740
+ creation and generated ref updates use the run-scoped token. New channel
741
+ protection binds required checks to GitHub Actions App id `15368`, enables Code
742
+ Owner, stale-review, and latest-push review gates, and admits no user or team
743
+ bypass actor.
747
744
 
748
745
  ## What This Guarantees
749
746
 
@@ -830,6 +827,23 @@ bytes, uploads only missing assets, and fails with an immutable-release
830
827
  collision when a same-name asset has different bytes. It never deletes and
831
828
  replaces an existing asset during retry or duplicate workflow delivery.
832
829
 
830
+ Product payloads are included only through the explicit
831
+ `github-release-payload-patterns` input. Patterns match basenames inside the
832
+ downloaded PR-stage RC payload bundle; zero matches or duplicate public
833
+ basenames fail closed. This preserves the exact PR-built bytes instead of
834
+ rebuilding archives during promotion.
835
+
836
+ Consumers with a signed well-known discovery document can additionally provide
837
+ `publication-commit-command`. The advanced promotion workflow validates its
838
+ topology before any publish-gate or release mutation, then runs it only after
839
+ the GitHub Release and its immutable payload/passport assets exist. The command
840
+ must publicly read back the exact new payload root and emit
841
+ `kungfu-buildchain-publication-commit-evidence/v1`; that evidence is copied
842
+ into the controller artifact and exposed as workflow outputs. The previous
843
+ authority must remain valid on every failure. Deferred standalone binary
844
+ distribution is incompatible with this mode because the discovery authority
845
+ must be the final product mutation.
846
+
833
847
  Buildchain also does not maintain bare exact tags such as `1.0.0`. The supported
834
848
  exact release and alpha refs are v-prefixed:
835
849
 
@@ -519,7 +519,9 @@ diagnostics artifacts first.
519
519
  ## macOS Credential Island
520
520
 
521
521
  Alpha consumers can ask the build controller to seal one exact macOS app and
522
- hand it to a separate protected signing job:
522
+ hand it to a separate protected signing job. The built-in mode is suitable
523
+ when the protected environment belongs to the repository that defines the
524
+ reusable workflow:
523
525
 
524
526
  ```yaml
525
527
  with:
@@ -528,14 +530,31 @@ with:
528
530
  credential-island-macos-platform-id: macos-arm64
529
531
  ```
530
532
 
533
+ For a cross-repository reusable workflow, keep the credentials in the consumer
534
+ repository and select caller-owned mode:
535
+
536
+ ```yaml
537
+ with:
538
+ credential-island-macos-app-path: product/dist/desktop/mac-arm64/Kungfu Episodes.app
539
+ credential-island-caller-owned: true
540
+ credential-island-macos-platform-id: macos-arm64
541
+ ```
542
+
543
+ The caller then runs its own no-checkout macOS job after the reusable build,
544
+ binds the consumer-owned protected environment on that job, and downloads the
545
+ source-bound input plus immutable action runtime from the same workflow run.
546
+ This is required for cross-repository callers because environment credentials
547
+ must never be widened into repository secrets merely to cross a reusable
548
+ workflow boundary.
549
+
531
550
  The ordinary matrix uploads
532
551
  `credential-island-input-<platform>-<source-sha>`, containing a `ditto`
533
552
  archive and a manifest bound to the caller repository, source commit, source
534
553
  tree, bundle identity, version, size, and digest. The pinned reusable workflow
535
- then starts a separate GitHub-hosted macOS job that names the caller
536
- environment. That job has no source checkout or package-manager step: it
537
- downloads the immutable Buildchain action runtime plus the sealed app and never
538
- invokes consumer code.
554
+ either starts its built-in GitHub-hosted macOS job or leaves that job to the
555
+ caller. In both modes the credential-bearing job has no source checkout or
556
+ package-manager step: it downloads the immutable Buildchain action runtime plus
557
+ the sealed app and never invokes consumer code.
539
558
 
540
559
  The protected environment supplies these non-secret variables:
541
560
 
@@ -781,12 +800,11 @@ floating `@v2` consumers receive publish-side source-lock drift protection by
781
800
  default. It also defaults `branch-protection-bypass-apps` to `github-actions`
782
801
  so the workflow automation can apply generated version-state and channel
783
802
  bookkeeping on protected `dev`/`alpha`/`release` branches after the reviewed
784
- channel PR has merged; consumers using a different promotion identity can pass
785
- `branch-protection-bypass-users`, `branch-protection-bypass-teams`, or a
786
- different app slug declaratively. The wrapper uses
787
- `secrets.BUILDCHAIN_PROMOTION_TOKEN || github.token` as the generated ref update
788
- token for protected bookkeeping PATCH calls, so a bypass-capable promotion token
789
- can sync dev immediately after alpha/release publish without a post-publish PR.
803
+ channel PR has merged. Other App slugs and all user or team bypass actors are
804
+ rejected. The wrapper uses the run-scoped `github.token` as the generated ref
805
+ update token for protected bookkeeping PATCH calls, so the exact GitHub Actions
806
+ App authority can sync dev immediately after alpha/release publish without a
807
+ post-publish PR.
790
808
  It does not call `.build.yml`, does not create a matrix, and must fail before
791
809
  publish if the RC evidence, payload set, or source-lock ref is missing or
792
810
  ambiguous.
@@ -944,6 +944,52 @@ The project may use pnpm, npm, yarn, Vite, Astro, Next static export, Sphinx,
944
944
  MkDocs, CMake-generated docs, or another lifecycle command source. Buildchain
945
945
  only needs a deterministic artifact path and the manifest facts.
946
946
 
947
+ ## Signed bootstrap installer publications
948
+
949
+ A web-surface artifact that contains `installer-publication.json` opts into the
950
+ `kungfu.bootstrap-installer-publication/v1` seam. During planning, Buildchain
951
+ fails closed unless the manifest binds:
952
+
953
+ - one signed-channel payload root and exact channel-file digest;
954
+ - one source SHA and Release Passport;
955
+ - unique platform/architecture entries with manifest, artifact, and archive
956
+ digest roots; and
957
+ - byte-identical friendly and immutable `install.sh` / `install.ps1` assets.
958
+
959
+ The resulting `kungfu-buildchain-installer-publication-evidence/v1` object and
960
+ root are welded into the deployment manifest. This does not make Buildchain the
961
+ product installer authority: Kungfu generates the installer from its signed
962
+ release channel, while the site owns only routes and presentation.
963
+
964
+ The site artifact should also declare the existing
965
+ `kungfu-buildchain-publication-archive-policy` in its root `manifest.json`, with
966
+ the versioned installer directory as `immutablePath`. Buildchain then performs
967
+ pre-upload object digest checks, `--no-overwrite` upload, post-upload checks, and
968
+ excludes the immutable root from mutable deletion.
969
+
970
+ Local verification:
971
+
972
+ ```sh
973
+ node scripts/installer-publication.mjs \
974
+ --manifest dist/installer-publication.json \
975
+ --artifact-root dist
976
+ ```
977
+
978
+ After preview, staging, or production apply, public read-back verifies exact
979
+ bytes plus route semantics. Friendly routes require a revalidated cache policy
980
+ with `max-age` no greater than 300 seconds; immutable routes require at least
981
+ one year and the `immutable` directive:
982
+
983
+ ```sh
984
+ node scripts/installer-publication.mjs \
985
+ --manifest dist/installer-publication.json \
986
+ --public-readback
987
+ ```
988
+
989
+ Redirects are not accepted as successful read-back. The evidence retains
990
+ content type, cache control, ETag, object version id when exposed, size, digest,
991
+ URL, channel root, source SHA, and Release Passport coordinates.
992
+
947
993
  ## Boundaries
948
994
 
949
995
  Buildchain only performs live AWS mutations in explicit apply modes with
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungfu-tech/buildchain",
3
- "version": "2.14.18-alpha.1",
3
+ "version": "2.14.18-alpha.11",
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",
@@ -37,6 +37,7 @@
37
37
  "./publication-authority": "./packages/core/publication-authority.js",
38
38
  "./publication-control-plane-audit": "./packages/core/publication-control-plane-audit.js",
39
39
  "./buildchain-publication-authority": "./packages/core/buildchain-publication-authority.js",
40
+ "./github-governance-authority": "./packages/core/github-governance-authority.js",
40
41
  "./kfd-gate": "./packages/core/kfd-gate.js",
41
42
  "./release-candidate": "./packages/core/release-candidate.js",
42
43
  "./stable-candidate-ledger": "./packages/core/stable-candidate-ledger.js",
@@ -17,6 +17,7 @@ export const BUILDCHAIN_AGENT_MANUALS = Object.freeze([
17
17
  { id: "release-passport", title: "Release Passport protocol", path: "docs/release-passport.md", plane: "verify" },
18
18
  { id: "controller-evidence", title: "Controller evidence contract", path: "docs/controller-evidence.md", plane: "verify" },
19
19
  { id: "publication-authority", title: "Sealed publication authority", path: "docs/publication-authority.md", plane: "verify" },
20
+ { id: "github-governance-authority", title: "GitHub governance authority", path: "docs/github-governance-authority.md", plane: "verify" },
20
21
  { id: "release-candidate", title: "Release Candidate Passport", path: "docs/release-candidate.md", plane: "verify" },
21
22
  { id: "release-propagation", title: "Release propagation", path: "docs/release-propagation.md", plane: "use" },
22
23
  { id: "readme-badges", title: "README badge blocks", path: "docs/readme-badges.md", plane: "use" },
@@ -74,6 +75,7 @@ const SCHEMA_AND_STANDARD_FILES = Object.freeze([
74
75
  "packages/core/publication-authority.js",
75
76
  "packages/core/publication-control-plane-audit.js",
76
77
  "packages/core/buildchain-publication-authority.js",
78
+ "packages/core/github-governance-authority.js",
77
79
  "packages/core/buildchain-kfd-claims.js",
78
80
  "packages/core/kfd3-surface-register.js",
79
81
  "packages/core/public-surface-audit.js",
@@ -28,6 +28,7 @@ const DESCRIPTORS = Object.freeze([
28
28
  [".github/workflows/buildchain-stable-candidate-patrol.yml", "governance-write"],
29
29
  [".github/workflows/dev-merge-queue-governance.yml", "governance-write"],
30
30
  [".github/workflows/dev-pr-auto-merge.yml", "governance-write"],
31
+ [".github/workflows/github-governance-audit.yml", "governance-write"],
31
32
  [".github/workflows/npm-publish.yml", "dry-run-only"],
32
33
  [".github/workflows/paper-release-sealed.yml", "product-publication", true, ["npm-publish", "github-release"], "trusted-publishing", "none", "fixed", "caller-bound"],
33
34
  [".github/workflows/paper-release.yml", "product-publication", true, ["npm-publish", "github-release"], "trusted-publishing", "none", "fixed", "caller-bound"],
@@ -7,7 +7,7 @@ export const BUILDCHAIN_CONTROLLER_AGGREGATE_CONTRACT = "buildchain.controller-e
7
7
 
8
8
  const SHA256_PATTERN = /^sha256:[0-9a-f]{64}$/;
9
9
  const GIT_SHA_PATTERN = /^[0-9a-f]{40}$/;
10
- const STAGE_STATUSES = new Set(["passed", "failed", "skipped", "cancelled", "missing"]);
10
+ const STAGE_STATUSES = new Set(["passed", "failed", "skipped", "cancelled", "missing", "partial"]);
11
11
 
12
12
  const CONTROLLER_SPECS = [
13
13
  {