@kungfu-tech/buildchain 2.10.10 → 2.10.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.
@@ -4,7 +4,7 @@
4
4
  "product": {
5
5
  "name": "Buildchain",
6
6
  "package": "@kungfu-tech/buildchain",
7
- "version": "2.10.10",
7
+ "version": "2.10.11",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "majorLine": "v2",
@@ -92,7 +92,7 @@
92
92
  "GitHub Release passport and evidence publication is delegated to promote-buildchain-ref after the semver release transaction completes"
93
93
  ],
94
94
  "breakingDigest": "sha256:403d2fcdb0c5eabe749e89102defad69745f70a1556707bec7831fcc2e9fa8f8",
95
- "auditDigest": "sha256:b3e96fe1d01793481dcf507373b7856a9b29451d168b18cd0f149517cb61ffde"
95
+ "auditDigest": "sha256:db6fe83e886a04221cc2457d3bdf091cd8607083d5c5e4dc87f40220c2436581"
96
96
  },
97
97
  {
98
98
  "contractVersion": 1,
@@ -134,7 +134,7 @@
134
134
  "breaking contract drift fails closed before rendering, deployment, or release publication"
135
135
  ],
136
136
  "breakingDigest": "sha256:82ee63cb336e40d832dfff4a1c5e6cbfa221a4fc8b2359990033bc931bffc43a",
137
- "auditDigest": "sha256:fdb586f033b0bcbe2455b1f9e1ced419d22b715fcdcb5d096265b741471cac9a"
137
+ "auditDigest": "sha256:623e5222b8e649b40a05817fabf4c7fd8052a3e64636e74eb7a7bbcfd9de4998"
138
138
  },
139
139
  {
140
140
  "contractVersion": 1,
@@ -456,9 +456,9 @@
456
456
  "agents can discover supported Node APIs without importing internal file paths"
457
457
  ],
458
458
  "breakingDigest": "sha256:48f925608d3e2131d90936b07dc2a30341204cae3e6e785c0f77d61ad755c945",
459
- "auditDigest": "sha256:44685053beb1571e543d5912009acea8eb29e13ca9bb96baffb10e87805dfcbf"
459
+ "auditDigest": "sha256:983094d1f0d421294e6c542232a5483c408aa72352883b851e1e2ecff1f9e8b5"
460
460
  }
461
461
  ],
462
462
  "compatibilityDigest": "sha256:967df7e854fdf582294ddfb6403eff25c00db9518a24051e7d47cbd75527c785",
463
- "contractDigest": "sha256:3ed710d73ac54819396ec372044ec633230fac360b8cad972b4318044d782538"
463
+ "contractDigest": "sha256:b420ce7d38f966d3a2d72b31ef43490f9720bf0733d1848b1cc497c4a6ac5643"
464
464
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-bundle",
4
- "generatedAt": "2026-07-09T01:16:31.067Z",
5
- "publishedAt": "2026-07-09T01:16:31.067Z",
4
+ "generatedAt": "2026-07-09T03:20:50.735Z",
5
+ "publishedAt": "2026-07-09T03:20:50.735Z",
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": "227aeefaff9a5bbf881d7fb903d39544ef0624af",
22
+ "sourceRevision": "c7e618f57355231a8f27fd628ee9499bd5b8e9fd",
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.10",
40
+ "version": "2.10.11",
41
41
  "versionSource": "package.json#version"
42
42
  },
43
43
  "source": {
@@ -965,7 +965,7 @@
965
965
  ],
966
966
  "maturity": "stable",
967
967
  "sourcePath": "docs/publication-artifacts.md",
968
- "digest": "sha256:ef8f4cc214b5fb5f6214796e7688ea897eddb5bc9dd9135638500ce9a1e18c92",
968
+ "digest": "sha256:06ba810c9eb13d47e408c74d58442635727396da66ed90fd4d505f2ff031cc18",
969
969
  "headings": [
970
970
  {
971
971
  "level": 1,
@@ -993,7 +993,7 @@
993
993
  "anchor": "site-consumption"
994
994
  }
995
995
  ],
996
- "markdown": "# Publication Artifact Workflow\n\nBuildchain supports `project.type = \"publication-artifact\"` for repositories\nthat produce auditable papers, reports, specifications, or similar publication\npackages. These repositories are artifact producers. They should not be forced\nto become `web-surface` repositories just because a downstream site later\nrenders the paper.\n\nThe split is:\n\n```text\npaper repo = source, PDF, metadata, source bundle, publication manifest\npapers site = layout, navigation, public web surface, downstream rendering\n```\n\n## Configuration\n\nThe paper repository owns `.buildchain/buildchain.toml`:\n\n```toml\nschema = 1\n\n[project]\ntype = \"publication-artifact\"\nname = \"paper-observer-declared-timelines\"\n\n[publication]\nkind = \"paper\"\ntitle = \"Observer-Declared Timelines for Real-World Agent Work\"\nprimary_artifact = \"_build/main.pdf\"\nartifact_paths = [\"_build/main.pdf\"]\nmetadata_paths = [\"README.md\", \"docs/MAP.md\"]\nsource_paths = [\"paper\", \"README.md\", \"LICENSE\", \"Makefile\"]\nsite_consumers = [\"papers.libkungfu.dev\"]\nmanifest_path = \".buildchain/publication/publication-artifact.json\"\nsource_bundle_path = \".buildchain/publication/source.tar.gz\"\n\n[lifecycle.build]\ncommand = \"make pdf\"\n\n[lifecycle.verify]\ncommand = \"make check\"\n```\n\n`primary_artifact` is the human-facing publication output, usually a PDF.\n`source_paths` are archived into a source bundle. `metadata_paths` are hashed\nand recorded so a site can consume the paper facts without scraping prose.\n\n## Reusable Workflow\n\nConsumer repositories can call the Buildchain wrapper directly:\n\n```yaml\njobs:\n publication:\n uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2\n with:\n build-command: make pdf\n verify-command: make check\n artifact-name: observer-declared-timelines\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe workflow:\n\n- resolves the Buildchain runtime and checks the floating contract lock before\n any paper build runs;\n- runs the declared build and verify commands;\n- creates a source bundle from `publication.source_paths`;\n- writes `.buildchain/publication/publication-artifact.json`;\n- writes `.buildchain/publication/publication-artifact-passport.json`;\n- uploads one GitHub artifact containing the PDF, manifest, passport, and\n source bundle.\n\nThe wrapper is build-only. It does not publish npm packages, deploy web pages,\nor create GitHub Releases. Release publication can be layered later by a\nrepository-specific governance workflow that attaches the generated manifest\nand passport as release assets.\n\n## CLI And Node API\n\nGenerate the publication manifest locally or in CI:\n\n```sh\nbuildchain publication-artifact manifest --source-sha \"$(git rev-parse HEAD)\" --json\n```\n\nNode API:\n\n```js\nimport {\n collectPublicationArtifact,\n writePublicationArtifact,\n} from \"@kungfu-tech/buildchain/publication-artifact\";\n```\n\n`writePublicationArtifact()` is the single implementation used by the CLI and\nthe reusable workflow. The generated manifest records:\n\n- publication title, kind, authors, and primary artifact;\n- artifact paths, byte sizes, and SHA-256 digests;\n- metadata paths and SHA-256 digests;\n- source SHA, tree SHA, source files, and source bundle digest;\n- timestamp and reproducibility policy;\n- downstream site-consumption hints.\n\nThe companion publication artifact passport records the same source and\nartifact evidence plus an explicit responsibility split. Buildchain proves\ndeclared files and hashes; it does not peer-review paper claims.\n\n## Site Consumption\n\nA downstream papers site should treat the publication manifest as the single\nfact source for the artifact. The site owns rendering and navigation; it should\nnot reinterpret the paper repository as a web deployment source.\n\nFor `paper-observer-declared-timelines`, the expected adoption path is:\n\n```text\npaper repo builds PDF + manifest + source bundle\npapers site consumes publication-artifact.json\nsite renders paper page and links the PDF/source bundle\n```\n\nThis mirrors web-surface governance without mixing producer and renderer\nresponsibilities."
996
+ "markdown": "# Publication Artifact Workflow\n\nBuildchain supports `project.type = \"publication-artifact\"` for repositories\nthat produce auditable papers, reports, specifications, or similar publication\npackages. These repositories are artifact producers. They should not be forced\nto become `web-surface` repositories just because a downstream site later\nrenders the paper.\n\nThe split is:\n\n```text\npaper repo = source, PDF, metadata, source bundle, publication manifest\npapers site = layout, navigation, public web surface, downstream rendering\n```\n\n## Configuration\n\nThe paper repository owns `.buildchain/buildchain.toml`:\n\n```toml\nschema = 1\n\n[project]\ntype = \"publication-artifact\"\nname = \"paper-observer-declared-timelines\"\n\n[publication]\nkind = \"paper\"\ntitle = \"Observer-Declared Timelines for Real-World Agent Work\"\nprimary_artifact = \"_build/main.pdf\"\nartifact_paths = [\"_build/main.pdf\"]\nmetadata_paths = [\"README.md\", \"docs/MAP.md\"]\nsource_paths = [\"paper\", \"README.md\", \"LICENSE\", \"Makefile\"]\nsite_consumers = [\"papers.libkungfu.dev\"]\nmanifest_path = \".buildchain/publication/publication-artifact.json\"\nsource_bundle_path = \".buildchain/publication/source.tar.gz\"\n\n[publication.toolchain]\ntype = \"latex-docker\"\nimage = \"ghcr.io/kungfu-systems/latex\"\ndigest = \"sha256:0000000000000000000000000000000000000000000000000000000000000000\"\ncommand = \"latexmk -pdf -outdir=_build paper/main.tex\"\n\n[lifecycle.build]\ncommand = \"make pdf\"\n\n[lifecycle.verify]\ncommand = \"make check\"\n```\n\n`primary_artifact` is the human-facing publication output, usually a PDF.\n`source_paths` are archived into a source bundle. `metadata_paths` are hashed\nand recorded so a site can consume the paper facts without scraping prose.\n\n`publication.toolchain` makes the source-to-PDF transformation part of the\nmachine-readable contract. `latex-docker` is the preferred LaTeX profile: the\nworkflow pulls the declared image by digest and runs the declared command in\nthat pinned container. `custom-command` remains available for compatibility,\nbut the passport records it as lower trust because Buildchain can record the\ncommand boundary without proving the compiler or LaTeX distribution digest.\n\n## Reusable Workflow\n\nConsumer repositories can call the Buildchain wrapper directly:\n\n```yaml\njobs:\n publication:\n uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2\n with:\n toolchain-type: config\n verify-command: make check\n artifact-name: observer-declared-timelines\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe workflow:\n\n- resolves the Buildchain runtime and checks the floating contract lock before\n any paper build runs;\n- resolves the declared publication toolchain from `[publication.toolchain]` or\n workflow inputs;\n- for `latex-docker`, pulls the pinned image digest and runs the declared\n command in the container;\n- for `custom-command`, runs the declared command and records the lower-trust\n boundary in the passport;\n- runs the verify command;\n- creates a source bundle from `publication.source_paths`;\n- writes `.buildchain/publication/publication-artifact.json`;\n- writes `.buildchain/publication/publication-artifact-passport.json`;\n- uploads one GitHub artifact containing the PDF, manifest, passport, and\n source bundle.\n\nThe wrapper is build-only. It does not publish npm packages, deploy web pages,\nor create GitHub Releases. Release publication can be layered later by a\nrepository-specific governance workflow that attaches the generated manifest\nand passport as release assets.\n\n## CLI And Node API\n\nGenerate the publication manifest locally or in CI:\n\n```sh\nbuildchain publication-artifact manifest --source-sha \"$(git rev-parse HEAD)\" --json\n```\n\nNode API:\n\n```js\nimport {\n collectPublicationArtifact,\n writePublicationArtifact,\n} from \"@kungfu-tech/buildchain/publication-artifact\";\n```\n\n`writePublicationArtifact()` is the single implementation used by the CLI and\nthe reusable workflow. The generated manifest records:\n\n- publication title, kind, authors, and primary artifact;\n- artifact paths, byte sizes, and SHA-256 digests;\n- metadata paths and SHA-256 digests;\n- source SHA, tree SHA, source files, and source bundle digest;\n- publication toolchain type, image, digest, command, invocation mode, and trust\n classification;\n- timestamp and reproducibility policy;\n- downstream site-consumption hints.\n\nThe companion publication artifact passport records the same source and\nartifact evidence plus an explicit responsibility split. Buildchain proves\ndeclared files and hashes; it does not peer-review paper claims.\n\n## Site Consumption\n\nA downstream papers site should treat the publication manifest as the single\nfact source for the artifact. The site owns rendering and navigation; it should\nnot reinterpret the paper repository as a web deployment source.\n\nFor `paper-observer-declared-timelines`, the expected adoption path is:\n\n```text\npaper repo builds PDF + manifest + source bundle\npapers site consumes publication-artifact.json\nsite renders paper page and links the PDF/source bundle\n```\n\nThis mirrors web-surface governance without mixing producer and renderer\nresponsibilities."
997
997
  },
998
998
  {
999
999
  "id": "manual:publish-transaction",
@@ -21,7 +21,7 @@
21
21
  "contract": "kungfu-buildchain-public-surface-reverse-audit",
22
22
  "path": "dist/site/public-surface-audit.json",
23
23
  "status": "passed",
24
- "sha256": "7d22fa037b5c1c14ac2ca1853dd414bb83b2c561221034a49a97401f28672471",
24
+ "sha256": "a978e2407063ed5d118024da92e28916a90d7704d9948fea52b62e933f7387b4",
25
25
  "summary": {
26
26
  "cliCommandCount": 73,
27
27
  "workflowCount": 36,
@@ -207,7 +207,7 @@
207
207
  "contract": "kungfu-buildchain-public-surface-reverse-audit",
208
208
  "path": "dist/site/public-surface-audit.json",
209
209
  "status": "passed",
210
- "sha256": "7d22fa037b5c1c14ac2ca1853dd414bb83b2c561221034a49a97401f28672471",
210
+ "sha256": "a978e2407063ed5d118024da92e28916a90d7704d9948fea52b62e933f7387b4",
211
211
  "summary": {
212
212
  "cliCommandCount": 73,
213
213
  "workflowCount": 36,
@@ -2895,7 +2895,7 @@
2895
2895
  "visibility": "public",
2896
2896
  "participantFacing": true,
2897
2897
  "public": true,
2898
- "inputCount": 13,
2898
+ "inputCount": 17,
2899
2899
  "inputs": [
2900
2900
  "artifact-name",
2901
2901
  "artifact-paths",
@@ -2908,6 +2908,10 @@
2908
2908
  "buildchain-repository",
2909
2909
  "node-version",
2910
2910
  "setup-node",
2911
+ "toolchain-command",
2912
+ "toolchain-digest",
2913
+ "toolchain-image",
2914
+ "toolchain-type",
2911
2915
  "verify-command",
2912
2916
  "working-directory"
2913
2917
  ],
@@ -4,7 +4,7 @@
4
4
  "product": {
5
5
  "id": "kungfu-tech-buildchain",
6
6
  "name": "@kungfu-tech/buildchain",
7
- "version": "2.10.10",
7
+ "version": "2.10.11",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "source": {
@@ -203,7 +203,7 @@
203
203
  "specifier": "@kungfu-tech/buildchain/publication-artifact",
204
204
  "export": "./publication-artifact",
205
205
  "target": "./packages/core/publication-artifact.js",
206
- "digest": "sha256:4d00985aa43a98ca0feee872f889251d7b7b2c8f1a6703316ffc27ad4405e423",
206
+ "digest": "sha256:03cf19323cf8d4bd7726e07ab615ed74b4ff7ca0b58becd25963ff080993c6ea",
207
207
  "summary": "Publication artifact manifest, source bundle, and publication passport APIs.",
208
208
  "capabilityGroup": "reusable-build",
209
209
  "audience": [
@@ -902,7 +902,7 @@
902
902
  ],
903
903
  "maturity": "stable",
904
904
  "sourcePath": "docs/publication-artifacts.md",
905
- "digest": "sha256:ef8f4cc214b5fb5f6214796e7688ea897eddb5bc9dd9135638500ce9a1e18c92",
905
+ "digest": "sha256:06ba810c9eb13d47e408c74d58442635727396da66ed90fd4d505f2ff031cc18",
906
906
  "headings": [
907
907
  {
908
908
  "level": 1,
@@ -930,7 +930,7 @@
930
930
  "anchor": "site-consumption"
931
931
  }
932
932
  ],
933
- "markdown": "# Publication Artifact Workflow\n\nBuildchain supports `project.type = \"publication-artifact\"` for repositories\nthat produce auditable papers, reports, specifications, or similar publication\npackages. These repositories are artifact producers. They should not be forced\nto become `web-surface` repositories just because a downstream site later\nrenders the paper.\n\nThe split is:\n\n```text\npaper repo = source, PDF, metadata, source bundle, publication manifest\npapers site = layout, navigation, public web surface, downstream rendering\n```\n\n## Configuration\n\nThe paper repository owns `.buildchain/buildchain.toml`:\n\n```toml\nschema = 1\n\n[project]\ntype = \"publication-artifact\"\nname = \"paper-observer-declared-timelines\"\n\n[publication]\nkind = \"paper\"\ntitle = \"Observer-Declared Timelines for Real-World Agent Work\"\nprimary_artifact = \"_build/main.pdf\"\nartifact_paths = [\"_build/main.pdf\"]\nmetadata_paths = [\"README.md\", \"docs/MAP.md\"]\nsource_paths = [\"paper\", \"README.md\", \"LICENSE\", \"Makefile\"]\nsite_consumers = [\"papers.libkungfu.dev\"]\nmanifest_path = \".buildchain/publication/publication-artifact.json\"\nsource_bundle_path = \".buildchain/publication/source.tar.gz\"\n\n[lifecycle.build]\ncommand = \"make pdf\"\n\n[lifecycle.verify]\ncommand = \"make check\"\n```\n\n`primary_artifact` is the human-facing publication output, usually a PDF.\n`source_paths` are archived into a source bundle. `metadata_paths` are hashed\nand recorded so a site can consume the paper facts without scraping prose.\n\n## Reusable Workflow\n\nConsumer repositories can call the Buildchain wrapper directly:\n\n```yaml\njobs:\n publication:\n uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2\n with:\n build-command: make pdf\n verify-command: make check\n artifact-name: observer-declared-timelines\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe workflow:\n\n- resolves the Buildchain runtime and checks the floating contract lock before\n any paper build runs;\n- runs the declared build and verify commands;\n- creates a source bundle from `publication.source_paths`;\n- writes `.buildchain/publication/publication-artifact.json`;\n- writes `.buildchain/publication/publication-artifact-passport.json`;\n- uploads one GitHub artifact containing the PDF, manifest, passport, and\n source bundle.\n\nThe wrapper is build-only. It does not publish npm packages, deploy web pages,\nor create GitHub Releases. Release publication can be layered later by a\nrepository-specific governance workflow that attaches the generated manifest\nand passport as release assets.\n\n## CLI And Node API\n\nGenerate the publication manifest locally or in CI:\n\n```sh\nbuildchain publication-artifact manifest --source-sha \"$(git rev-parse HEAD)\" --json\n```\n\nNode API:\n\n```js\nimport {\n collectPublicationArtifact,\n writePublicationArtifact,\n} from \"@kungfu-tech/buildchain/publication-artifact\";\n```\n\n`writePublicationArtifact()` is the single implementation used by the CLI and\nthe reusable workflow. The generated manifest records:\n\n- publication title, kind, authors, and primary artifact;\n- artifact paths, byte sizes, and SHA-256 digests;\n- metadata paths and SHA-256 digests;\n- source SHA, tree SHA, source files, and source bundle digest;\n- timestamp and reproducibility policy;\n- downstream site-consumption hints.\n\nThe companion publication artifact passport records the same source and\nartifact evidence plus an explicit responsibility split. Buildchain proves\ndeclared files and hashes; it does not peer-review paper claims.\n\n## Site Consumption\n\nA downstream papers site should treat the publication manifest as the single\nfact source for the artifact. The site owns rendering and navigation; it should\nnot reinterpret the paper repository as a web deployment source.\n\nFor `paper-observer-declared-timelines`, the expected adoption path is:\n\n```text\npaper repo builds PDF + manifest + source bundle\npapers site consumes publication-artifact.json\nsite renders paper page and links the PDF/source bundle\n```\n\nThis mirrors web-surface governance without mixing producer and renderer\nresponsibilities."
933
+ "markdown": "# Publication Artifact Workflow\n\nBuildchain supports `project.type = \"publication-artifact\"` for repositories\nthat produce auditable papers, reports, specifications, or similar publication\npackages. These repositories are artifact producers. They should not be forced\nto become `web-surface` repositories just because a downstream site later\nrenders the paper.\n\nThe split is:\n\n```text\npaper repo = source, PDF, metadata, source bundle, publication manifest\npapers site = layout, navigation, public web surface, downstream rendering\n```\n\n## Configuration\n\nThe paper repository owns `.buildchain/buildchain.toml`:\n\n```toml\nschema = 1\n\n[project]\ntype = \"publication-artifact\"\nname = \"paper-observer-declared-timelines\"\n\n[publication]\nkind = \"paper\"\ntitle = \"Observer-Declared Timelines for Real-World Agent Work\"\nprimary_artifact = \"_build/main.pdf\"\nartifact_paths = [\"_build/main.pdf\"]\nmetadata_paths = [\"README.md\", \"docs/MAP.md\"]\nsource_paths = [\"paper\", \"README.md\", \"LICENSE\", \"Makefile\"]\nsite_consumers = [\"papers.libkungfu.dev\"]\nmanifest_path = \".buildchain/publication/publication-artifact.json\"\nsource_bundle_path = \".buildchain/publication/source.tar.gz\"\n\n[publication.toolchain]\ntype = \"latex-docker\"\nimage = \"ghcr.io/kungfu-systems/latex\"\ndigest = \"sha256:0000000000000000000000000000000000000000000000000000000000000000\"\ncommand = \"latexmk -pdf -outdir=_build paper/main.tex\"\n\n[lifecycle.build]\ncommand = \"make pdf\"\n\n[lifecycle.verify]\ncommand = \"make check\"\n```\n\n`primary_artifact` is the human-facing publication output, usually a PDF.\n`source_paths` are archived into a source bundle. `metadata_paths` are hashed\nand recorded so a site can consume the paper facts without scraping prose.\n\n`publication.toolchain` makes the source-to-PDF transformation part of the\nmachine-readable contract. `latex-docker` is the preferred LaTeX profile: the\nworkflow pulls the declared image by digest and runs the declared command in\nthat pinned container. `custom-command` remains available for compatibility,\nbut the passport records it as lower trust because Buildchain can record the\ncommand boundary without proving the compiler or LaTeX distribution digest.\n\n## Reusable Workflow\n\nConsumer repositories can call the Buildchain wrapper directly:\n\n```yaml\njobs:\n publication:\n uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2\n with:\n toolchain-type: config\n verify-command: make check\n artifact-name: observer-declared-timelines\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe workflow:\n\n- resolves the Buildchain runtime and checks the floating contract lock before\n any paper build runs;\n- resolves the declared publication toolchain from `[publication.toolchain]` or\n workflow inputs;\n- for `latex-docker`, pulls the pinned image digest and runs the declared\n command in the container;\n- for `custom-command`, runs the declared command and records the lower-trust\n boundary in the passport;\n- runs the verify command;\n- creates a source bundle from `publication.source_paths`;\n- writes `.buildchain/publication/publication-artifact.json`;\n- writes `.buildchain/publication/publication-artifact-passport.json`;\n- uploads one GitHub artifact containing the PDF, manifest, passport, and\n source bundle.\n\nThe wrapper is build-only. It does not publish npm packages, deploy web pages,\nor create GitHub Releases. Release publication can be layered later by a\nrepository-specific governance workflow that attaches the generated manifest\nand passport as release assets.\n\n## CLI And Node API\n\nGenerate the publication manifest locally or in CI:\n\n```sh\nbuildchain publication-artifact manifest --source-sha \"$(git rev-parse HEAD)\" --json\n```\n\nNode API:\n\n```js\nimport {\n collectPublicationArtifact,\n writePublicationArtifact,\n} from \"@kungfu-tech/buildchain/publication-artifact\";\n```\n\n`writePublicationArtifact()` is the single implementation used by the CLI and\nthe reusable workflow. The generated manifest records:\n\n- publication title, kind, authors, and primary artifact;\n- artifact paths, byte sizes, and SHA-256 digests;\n- metadata paths and SHA-256 digests;\n- source SHA, tree SHA, source files, and source bundle digest;\n- publication toolchain type, image, digest, command, invocation mode, and trust\n classification;\n- timestamp and reproducibility policy;\n- downstream site-consumption hints.\n\nThe companion publication artifact passport records the same source and\nartifact evidence plus an explicit responsibility split. Buildchain proves\ndeclared files and hashes; it does not peer-review paper claims.\n\n## Site Consumption\n\nA downstream papers site should treat the publication manifest as the single\nfact source for the artifact. The site owns rendering and navigation; it should\nnot reinterpret the paper repository as a web deployment source.\n\nFor `paper-observer-declared-timelines`, the expected adoption path is:\n\n```text\npaper repo builds PDF + manifest + source bundle\npapers site consumes publication-artifact.json\nsite renders paper page and links the PDF/source bundle\n```\n\nThis mirrors web-surface governance without mixing producer and renderer\nresponsibilities."
934
934
  },
935
935
  {
936
936
  "id": "manual:publish-transaction",
@@ -839,10 +839,14 @@
839
839
  "buildchain-repository",
840
840
  "node-version",
841
841
  "setup-node",
842
+ "toolchain-command",
843
+ "toolchain-digest",
844
+ "toolchain-image",
845
+ "toolchain-type",
842
846
  "verify-command",
843
847
  "working-directory"
844
848
  ],
845
- "inputCount": 13
849
+ "inputCount": 17
846
850
  },
847
851
  {
848
852
  "id": "release-candidate-promote",
@@ -2435,8 +2439,8 @@
2435
2439
  "workflowRegistryPath": "dist/site/workflow-registry.json",
2436
2440
  "pageRegistryPath": "dist/site/page-registry.json",
2437
2441
  "cliRegistryDigest": "1f7e1f7707a089f067175030fde6712b69ceece3df1b811eb542b0b4c8c1d4a9",
2438
- "workflowRegistryDigest": "5a74fd4e5b7b071f014b59d590313535da05e7a96d46b82db0bc306182911395",
2439
- "pageRegistryDigest": "a32dc62d72d1499d3156711aa51c58c0a19be4cace798617815c98c733e43f8e"
2442
+ "workflowRegistryDigest": "67572429a83124370b9ffd46f56923aa2b252873c9624ded39a26675fb0ee815",
2443
+ "pageRegistryDigest": "c1ec998aced6612b9cf444b886d126a89b344954a1ecebf6908d11610dba3cf8"
2440
2444
  },
2441
2445
  "comparison": {
2442
2446
  "missingCliRegistry": [],
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-manifest",
4
- "generatedAt": "2026-07-09T01:16:31.067Z",
5
- "publishedAt": "2026-07-09T01:16:31.067Z",
4
+ "generatedAt": "2026-07-09T03:20:50.735Z",
5
+ "publishedAt": "2026-07-09T03:20:50.735Z",
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": "227aeefaff9a5bbf881d7fb903d39544ef0624af",
22
+ "sourceRevision": "c7e618f57355231a8f27fd628ee9499bd5b8e9fd",
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.10",
40
+ "version": "2.10.11",
41
41
  "versionSource": "package.json#version"
42
42
  },
43
43
  "entrypoint": "buildchain-site.json",
@@ -544,10 +544,14 @@
544
544
  "buildchain-repository",
545
545
  "node-version",
546
546
  "setup-node",
547
+ "toolchain-command",
548
+ "toolchain-digest",
549
+ "toolchain-image",
550
+ "toolchain-type",
547
551
  "verify-command",
548
552
  "working-directory"
549
553
  ],
550
- "inputCount": 13,
554
+ "inputCount": 17,
551
555
  "surface": "repository-workflow",
552
556
  "capabilityGroup": "reusable-build",
553
557
  "status": "active"
@@ -35,6 +35,12 @@ site_consumers = ["papers.libkungfu.dev"]
35
35
  manifest_path = ".buildchain/publication/publication-artifact.json"
36
36
  source_bundle_path = ".buildchain/publication/source.tar.gz"
37
37
 
38
+ [publication.toolchain]
39
+ type = "latex-docker"
40
+ image = "ghcr.io/kungfu-systems/latex"
41
+ digest = "sha256:0000000000000000000000000000000000000000000000000000000000000000"
42
+ command = "latexmk -pdf -outdir=_build paper/main.tex"
43
+
38
44
  [lifecycle.build]
39
45
  command = "make pdf"
40
46
 
@@ -46,6 +52,13 @@ command = "make check"
46
52
  `source_paths` are archived into a source bundle. `metadata_paths` are hashed
47
53
  and recorded so a site can consume the paper facts without scraping prose.
48
54
 
55
+ `publication.toolchain` makes the source-to-PDF transformation part of the
56
+ machine-readable contract. `latex-docker` is the preferred LaTeX profile: the
57
+ workflow pulls the declared image by digest and runs the declared command in
58
+ that pinned container. `custom-command` remains available for compatibility,
59
+ but the passport records it as lower trust because Buildchain can record the
60
+ command boundary without proving the compiler or LaTeX distribution digest.
61
+
49
62
  ## Reusable Workflow
50
63
 
51
64
  Consumer repositories can call the Buildchain wrapper directly:
@@ -55,7 +68,7 @@ jobs:
55
68
  publication:
56
69
  uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2
57
70
  with:
58
- build-command: make pdf
71
+ toolchain-type: config
59
72
  verify-command: make check
60
73
  artifact-name: observer-declared-timelines
61
74
  buildchain-contract-lock-path: .buildchain/contract-lock.json
@@ -65,7 +78,13 @@ The workflow:
65
78
 
66
79
  - resolves the Buildchain runtime and checks the floating contract lock before
67
80
  any paper build runs;
68
- - runs the declared build and verify commands;
81
+ - resolves the declared publication toolchain from `[publication.toolchain]` or
82
+ workflow inputs;
83
+ - for `latex-docker`, pulls the pinned image digest and runs the declared
84
+ command in the container;
85
+ - for `custom-command`, runs the declared command and records the lower-trust
86
+ boundary in the passport;
87
+ - runs the verify command;
69
88
  - creates a source bundle from `publication.source_paths`;
70
89
  - writes `.buildchain/publication/publication-artifact.json`;
71
90
  - writes `.buildchain/publication/publication-artifact-passport.json`;
@@ -101,6 +120,8 @@ the reusable workflow. The generated manifest records:
101
120
  - artifact paths, byte sizes, and SHA-256 digests;
102
121
  - metadata paths and SHA-256 digests;
103
122
  - source SHA, tree SHA, source files, and source bundle digest;
123
+ - publication toolchain type, image, digest, command, invocation mode, and trust
124
+ classification;
104
125
  - timestamp and reproducibility policy;
105
126
  - downstream site-consumption hints.
106
127
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungfu-tech/buildchain",
3
- "version": "2.10.10",
3
+ "version": "2.10.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",
@@ -49,6 +49,7 @@ const SUPPORTED_INFRA_ADOPTION_MODES = new Set([
49
49
  const SUPPORTED_INFRA_APPLY_MODES = new Set(["disabled", "manual-approval", "environment-approval"]);
50
50
  const SUPPORTED_FACT_VERSION_SOURCE_TYPES = new Set(["static", "json", "toml", "regex", "command"]);
51
51
  const SUPPORTED_FACT_LEGACY_PROJECTIONS = new Set(["kungfu-buildinfo"]);
52
+ const SUPPORTED_PUBLICATION_TOOLCHAINS = new Set(["custom-command", "latex-docker"]);
52
53
 
53
54
  function posixPath(value) {
54
55
  return String(value || "").split(path.sep).join("/");
@@ -389,6 +390,7 @@ function normalizePublicationSection(publication) {
389
390
  metadataPaths: normalizeStringArray(publication.metadata_paths, "publication.metadata_paths").map(posixPath),
390
391
  sourcePaths: normalizeStringArray(publication.source_paths, "publication.source_paths").map(posixPath),
391
392
  siteConsumers: normalizeStringArray(publication.site_consumers, "publication.site_consumers"),
393
+ toolchain: normalizePublicationToolchain(publication.toolchain),
392
394
  manifestPath: publication.manifest_path === undefined
393
395
  ? ".buildchain/publication/publication-artifact.json"
394
396
  : posixPath(assertString(publication.manifest_path, "publication.manifest_path")),
@@ -398,6 +400,49 @@ function normalizePublicationSection(publication) {
398
400
  };
399
401
  }
400
402
 
403
+ function normalizePublicationToolchain(toolchain = undefined) {
404
+ if (toolchain === undefined) {
405
+ return {
406
+ type: "custom-command",
407
+ image: "",
408
+ digest: "",
409
+ command: "",
410
+ trustClassification: "custom-command",
411
+ };
412
+ }
413
+ assertPlainObject(toolchain, "publication.toolchain");
414
+ const type = toolchain.type === undefined
415
+ ? "custom-command"
416
+ : assertString(toolchain.type, "publication.toolchain.type");
417
+ if (!SUPPORTED_PUBLICATION_TOOLCHAINS.has(type)) {
418
+ throw new Error("publication.toolchain.type must be one of custom-command or latex-docker");
419
+ }
420
+ const command = toolchain.command === undefined
421
+ ? ""
422
+ : assertString(toolchain.command, "publication.toolchain.command");
423
+ const image = toolchain.image === undefined
424
+ ? ""
425
+ : assertString(toolchain.image, "publication.toolchain.image");
426
+ const digest = toolchain.digest === undefined
427
+ ? ""
428
+ : assertString(toolchain.digest, "publication.toolchain.digest");
429
+ if (type === "latex-docker") {
430
+ if (!image) throw new Error("publication.toolchain.image is required for latex-docker");
431
+ if (!digest) throw new Error("publication.toolchain.digest is required for latex-docker");
432
+ if (!/^sha256:[0-9a-f]{64}$/i.test(digest)) {
433
+ throw new Error("publication.toolchain.digest must be a sha256:<64 hex> image digest");
434
+ }
435
+ if (!command) throw new Error("publication.toolchain.command is required for latex-docker");
436
+ }
437
+ return {
438
+ type,
439
+ image,
440
+ digest,
441
+ command,
442
+ trustClassification: type === "latex-docker" ? "pinned-docker-toolchain" : "custom-command",
443
+ };
444
+ }
445
+
401
446
  function normalizeInfraSection(infra) {
402
447
  assertPlainObject(infra, "infra");
403
448
  const adapter = assertString(infra.adapter, "infra.adapter");
@@ -6,6 +6,7 @@ import { loadBuildchainConfig } from "./buildchain-config.js";
6
6
 
7
7
  export const PUBLICATION_ARTIFACT_MANIFEST_CONTRACT = "kungfu-buildchain-publication-artifact-manifest";
8
8
  export const PUBLICATION_ARTIFACT_PASSPORT_CONTRACT = "kungfu-buildchain-publication-artifact-passport";
9
+ const KFD2_RESIDUAL_RISK_SCHEMA = "https://kfd.libkungfu.dev/schemas/kfd-2/trust-taxonomy.schema.json#/$defs/residualRisk";
9
10
 
10
11
  function toPosix(value) {
11
12
  return String(value || "").split(path.sep).join("/");
@@ -74,6 +75,69 @@ function createdAt(now = new Date()) {
74
75
  return now.toISOString();
75
76
  }
76
77
 
78
+ function publicationToolchainFacts(publication) {
79
+ const envType = String(process.env.BUILDCHAIN_PUBLICATION_TOOLCHAIN_TYPE || "").trim();
80
+ const envToolchain = envType
81
+ ? {
82
+ type: envType,
83
+ image: process.env.BUILDCHAIN_PUBLICATION_TOOLCHAIN_IMAGE || "",
84
+ digest: process.env.BUILDCHAIN_PUBLICATION_TOOLCHAIN_DIGEST || "",
85
+ command: process.env.BUILDCHAIN_PUBLICATION_TOOLCHAIN_COMMAND || "",
86
+ trustClassification: envType === "latex-docker" ? "pinned-docker-toolchain" : "custom-command",
87
+ }
88
+ : undefined;
89
+ const toolchain = publication.toolchain || {
90
+ type: "custom-command",
91
+ image: "",
92
+ digest: "",
93
+ command: "",
94
+ trustClassification: "custom-command",
95
+ };
96
+ const resolved = envToolchain || toolchain;
97
+ const facts = {
98
+ type: resolved.type,
99
+ trustClassification: resolved.trustClassification || (resolved.type === "latex-docker" ? "pinned-docker-toolchain" : "custom-command"),
100
+ command: resolved.command || "",
101
+ image: resolved.image || "",
102
+ digest: resolved.digest || "",
103
+ machineVerifiable: resolved.type === "latex-docker" && Boolean(resolved.image && resolved.digest && resolved.command),
104
+ };
105
+ facts.invocation = facts.type === "latex-docker"
106
+ ? "docker-image-digest"
107
+ : "caller-provided-command";
108
+ return facts;
109
+ }
110
+
111
+ function publicationResidualRisk(toolchainFacts) {
112
+ const risks = [
113
+ {
114
+ id: "publication-semantic-review",
115
+ definedBy: KFD2_RESIDUAL_RISK_SCHEMA,
116
+ riskType: "natural-language-semantic-risk",
117
+ trustImpact: "downgrade-warning",
118
+ machineProvability: "not-machine-verifiable",
119
+ agentAction: "semantic-review-required",
120
+ owner: "publication maintainers",
121
+ reason: "Buildchain verifies declared files and hashes; it does not peer-review paper claims.",
122
+ note: "Buildchain verifies declared files and hashes; it does not peer-review paper claims.",
123
+ },
124
+ ];
125
+ if (toolchainFacts.type === "custom-command") {
126
+ risks.push({
127
+ id: "publication-custom-build-toolchain",
128
+ definedBy: KFD2_RESIDUAL_RISK_SCHEMA,
129
+ riskType: "natural-language-semantic-risk",
130
+ trustImpact: "downgrade-warning",
131
+ machineProvability: "not-machine-verifiable",
132
+ agentAction: "semantic-review-required",
133
+ owner: "publication maintainers",
134
+ reason: "The source-to-publication build is a caller-provided command, so Buildchain records the command boundary but cannot prove a pinned compiler or LaTeX image digest.",
135
+ note: "Use publication.toolchain.type = \"latex-docker\" with an image digest to make the PDF build toolchain machine-auditable.",
136
+ });
137
+ }
138
+ return risks;
139
+ }
140
+
77
141
  export function createPublicationSourceBundle({
78
142
  cwd = process.cwd(),
79
143
  sourcePaths = [],
@@ -130,6 +194,7 @@ export function collectPublicationArtifact({
130
194
  const resolvedSourceSha = sourceSha || gitValue(cwd, ["rev-parse", "HEAD"]);
131
195
  const sourceTreeSha = gitValue(cwd, ["rev-parse", `${resolvedSourceSha}^{tree}`]);
132
196
  const timestamp = generatedAt || createdAt();
197
+ const toolchain = publicationToolchainFacts(publication);
133
198
  const manifest = {
134
199
  schemaVersion: 1,
135
200
  contract: PUBLICATION_ARTIFACT_MANIFEST_CONTRACT,
@@ -146,6 +211,7 @@ export function collectPublicationArtifact({
146
211
  primaryArtifact: publication.primaryArtifact,
147
212
  siteConsumers: publication.siteConsumers,
148
213
  },
214
+ toolchain,
149
215
  source: {
150
216
  repository: gitValue(cwd, ["config", "--get", "remote.origin.url"]),
151
217
  sha: resolvedSourceSha,
@@ -183,6 +249,7 @@ export function collectPublicationArtifact({
183
249
  status: "passed",
184
250
  manifestDigest: `sha256:${sha256Buffer(Buffer.from(JSON.stringify(manifest, null, 2)))}`,
185
251
  source: manifest.source,
252
+ toolchain,
186
253
  artifacts: manifest.artifacts,
187
254
  responsibility: {
188
255
  producer: "publication repository",
@@ -195,6 +262,9 @@ export function collectPublicationArtifact({
195
262
  "declared publication metadata files exist",
196
263
  "declared publication source files are hashed",
197
264
  "source bundle digest is recorded",
265
+ toolchain.machineVerifiable
266
+ ? "publication PDF build toolchain image digest is declared"
267
+ : "publication build command boundary is recorded",
198
268
  ],
199
269
  outsideBoundary: [
200
270
  "paper scientific claims",
@@ -202,15 +272,7 @@ export function collectPublicationArtifact({
202
272
  "human review of publication content",
203
273
  ],
204
274
  },
205
- residualRisk: [
206
- {
207
- riskType: "natural-language-semantic-risk",
208
- trustImpact: "downgrade-warning",
209
- machineProvability: "not-machine-verifiable",
210
- agentAction: "semantic-review-required",
211
- note: "Buildchain verifies declared files and hashes; it does not peer-review paper claims.",
212
- },
213
- ],
275
+ residualRisk: publicationResidualRisk(toolchain),
214
276
  },
215
277
  };
216
278
  }
@@ -258,6 +258,10 @@ site_consumers = ["papers-site"]
258
258
  manifest_path = ".buildchain/publication/publication-artifact.json"
259
259
  source_bundle_path = ".buildchain/publication/source.tar.gz"
260
260
 
261
+ [publication.toolchain]
262
+ type = "custom-command"
263
+ command = "make pdf"
264
+
261
265
  [lifecycle.build]
262
266
  command = "make pdf"
263
267
 
@@ -343,7 +347,7 @@ jobs:
343
347
  uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2
344
348
  with:
345
349
  buildchain-ref: \${{ inputs.buildchain-ref || '' }}
346
- build-command: make pdf
350
+ toolchain-type: config
347
351
  verify-command: make check
348
352
  artifact-name: publication-artifact
349
353
  `;