@kungfu-tech/buildchain 2.10.9 → 2.10.10

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.
@@ -3,11 +3,11 @@
3
3
  "contract": "kungfu-buildchain-public-surface-reverse-audit",
4
4
  "status": "passed",
5
5
  "summary": {
6
- "cliCommandCount": 71,
7
- "workflowCount": 35,
6
+ "cliCommandCount": 73,
7
+ "workflowCount": 36,
8
8
  "actionCount": 4,
9
- "sitePageCount": 43,
10
- "docCommandRefCount": 224,
9
+ "sitePageCount": 45,
10
+ "docCommandRefCount": 227,
11
11
  "failureCount": 0
12
12
  },
13
13
  "enumerated": {
@@ -110,7 +110,7 @@
110
110
  {
111
111
  "id": "init",
112
112
  "source": "bin/buildchain.mjs",
113
- "usage": "buildchain init [--cwd <dir>] [--type package|native|web-surface|infra-contract|anchored-package] [--force]"
113
+ "usage": "buildchain init [--cwd <dir>] [--type package|native|web-surface|infra-contract|publication-artifact|anchored-package] [--force]"
114
114
  },
115
115
  {
116
116
  "id": "inspect",
@@ -282,6 +282,16 @@
282
282
  "source": "bin/buildchain.mjs",
283
283
  "usage": "buildchain npm dry-run [--cwd <dir>] [--expected-tag <tag>] [--registry <url>]"
284
284
  },
285
+ {
286
+ "id": "publication-artifact",
287
+ "source": "bin/buildchain.mjs",
288
+ "usage": "buildchain publication-artifact"
289
+ },
290
+ {
291
+ "id": "publication-artifact-manifest",
292
+ "source": "bin/buildchain.mjs",
293
+ "usage": "buildchain publication-artifact manifest [--cwd <dir>] [--source-sha <sha>]"
294
+ },
285
295
  {
286
296
  "id": "publish-source",
287
297
  "source": "bin/buildchain.mjs",
@@ -606,6 +616,7 @@
606
616
  "production-approved",
607
617
  "production-aws-role-arn",
608
618
  "production-environment",
619
+ "production-release-app-client-id",
609
620
  "production-release-app-id",
610
621
  "production-release-branch-channel",
611
622
  "production-release-head-prefix",
@@ -620,7 +631,7 @@
620
631
  "verify-command",
621
632
  "working-directory"
622
633
  ],
623
- "inputCount": 32
634
+ "inputCount": 33
624
635
  },
625
636
  {
626
637
  "id": ".wheel-release",
@@ -813,6 +824,26 @@
813
824
  ],
814
825
  "inputCount": 4
815
826
  },
827
+ {
828
+ "id": "publication-artifact",
829
+ "path": ".github/workflows/publication-artifact.yml",
830
+ "inputs": [
831
+ "artifact-name",
832
+ "artifact-paths",
833
+ "artifact-retention-days",
834
+ "build-command",
835
+ "buildchain-contract-compatibility-policy",
836
+ "buildchain-contract-drift-issue-mode",
837
+ "buildchain-contract-lock-path",
838
+ "buildchain-ref",
839
+ "buildchain-repository",
840
+ "node-version",
841
+ "setup-node",
842
+ "verify-command",
843
+ "working-directory"
844
+ ],
845
+ "inputCount": 13
846
+ },
816
847
  {
817
848
  "id": "release-candidate-promote",
818
849
  "path": ".github/workflows/release-candidate-promote.yml",
@@ -1132,6 +1163,10 @@
1132
1163
  "id": "fixture:libnode-shaped",
1133
1164
  "category": "fixture"
1134
1165
  },
1166
+ {
1167
+ "id": "fixture:publication-artifact-shaped",
1168
+ "category": "fixture"
1169
+ },
1135
1170
  {
1136
1171
  "id": "fixture:publish-transaction-shaped",
1137
1172
  "category": "fixture"
@@ -1196,6 +1231,10 @@
1196
1231
  "id": "manual:product-mechanism",
1197
1232
  "category": "manual"
1198
1233
  },
1234
+ {
1235
+ "id": "manual:publication-artifacts",
1236
+ "category": "manual"
1237
+ },
1199
1238
  {
1200
1239
  "id": "manual:publish-transaction",
1201
1240
  "category": "manual"
@@ -2084,6 +2123,21 @@
2084
2123
  "path": "docs/cli.md",
2085
2124
  "command": "buildchain npm dry-run"
2086
2125
  },
2126
+ {
2127
+ "id": "publication-artifact-manifest",
2128
+ "path": "docs/cli.md",
2129
+ "command": "buildchain publication-artifact manifest"
2130
+ },
2131
+ {
2132
+ "id": "publication-artifact-manifest",
2133
+ "path": "docs/publication-artifacts.md",
2134
+ "command": "buildchain publication-artifact manifest --source-sha"
2135
+ },
2136
+ {
2137
+ "id": "publication-artifact",
2138
+ "path": "docs/cli.md",
2139
+ "command": "buildchain publication-artifact"
2140
+ },
2087
2141
  {
2088
2142
  "id": "publish-source",
2089
2143
  "path": "docs/cli.md",
@@ -2380,9 +2434,9 @@
2380
2434
  "cliRegistryPath": "dist/site/cli-registry.json",
2381
2435
  "workflowRegistryPath": "dist/site/workflow-registry.json",
2382
2436
  "pageRegistryPath": "dist/site/page-registry.json",
2383
- "cliRegistryDigest": "239414b93a2165625ea54f124377ad270355ca8c0764f4ff2a8ebc9ad78f2832",
2384
- "workflowRegistryDigest": "7ec4a7f4f2d81ec294a4b961f6f991c3e90bacb6f516a5138736399d461d9aee",
2385
- "pageRegistryDigest": "23c900280e3c30ca9886d74a5f744961f2b2c5a202743d264d423f0bb29c9eee"
2437
+ "cliRegistryDigest": "1f7e1f7707a089f067175030fde6712b69ceece3df1b811eb542b0b4c8c1d4a9",
2438
+ "workflowRegistryDigest": "5a74fd4e5b7b071f014b59d590313535da05e7a96d46b82db0bc306182911395",
2439
+ "pageRegistryDigest": "a32dc62d72d1499d3156711aa51c58c0a19be4cace798617815c98c733e43f8e"
2386
2440
  },
2387
2441
  "comparison": {
2388
2442
  "missingCliRegistry": [],
@@ -23,6 +23,7 @@
23
23
  "./readme-badges": "./packages/core/readme-badges.js",
24
24
  "./public-surface-audit": "./packages/core/public-surface-audit.js",
25
25
  "./logging": "./packages/core/logging.js",
26
+ "./publication-artifact": "./packages/core/publication-artifact.js",
26
27
  "./kfd-gate": "./packages/core/kfd-gate.js",
27
28
  "./release-candidate": "./packages/core/release-candidate.js",
28
29
  "./release-passport": "./packages/core/release-passport.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-manifest",
4
- "generatedAt": "2026-07-09T00:25:26.922Z",
5
- "publishedAt": "2026-07-09T00:25:26.922Z",
4
+ "generatedAt": "2026-07-09T01:16:31.067Z",
5
+ "publishedAt": "2026-07-09T01:16:31.067Z",
6
6
  "reproducible": true,
7
7
  "timestampPolicy": "ci-injected",
8
8
  "deterministicInputs": [
@@ -19,7 +19,7 @@
19
19
  "declared Buildchain surface manifest contract"
20
20
  ],
21
21
  "sourceDateEpoch": "0",
22
- "sourceRevision": "bdd863e4ac8fa7b502a23f7e9a8faf9d31535c19",
22
+ "sourceRevision": "227aeefaff9a5bbf881d7fb903d39544ef0624af",
23
23
  "timestampPolicyDetails": {
24
24
  "contract": "kungfu-buildchain-surface-timestamp-policy",
25
25
  "timestampFields": [
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "package": {
39
39
  "name": "@kungfu-tech/buildchain",
40
- "version": "2.10.9",
40
+ "version": "2.10.10",
41
41
  "versionSource": "package.json#version"
42
42
  },
43
43
  "entrypoint": "buildchain-site.json",
@@ -53,7 +53,7 @@
53
53
  "path": "docs/MAP.md",
54
54
  "plane": "use",
55
55
  "exists": true,
56
- "digest": "sha256:b12caa887a325820c591d462ae2c0a4521eda001cb71d3def72e9b55924f892f"
56
+ "digest": "sha256:2295adcb4860c46a6f7fb39a0790d7347d916a0ac999d862437698d194af31de"
57
57
  },
58
58
  {
59
59
  "id": "install",
@@ -173,7 +173,7 @@
173
173
  "path": "docs/cli.md",
174
174
  "plane": "use",
175
175
  "exists": true,
176
- "digest": "sha256:b6bc32831d202d5c542d72f6e63322f632014751e7db00862b28fb9ce5318fd3"
176
+ "digest": "sha256:35df4de8a3ade449bb577b50ac3000adb2eafe354fd2f885f408ffe6e86d5f19"
177
177
  },
178
178
  {
179
179
  "id": "build-facts",
@@ -253,7 +253,7 @@
253
253
  "path": "docs/web-surface-deployments.md",
254
254
  "plane": "use",
255
255
  "exists": true,
256
- "digest": "sha256:cae39c60ffa0da5eb963a49d8d4ad6294788b1b76a8ba2516de75b263b3b8504"
256
+ "digest": "sha256:e5792a28aac1b2502a91f0cafd06dd52a4eecbcfb1f8df349c5aed16229777ec"
257
257
  }
258
258
  ],
259
259
  "facts": [
@@ -270,6 +270,7 @@
270
270
  "production-approved",
271
271
  "production-aws-role-arn",
272
272
  "production-environment",
273
+ "production-release-app-client-id",
273
274
  "production-release-app-id",
274
275
  "production-release-branch-channel",
275
276
  "production-release-head-prefix",
@@ -284,7 +285,7 @@
284
285
  "verify-command",
285
286
  "working-directory"
286
287
  ],
287
- "inputCount": 32,
288
+ "inputCount": 33,
288
289
  "surface": "reusable-workflow",
289
290
  "capabilityGroup": "api-cli-reference",
290
291
  "status": "active"
@@ -528,6 +529,29 @@
528
529
  "capabilityGroup": "governance-versioning",
529
530
  "status": "active"
530
531
  },
532
+ {
533
+ "id": "publication-artifact",
534
+ "path": ".github/workflows/publication-artifact.yml",
535
+ "inputs": [
536
+ "artifact-name",
537
+ "artifact-paths",
538
+ "artifact-retention-days",
539
+ "build-command",
540
+ "buildchain-contract-compatibility-policy",
541
+ "buildchain-contract-drift-issue-mode",
542
+ "buildchain-contract-lock-path",
543
+ "buildchain-ref",
544
+ "buildchain-repository",
545
+ "node-version",
546
+ "setup-node",
547
+ "verify-command",
548
+ "working-directory"
549
+ ],
550
+ "inputCount": 13,
551
+ "surface": "repository-workflow",
552
+ "capabilityGroup": "reusable-build",
553
+ "status": "active"
554
+ },
531
555
  {
532
556
  "id": "release-candidate-promote",
533
557
  "path": ".github/workflows/release-candidate-promote.yml",
package/docs/MAP.md CHANGED
@@ -31,6 +31,7 @@ workflow, action, and Node API export also carries a `capabilityGroup`,
31
31
  | Reusable Build and Lifecycle | `workflow-registry.json`, `release-model.json` | [`reusable-build-surface.md`](reusable-build-surface.md), [`lifecycle-protocol.md`](lifecycle-protocol.md) |
32
32
  | KFD Trust and Surface Closure | `kfd-claims.json`, `public-surface-audit.json`, `cli-registry.json`, `node-api-registry.json` | [`kfd-support.md`](kfd-support.md), [`release-passport.md`](release-passport.md) |
33
33
  | Site Bundle, Web Surfaces, and Propagation | `buildchain-site.json`, `site-manifest.json`, `page-registry.json`, `release-model.json` | [`site-bundle-contract.md`](site-bundle-contract.md), [`web-surface-deployments.md`](web-surface-deployments.md), [`release-propagation.md`](release-propagation.md) |
34
+ | Publication Artifacts | `workflow-registry.json`, `node-api-registry.json`, `manual-registry.json` | [`publication-artifacts.md`](publication-artifacts.md), [`reusable-build-surface.md`](reusable-build-surface.md) |
34
35
  | Distribution Indexes and Badges | `badge-endpoint-registry.json`, `node-api-registry.json`, `manual-registry.json` | [`readme-badges.md`](readme-badges.md), [`homebrew.md`](homebrew.md) |
35
36
  | Build Facts, Observability, and Diagnostics | `cli-registry.json`, `node-api-registry.json`, lifecycle artifacts | [`build-facts.md`](build-facts.md), [`toolkit-observability.md`](toolkit-observability.md), [`consumer-issue-reporting.md`](consumer-issue-reporting.md) |
36
37
  | Governance, Versioning, and Runtime Drift | `buildchain-contract.json`, `workflow-registry.json`, `release-model.json` | [`release-governance.md`](release-governance.md), [`release-flow.md`](release-flow.md), [`versioning.md`](versioning.md), [`runtime-train-validation.md`](runtime-train-validation.md) |
@@ -47,6 +48,7 @@ workflow, action, and Node API export also carries a `capabilityGroup`,
47
48
  | Git/source/version/module/product build facts | `dist/site/node-api-registry.json`, `dist/site/cli-registry.json`, `kungfu-buildchain-module-build-facts`, `kungfu-buildchain-product-build-facts` | [`build-facts.md`](build-facts.md) |
48
49
  | GitHub Release passport/evidence publication | `dist/site/release-model.json`, `dist/site/artifact-schemas.json` | [`release-governance.md`](release-governance.md), [`release-candidate.md`](release-candidate.md) |
49
50
  | release propagation for package/site chains | `dist/site/release-model.json` | [`release-propagation.md`](release-propagation.md) |
51
+ | publication artifact manifests, source bundles, and paper repository workflows | `dist/site/workflow-registry.json`, `dist/site/node-api-registry.json`, `kungfu-buildchain-publication-artifact-manifest` | [`publication-artifacts.md`](publication-artifacts.md) |
50
52
  | Generated badge bundles, README badge blocks, and badge facts | `dist/site/node-api-registry.json`, `dist/site/manual-registry.json`, `kungfu-buildchain-badge-bundle-facts`, `kungfu-buildchain-readme-badge-facts` | [`readme-badges.md`](readme-badges.md) |
51
53
  | Homebrew tap distribution indexes | `dist/site/node-api-registry.json`, `dist/site/buildchain-contract.json` | [`homebrew.md`](homebrew.md) |
52
54
  | Buildchain CLI manual | `dist/site/cli-registry.json`, `dist/site/manual-registry.json` | [`cli.md`](cli.md) |
@@ -85,6 +87,7 @@ replace them.
85
87
  | How do I detect, register, audit, witness, or query KFD-3 product surfaces? | [`kfd-support.md`](kfd-support.md) + [`cli.md`](cli.md) | verify/use | stable |
86
88
  | How do I keep `@v2` floating refs while detecting Buildchain contract drift? | [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock) | verify/use | stable |
87
89
  | How do I propagate finalized upstream releases to downstream package/site PRs? | [`release-propagation.md`](release-propagation.md) | use | preview |
90
+ | How do paper or report repositories publish PDFs, metadata, source bundles, and site-consumable manifests? | [`publication-artifacts.md`](publication-artifacts.md) | use | stable |
88
91
  | How do I generate KFD / Release Passport badge bundles without hand-maintaining Markdown? | [`readme-badges.md`](readme-badges.md) + [`cli.md`](cli.md) | use | stable |
89
92
  | How do I generate and verify a Homebrew tap from release passport evidence? | [`homebrew.md`](homebrew.md) + [`cli.md`](cli.md) | use/verify | stable |
90
93
  | How do I prove a PR-stage reusable build is the artifact source promoted later? | [`release-candidate.md`](release-candidate.md) + [`reusable-build-surface.md`](reusable-build-surface.md) | verify | stable |
@@ -99,7 +102,7 @@ replace them.
99
102
  | How do I publish observed infrastructure contracts for downstream consumers? | [`infra-contract.md`](infra-contract.md) | use | preview |
100
103
  | How do I use the active actions directly? | [`../actions/validate-config/README.md`](../actions/validate-config/README.md), [`../actions/run-lifecycle/README.md`](../actions/run-lifecycle/README.md), [`../actions/promote-buildchain-ref/README.md`](../actions/promote-buildchain-ref/README.md), [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md) | use | stable |
101
104
  | How can a consumer workflow report a Buildchain-owned failure back to Buildchain? | [`consumer-issue-reporting.md`](consumer-issue-reporting.md) + [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md) | use | stable |
102
- | What do the fixture repositories demonstrate? | [`../fixtures/libnode-shaped/README.md`](../fixtures/libnode-shaped/README.md), [`../fixtures/publish-transaction-shaped/README.md`](../fixtures/publish-transaction-shaped/README.md), [`../fixtures/web-surface-shaped/README.md`](../fixtures/web-surface-shaped/README.md) | verify | stable |
105
+ | What do the fixture repositories demonstrate? | [`../fixtures/libnode-shaped/README.md`](../fixtures/libnode-shaped/README.md), [`../fixtures/publish-transaction-shaped/README.md`](../fixtures/publish-transaction-shaped/README.md), [`../fixtures/web-surface-shaped/README.md`](../fixtures/web-surface-shaped/README.md), [`../fixtures/publication-artifact-shaped/README.md`](../fixtures/publication-artifact-shaped/README.md) | verify | stable |
103
106
  | What license and contribution terms apply? | [`../LICENSE`](../LICENSE) + [`../LICENSE-POLICY.md`](../LICENSE-POLICY.md) | use | stable |
104
107
  | What trademark, official-service, and provider-compliance boundaries apply? | [`../TRADEMARK.md`](../TRADEMARK.md) + [`../ACCEPTABLE_USE.md`](../ACCEPTABLE_USE.md) + [`../PROVIDER_COMPLIANCE.md`](../PROVIDER_COMPLIANCE.md) | use | stable |
105
108
  | How do I report a vulnerability? | [`../SECURITY.md`](../SECURITY.md) | use | stable |
@@ -148,6 +151,8 @@ replace them.
148
151
  Kungfu build info** -> [`build-facts.md`](build-facts.md) and [`cli.md`](cli.md).
149
152
  - **release chains / upstream package as source of truth / site synchronization** ->
150
153
  [`release-propagation.md`](release-propagation.md).
154
+ - **paper repositories / PDFs / publication manifests / source bundles** ->
155
+ [`publication-artifacts.md`](publication-artifacts.md).
151
156
  - **README status badges / KFD badge bundles / badge facts JSON** ->
152
157
  [`readme-badges.md`](readme-badges.md) and [`cli.md`](cli.md).
153
158
  - **Homebrew taps / distribution indexes / Formula drift checks** ->
package/docs/cli.md CHANGED
@@ -102,6 +102,9 @@ Supported presets:
102
102
  validation, observation, contract publication, and downstream propagation
103
103
  planning without default mutation. Provider adapters expose built-in command
104
104
  plans by default, and only configured `[infra.commands]` hooks can execute.
105
+ - `--type publication-artifact` for papers, reports, specifications, and other
106
+ publication repositories that produce PDFs, metadata, source bundles, and
107
+ site-consumable manifests without becoming web-surface repositories.
105
108
  - `--type distribution-index` for Homebrew taps and other index repositories
106
109
  whose files are projections of upstream release passport evidence.
107
110
  - `--type anchored-package` for packages whose version is anchored to an
@@ -378,11 +381,25 @@ version against configured version files and the anchor manifest. The JSON
378
381
  result is shaped for future `buildchain.libkungfu.dev` fact ingestion.
379
382
 
380
383
  `buildchain release`, `buildchain web-surface`, `buildchain infra-contract`,
381
- `buildchain publish-source`, `buildchain badges`, `buildchain homebrew`, and
382
- `buildchain build-contract` route to the same implementation used by
384
+ `buildchain publication-artifact`, `buildchain publish-source`,
385
+ `buildchain badges`, `buildchain homebrew`, and `buildchain build-contract`
386
+ route to the same implementation used by
383
387
  Buildchain's package APIs or GitHub Actions workflows. This keeps local
384
388
  inspection and CI behavior on the same implementation path.
385
389
 
390
+ Generate publication artifact metadata after building a paper or report:
391
+
392
+ ```bash
393
+ buildchain publication-artifact manifest \
394
+ --source-sha "$(git rev-parse HEAD)" \
395
+ --json
396
+ ```
397
+
398
+ The command writes `.buildchain/publication/publication-artifact.json`,
399
+ `.buildchain/publication/publication-artifact-passport.json`, and a source
400
+ bundle by default. See [`publication-artifacts.md`](publication-artifacts.md)
401
+ for the repository contract and reusable workflow.
402
+
386
403
  Generate, check, or update the managed README badge block:
387
404
 
388
405
  ```bash
@@ -0,0 +1,126 @@
1
+ # Publication Artifact Workflow
2
+
3
+ Buildchain supports `project.type = "publication-artifact"` for repositories
4
+ that produce auditable papers, reports, specifications, or similar publication
5
+ packages. These repositories are artifact producers. They should not be forced
6
+ to become `web-surface` repositories just because a downstream site later
7
+ renders the paper.
8
+
9
+ The split is:
10
+
11
+ ```text
12
+ paper repo = source, PDF, metadata, source bundle, publication manifest
13
+ papers site = layout, navigation, public web surface, downstream rendering
14
+ ```
15
+
16
+ ## Configuration
17
+
18
+ The paper repository owns `.buildchain/buildchain.toml`:
19
+
20
+ ```toml
21
+ schema = 1
22
+
23
+ [project]
24
+ type = "publication-artifact"
25
+ name = "paper-observer-declared-timelines"
26
+
27
+ [publication]
28
+ kind = "paper"
29
+ title = "Observer-Declared Timelines for Real-World Agent Work"
30
+ primary_artifact = "_build/main.pdf"
31
+ artifact_paths = ["_build/main.pdf"]
32
+ metadata_paths = ["README.md", "docs/MAP.md"]
33
+ source_paths = ["paper", "README.md", "LICENSE", "Makefile"]
34
+ site_consumers = ["papers.libkungfu.dev"]
35
+ manifest_path = ".buildchain/publication/publication-artifact.json"
36
+ source_bundle_path = ".buildchain/publication/source.tar.gz"
37
+
38
+ [lifecycle.build]
39
+ command = "make pdf"
40
+
41
+ [lifecycle.verify]
42
+ command = "make check"
43
+ ```
44
+
45
+ `primary_artifact` is the human-facing publication output, usually a PDF.
46
+ `source_paths` are archived into a source bundle. `metadata_paths` are hashed
47
+ and recorded so a site can consume the paper facts without scraping prose.
48
+
49
+ ## Reusable Workflow
50
+
51
+ Consumer repositories can call the Buildchain wrapper directly:
52
+
53
+ ```yaml
54
+ jobs:
55
+ publication:
56
+ uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2
57
+ with:
58
+ build-command: make pdf
59
+ verify-command: make check
60
+ artifact-name: observer-declared-timelines
61
+ buildchain-contract-lock-path: .buildchain/contract-lock.json
62
+ ```
63
+
64
+ The workflow:
65
+
66
+ - resolves the Buildchain runtime and checks the floating contract lock before
67
+ any paper build runs;
68
+ - runs the declared build and verify commands;
69
+ - creates a source bundle from `publication.source_paths`;
70
+ - writes `.buildchain/publication/publication-artifact.json`;
71
+ - writes `.buildchain/publication/publication-artifact-passport.json`;
72
+ - uploads one GitHub artifact containing the PDF, manifest, passport, and
73
+ source bundle.
74
+
75
+ The wrapper is build-only. It does not publish npm packages, deploy web pages,
76
+ or create GitHub Releases. Release publication can be layered later by a
77
+ repository-specific governance workflow that attaches the generated manifest
78
+ and passport as release assets.
79
+
80
+ ## CLI And Node API
81
+
82
+ Generate the publication manifest locally or in CI:
83
+
84
+ ```sh
85
+ buildchain publication-artifact manifest --source-sha "$(git rev-parse HEAD)" --json
86
+ ```
87
+
88
+ Node API:
89
+
90
+ ```js
91
+ import {
92
+ collectPublicationArtifact,
93
+ writePublicationArtifact,
94
+ } from "@kungfu-tech/buildchain/publication-artifact";
95
+ ```
96
+
97
+ `writePublicationArtifact()` is the single implementation used by the CLI and
98
+ the reusable workflow. The generated manifest records:
99
+
100
+ - publication title, kind, authors, and primary artifact;
101
+ - artifact paths, byte sizes, and SHA-256 digests;
102
+ - metadata paths and SHA-256 digests;
103
+ - source SHA, tree SHA, source files, and source bundle digest;
104
+ - timestamp and reproducibility policy;
105
+ - downstream site-consumption hints.
106
+
107
+ The companion publication artifact passport records the same source and
108
+ artifact evidence plus an explicit responsibility split. Buildchain proves
109
+ declared files and hashes; it does not peer-review paper claims.
110
+
111
+ ## Site Consumption
112
+
113
+ A downstream papers site should treat the publication manifest as the single
114
+ fact source for the artifact. The site owns rendering and navigation; it should
115
+ not reinterpret the paper repository as a web deployment source.
116
+
117
+ For `paper-observer-declared-timelines`, the expected adoption path is:
118
+
119
+ ```text
120
+ paper repo builds PDF + manifest + source bundle
121
+ papers site consumes publication-artifact.json
122
+ site renders paper page and links the PDF/source bundle
123
+ ```
124
+
125
+ This mirrors web-surface governance without mixing producer and renderer
126
+ responsibilities.
@@ -726,17 +726,23 @@ jobs:
726
726
  Automatic release PR creation normally uses the workflow `github.token`.
727
727
  Consumers that cannot enable "GitHub Actions can create and approve pull
728
728
  requests" globally should prefer the first-class GitHub App path. Pass the App
729
- id as an input and the private key as a reusable workflow secret; Buildchain
729
+ client id as an input and the private key as a reusable workflow secret; Buildchain
730
730
  creates an installation token inside the release PR job and uses it only for the
731
731
  release-intent branch, PR, and label operations:
732
732
 
733
733
  ```yaml
734
734
  with:
735
- production-release-app-id: ${{ vars.KUNGFU_RELEASE_APP_ID }}
735
+ production-release-app-client-id: ${{ vars.KUNGFU_RELEASE_APP_CLIENT_ID }}
736
736
  secrets:
737
737
  production-release-app-private-key: ${{ secrets.KUNGFU_RELEASE_APP_PRIVATE_KEY }}
738
738
  ```
739
739
 
740
+ `production-release-app-id` remains accepted as a deprecated alias for the input
741
+ name, but the value should be the GitHub App client id. GitHub App numeric App
742
+ IDs and client IDs are distinct, and Buildchain passes the value to
743
+ `actions/create-github-app-token` through its non-deprecated `client-id` input so
744
+ new runs do not emit the deprecated `app-id` warning.
745
+
740
746
  If a repository already generates its own narrow token or PAT, it can still pass
741
747
  that through `production-release-pr-token`:
742
748
 
@@ -0,0 +1,11 @@
1
+ # Publication Artifact Fixture
2
+
3
+ This fixture models a paper repository that produces publication artifacts
4
+ without becoming a web-surface repository.
5
+
6
+ It declares:
7
+
8
+ - `project.type = "publication-artifact"`;
9
+ - a primary PDF artifact;
10
+ - source paths that Buildchain archives into a source bundle;
11
+ - metadata paths that a future papers site can consume as a single fact source.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungfu-tech/buildchain",
3
- "version": "2.10.9",
3
+ "version": "2.10.10",
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",
@@ -26,6 +26,7 @@
26
26
  "./readme-badges": "./packages/core/readme-badges.js",
27
27
  "./public-surface-audit": "./packages/core/public-surface-audit.js",
28
28
  "./logging": "./packages/core/logging.js",
29
+ "./publication-artifact": "./packages/core/publication-artifact.js",
29
30
  "./kfd-gate": "./packages/core/kfd-gate.js",
30
31
  "./release-candidate": "./packages/core/release-candidate.js",
31
32
  "./release-passport": "./packages/core/release-passport.js",
@@ -18,6 +18,8 @@ Current shared surfaces:
18
18
  `@kungfu-tech/buildchain/release-passport`.
19
19
  - managed KFD / Release Passport badge bundle facts and README marker blocks
20
20
  through `@kungfu-tech/buildchain/badges`.
21
+ - publication artifact manifests, source bundles, and publication artifact
22
+ passports through `@kungfu-tech/buildchain/publication-artifact`.
21
23
 
22
24
  ## Toolkit Imports
23
25
 
@@ -64,6 +66,15 @@ const fact = collectModuleBuildFacts({ moduleId: "native-core" });
64
66
  writeBuildFacts({ fact, output: ".buildchain/facts/native-core.json" });
65
67
  ```
66
68
 
69
+ Publication repositories can produce site-consumable paper/report facts without
70
+ becoming web-surface repositories:
71
+
72
+ ```js
73
+ import { writePublicationArtifact } from "@kungfu-tech/buildchain/publication-artifact";
74
+
75
+ writePublicationArtifact({ sourceSha: process.env.GITHUB_SHA });
76
+ ```
77
+
67
78
  Web-surface validation stays in core because both local scripts and GitHub
68
79
  Actions need the same fail-closed interpretation of project, channel, deploy,
69
80
  retention, and staging security declarations.
@@ -13,7 +13,7 @@ const RESERVED_LIFECYCLE_KEYS = new Set(["env", "shell"]);
13
13
  const SUPPORTED_VERSION_FILE_TYPES = new Set(["json", "toml", "regex"]);
14
14
  const SUPPORTED_VERSION_STRATEGIES = new Set(["semver", "anchored"]);
15
15
  const SUPPORTED_VERSION_NEXT = new Set(["auto", "manual"]);
16
- const SUPPORTED_PROJECT_TYPES = new Set(["package", "web-surface", "infra-contract", "distribution-index"]);
16
+ const SUPPORTED_PROJECT_TYPES = new Set(["package", "web-surface", "infra-contract", "distribution-index", "publication-artifact"]);
17
17
  const SUPPORTED_PUBLISH_MODES = new Set(["publish-final-version", "promote-existing-version"]);
18
18
  const SUPPORTED_PUBLISH_AUTH = new Set(["trusted-publishing", "npm-token"]);
19
19
  const SUPPORTED_PACKAGE_SET_ORDER = new Set(["as-provided", "platforms-first-main-last"]);
@@ -147,6 +147,9 @@ export function normalizeBuildchainConfig(config) {
147
147
  if (normalized.infra !== undefined) {
148
148
  normalized.infra = normalizeInfraSection(normalized.infra);
149
149
  }
150
+ if (normalized.publication !== undefined) {
151
+ normalized.publication = normalizePublicationSection(normalized.publication);
152
+ }
150
153
  if (normalized.consumers !== undefined) {
151
154
  normalized.consumers = normalizeConsumersSection(normalized.consumers);
152
155
  }
@@ -357,7 +360,7 @@ function normalizeProjectSection(project) {
357
360
  assertPlainObject(project, "project");
358
361
  const type = assertString(project.type, "project.type");
359
362
  if (!SUPPORTED_PROJECT_TYPES.has(type)) {
360
- throw new Error("project.type must be one of package, web-surface, infra-contract, or distribution-index");
363
+ throw new Error("project.type must be one of package, web-surface, infra-contract, distribution-index, or publication-artifact");
361
364
  }
362
365
  const normalized = { type };
363
366
  for (const key of ["name", "site"]) {
@@ -368,6 +371,33 @@ function normalizeProjectSection(project) {
368
371
  return normalized;
369
372
  }
370
373
 
374
+ function normalizePublicationSection(publication) {
375
+ assertPlainObject(publication, "publication");
376
+ const kind = publication.kind === undefined ? "paper" : assertString(publication.kind, "publication.kind");
377
+ if (!["paper", "report", "specification", "article", "dataset-note"].includes(kind)) {
378
+ throw new Error("publication.kind must be one of paper, report, specification, article, or dataset-note");
379
+ }
380
+ const primaryArtifact = posixPath(assertString(publication.primary_artifact, "publication.primary_artifact"));
381
+ return {
382
+ kind,
383
+ title: assertString(publication.title, "publication.title"),
384
+ primaryArtifact,
385
+ version: publication.version === undefined ? "" : assertString(publication.version, "publication.version"),
386
+ abstract: publication.abstract === undefined ? "" : assertString(publication.abstract, "publication.abstract"),
387
+ authors: normalizeStringArray(publication.authors, "publication.authors"),
388
+ artifactPaths: normalizeStringArray(publication.artifact_paths, "publication.artifact_paths").map(posixPath),
389
+ metadataPaths: normalizeStringArray(publication.metadata_paths, "publication.metadata_paths").map(posixPath),
390
+ sourcePaths: normalizeStringArray(publication.source_paths, "publication.source_paths").map(posixPath),
391
+ siteConsumers: normalizeStringArray(publication.site_consumers, "publication.site_consumers"),
392
+ manifestPath: publication.manifest_path === undefined
393
+ ? ".buildchain/publication/publication-artifact.json"
394
+ : posixPath(assertString(publication.manifest_path, "publication.manifest_path")),
395
+ sourceBundlePath: publication.source_bundle_path === undefined
396
+ ? ".buildchain/publication/source.tar.gz"
397
+ : posixPath(assertString(publication.source_bundle_path, "publication.source_bundle_path")),
398
+ };
399
+ }
400
+
371
401
  function normalizeInfraSection(infra) {
372
402
  assertPlainObject(infra, "infra");
373
403
  const adapter = assertString(infra.adapter, "infra.adapter");
@@ -1203,6 +1233,7 @@ export function validateBuildchainConfig(
1203
1233
  lifecycleStages,
1204
1234
  publish: loadedConfig.config.publish,
1205
1235
  facts: loadedConfig.config.facts,
1236
+ publication: loadedConfig.config.publication,
1206
1237
  };
1207
1238
  }
1208
1239
 
@@ -185,6 +185,14 @@ export {
185
185
  enumerateWorkflowInputs,
186
186
  } from "./public-surface-audit.js";
187
187
 
188
+ export {
189
+ PUBLICATION_ARTIFACT_MANIFEST_CONTRACT,
190
+ PUBLICATION_ARTIFACT_PASSPORT_CONTRACT,
191
+ collectPublicationArtifact,
192
+ createPublicationSourceBundle,
193
+ writePublicationArtifact,
194
+ } from "./publication-artifact.js";
195
+
188
196
  export {
189
197
  AGENT_INDEX_CONTRACT,
190
198
  ARTIFACT_EVIDENCE_CONTRACT,
@@ -73,6 +73,10 @@ function commandId(first = "", second = "", third = "") {
73
73
  if (head === "homebrew" && sub) return `homebrew-${sub}`;
74
74
  if (head === "release-propagation") return "release-propagation";
75
75
  if (head === "publish-source") return "publish-source";
76
+ if (head === "publication-artifact" && sub) return `publication-artifact-${sub}`;
77
+ if (head === "publication-artifact") return "publication-artifact";
78
+ if (head === "publication" && sub) return `publication-artifact-${sub}`;
79
+ if (head === "publication") return "publication-artifact";
76
80
  if (head === "build-contract") return "build-contract";
77
81
  if (head === "infra-contract") return "infra-contract";
78
82
  if (head === "web-surface") return "web-surface";