@kungfu-tech/buildchain 3.0.2-alpha.1 → 3.0.2-alpha.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.
Files changed (78) hide show
  1. package/README.md +4 -2
  2. package/actions/github-artifact-attestation/README.md +10 -0
  3. package/actions/promote-buildchain-ref/README.md +7 -0
  4. package/bin/buildchain.mjs +5 -0
  5. package/bin/internal/trust-release-cli.mjs +74 -3
  6. package/contracts/auditable-demo-media-profiles-v1.json +168 -0
  7. package/contracts/evidence/auditable-demo-web-delivery-v1.json +103 -0
  8. package/contracts/fixtures/auditable-demo-web-delivery-v1/complete-transcript.txt +2 -0
  9. package/contracts/fixtures/auditable-demo-web-delivery-v1/public-projection.json +16 -0
  10. package/contracts/fixtures/auditable-demo-web-delivery-v1/scene.json +12 -0
  11. package/dist/site/artifact-schemas.json +5 -1
  12. package/dist/site/buildchain-contract.json +103 -34
  13. package/dist/site/buildchain-site.json +159 -40
  14. package/dist/site/capability-registry.json +13 -12
  15. package/dist/site/cli-registry.json +12 -0
  16. package/dist/site/controller-registry.json +48 -4
  17. package/dist/site/kfd-claims.json +320 -20
  18. package/dist/site/kfd-upstream-aggregate.json +1 -1
  19. package/dist/site/manual-registry.json +24 -9
  20. package/dist/site/node-api-registry.json +75 -10
  21. package/dist/site/page-registry.json +135 -25
  22. package/dist/site/public-surface-audit.json +197 -21
  23. package/dist/site/publication-authority-registry.json +72 -2
  24. package/dist/site/publication-registry.json +4 -4
  25. package/dist/site/release-model.json +2 -1
  26. package/dist/site/release-passport-check-manifest.json +1 -0
  27. package/dist/site/release-provenance.json +5 -0
  28. package/dist/site/schemas/release-passport-v1.schema.json +6 -0
  29. package/dist/site/site-manifest.json +21 -13
  30. package/dist/site/workflow-registry.json +161 -13
  31. package/docs/MAP.md +5 -1
  32. package/docs/auditable-demo.md +55 -3
  33. package/docs/binary-distribution.md +7 -0
  34. package/docs/cli.md +9 -0
  35. package/docs/dev-alpha-candidate-patrol.md +111 -0
  36. package/docs/github-artifact-attestation.md +219 -0
  37. package/docs/release-governance.md +32 -0
  38. package/docs/release-passport.md +13 -0
  39. package/docs/reusable-build-surface.md +83 -61
  40. package/docs/runtime-train-validation.md +21 -0
  41. package/docs/versioning.md +1 -0
  42. package/package.json +7 -1
  43. package/packages/core/artifact-signing-result.js +228 -0
  44. package/packages/core/artifact-signing.js +412 -0
  45. package/packages/core/buildchain-config.js +58 -0
  46. package/packages/core/buildchain-contract.js +14 -0
  47. package/packages/core/buildchain-kfd-claims.js +5 -0
  48. package/packages/core/buildchain-publication-authority.js +3 -0
  49. package/packages/core/channel-candidate.js +186 -0
  50. package/packages/core/detached-artifact-signature.js +121 -0
  51. package/packages/core/github-artifact-attestation.js +642 -0
  52. package/packages/core/github-governance-authority.js +6 -0
  53. package/packages/core/index.js +52 -0
  54. package/packages/core/publication-authority.js +1 -1
  55. package/packages/core/release-passport-contract.js +2 -0
  56. package/packages/core/release-passport.js +60 -3
  57. package/scripts/auditable-demo.mjs +520 -28
  58. package/scripts/build-contract-core.mjs +31 -0
  59. package/scripts/buildchain-channel-router.mjs +8 -2
  60. package/scripts/check-inventory.mjs +9 -0
  61. package/scripts/create-github-artifact-attestation-policy.mjs +62 -0
  62. package/scripts/dev-alpha-candidate-patrol.mjs +864 -0
  63. package/scripts/dispatch-artifact-signing-authority.mjs +152 -0
  64. package/scripts/finalize-native-artifact-signing-result.mjs +96 -0
  65. package/scripts/generate-channel-promotion-workflow.mjs +6 -0
  66. package/scripts/generate-site-bundle.mjs +19 -0
  67. package/scripts/import-artifact-signing-results.mjs +76 -0
  68. package/scripts/inspect-artifact-signing-requests.mjs +101 -0
  69. package/scripts/materialize-artifact-signing-request.mjs +66 -0
  70. package/scripts/merge-artifact-signing-results.mjs +76 -0
  71. package/scripts/publish-github-artifact-attestation-evidence.mjs +201 -0
  72. package/scripts/release-candidate-resolver.mjs +12 -0
  73. package/scripts/release-line-policy.mjs +27 -0
  74. package/scripts/runtime-ref-core.mjs +10 -6
  75. package/scripts/seal-artifact-signing-requests.mjs +368 -0
  76. package/scripts/sign-detached-artifact-requests.mjs +237 -0
  77. package/scripts/stage-github-artifact-attestation-inputs.mjs +65 -0
  78. package/scripts/verify-artifact-signing-results.mjs +99 -0
package/README.md CHANGED
@@ -225,8 +225,9 @@ The active reusable workflow surfaces are:
225
225
  planning, capability-aware runner dispatch, receipt validation, and one
226
226
  stable aggregate check;
227
227
  - `.github/workflows/.auditable-demo.yml` for exact-artifact demo
228
- qualification, transcript-bound renderer smoke, and optional media rendering
229
- from the exact passing Gate bundle;
228
+ qualification, transcript-bound renderer smoke, optional media rendering
229
+ from the exact passing Gate bundle, and opt-in content-addressed web-delivery
230
+ profiles with independently verified rendition roles;
230
231
  - `.github/workflows/.build.yml` for deterministic multi-platform build and
231
232
  artifact contracts;
232
233
  - `.github/workflows/build.yml` for the single-config channel router that uses
@@ -366,6 +367,7 @@ npm pack --dry-run --json --registry=https://registry.npmjs.org/
366
367
  - [Product mechanism](docs/product-mechanism.md)
367
368
  - [Release Passport and binary distribution](docs/release-passport.md)
368
369
  - [GitHub governance authority](docs/github-governance-authority.md)
370
+ - [GitHub-native Linux artifact attestation](docs/github-artifact-attestation.md)
369
371
  - [Binary distribution details](docs/binary-distribution.md)
370
372
  - [Toolkit observability](docs/toolkit-observability.md)
371
373
  - [Site bundle contract](docs/site-bundle-contract.md)
@@ -0,0 +1,10 @@
1
+ # GitHub Artifact Attestation Evidence
2
+
3
+ This internal Buildchain action validates one downloaded Linux release artifact
4
+ against its platform manifest and Release Passport, writes the custom predicate
5
+ consumed by `actions/attest`, and finalizes the retained v1 evidence document.
6
+
7
+ Consumers should call
8
+ `.github/workflows/github-artifact-attestation.yml`; they should not call this
9
+ action directly. The action parses data files only. It never checks out or
10
+ executes consumer source or the downloaded subject.
@@ -357,6 +357,13 @@ inside the final version-state workspace, after the release transaction has
357
357
  materialized generated files such as `package.json` and `dist/site/*`. This
358
358
  keeps self-hosted KFD witness hashes bound to the exact published package
359
359
  instead of to a pre-promotion checkout.
360
+ Set `release-passport-github-artifact-attestation-policy-jsons` to one or more
361
+ newline-separated `buildchain.github-artifact-attestation-policy/v1` paths when
362
+ the Release Passport must require GitHub keyless provenance for Linux release
363
+ artifacts. The higher-level v3 promotion workflow exposes the single-artifact
364
+ `github-artifact-attestation-policy-json` input and owns staging, signing,
365
+ provider verification, immutable GitHub Release evidence upload, and read-back;
366
+ direct action callers own those post-Passport steps themselves.
360
367
  When present, the passport includes the aggregate build summary, platform
361
368
  artifact manifests, npm publish evidence, dist-tag promotion evidence, the
362
369
  release-state ref, trusted publishing metadata, and the Buildchain transaction
@@ -164,13 +164,18 @@ function usage() {
164
164
  [--kfd-product-gate-json <json-or-path>]...
165
165
  [--invariant-passport-json <json-or-path>]...
166
166
  [--invariant-passport-cmd <command>]
167
+ [--github-artifact-attestation-policy-json <json-or-path>]...
167
168
  [--kfd-agent-hub-evidence-json <json-or-path>]
168
169
  [--base-passport-json <json-or-path>] [--require-base-kfd]
169
170
  [--release-extra-json <json-or-path>]
170
171
  [--publish-json <json-or-path>] [--output-dir <dir>] [--json]
171
172
  buildchain create publication-admission --input-json <file-or-json> [--output <file>] [--json]
172
173
  buildchain create runner-provenance --input-json <file-or-json> [--output <file>] [--json]
174
+ buildchain create github-artifact-attestation-policy --input-json <file-or-json> [--output <file>] [--json]
173
175
  buildchain verify release-passport <file-or-url> [--json]
176
+ buildchain verify github-artifact-attestation <artifact>
177
+ --evidence <file> --bundle <file>
178
+ --platform-manifest <file> --release-passport <file> [--json]
174
179
  buildchain verify publication-admission <file-or-json>
175
180
  --registry-json <file-or-json>
176
181
  --runner-json <file-or-json>
@@ -1,5 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { spawnSync } from "node:child_process";
3
4
  import { verifyInfraContractEvidenceBundle } from "../../scripts/infra-contract-core.mjs";
4
5
  import { verifyBuildchainLogEvents } from "../../packages/core/logging.js";
5
6
  import {
@@ -20,6 +21,11 @@ import {
20
21
  createRunnerProvenance,
21
22
  verifyPublicationAdmission,
22
23
  } from "../../packages/core/publication-authority.js";
24
+ import {
25
+ createGitHubArtifactAttestationPolicy,
26
+ createGitHubArtifactAttestationVerificationPlan,
27
+ verifyGitHubArtifactAttestationEvidence,
28
+ } from "../../packages/core/github-artifact-attestation.js";
23
29
  import {
24
30
  explainArtifactPassport,
25
31
  verifyArtifactPassport,
@@ -127,13 +133,19 @@ async function dispatchTrustReleaseCommand({ command, args, runScript, packageVe
127
133
  if (command === "create") {
128
134
  const [subcommand = "", ...createArgs] = args;
129
135
  const inputValue = readFlag(createArgs, "input-json", "");
130
- if (!inputValue || !["publication-admission", "runner-provenance"].includes(subcommand)) {
131
- throw new Error("usage: buildchain create <publication-admission|runner-provenance> --input-json <file-or-json> [--output <file>]");
136
+ if (!inputValue || ![
137
+ "publication-admission",
138
+ "runner-provenance",
139
+ "github-artifact-attestation-policy",
140
+ ].includes(subcommand)) {
141
+ throw new Error("usage: buildchain create <publication-admission|runner-provenance|github-artifact-attestation-policy> --input-json <file-or-json> [--output <file>]");
132
142
  }
133
143
  const input = readJsonInput(inputValue, { label: "input-json" });
134
144
  const value = subcommand === "publication-admission"
135
145
  ? createPublicationAdmission(input)
136
- : createRunnerProvenance(input);
146
+ : subcommand === "runner-provenance"
147
+ ? createRunnerProvenance(input)
148
+ : createGitHubArtifactAttestationPolicy(input);
137
149
  const output = readFlag(createArgs, "output", "");
138
150
  if (output) writeJsonFile(path.resolve(output), value);
139
151
  if (!output || readBooleanFlag(createArgs, "json")) printJson(value);
@@ -190,6 +202,10 @@ async function dispatchTrustReleaseCommand({ command, args, runScript, packageVe
190
202
  kfdProductGateJsons: readRepeatedFlag(collectArgs, "kfd-product-gate-json"),
191
203
  invariantPassportJsons: readRepeatedFlag(collectArgs, "invariant-passport-json"),
192
204
  invariantPassportCommand: readFlag(collectArgs, "invariant-passport-cmd", ""),
205
+ githubArtifactAttestationPolicyJsons: readRepeatedFlag(
206
+ collectArgs,
207
+ "github-artifact-attestation-policy-json",
208
+ ),
193
209
  kfdAgentHubEvidenceJson: readFlag(collectArgs, "kfd-agent-hub-evidence-json", ""),
194
210
  basePassportJson: readFlag(collectArgs, "base-passport-json", ""),
195
211
  requireBaseKfd: readBooleanFlag(collectArgs, "require-base-kfd"),
@@ -225,6 +241,61 @@ async function dispatchTrustReleaseCommand({ command, args, runScript, packageVe
225
241
 
226
242
  if (command === "verify") {
227
243
  const [subcommand = "", location = "", ...verifyArgs] = args;
244
+ if (subcommand === "github-artifact-attestation") {
245
+ if (!location) {
246
+ throw new Error("usage: buildchain verify github-artifact-attestation <artifact> --evidence <file> --bundle <file> --platform-manifest <file> --release-passport <file>");
247
+ }
248
+ const requiredPath = (name) => {
249
+ const value = readFlag(verifyArgs, name, "");
250
+ if (!value) {
251
+ throw new Error(`buildchain verify github-artifact-attestation requires --${name} <file>`);
252
+ }
253
+ return path.resolve(value);
254
+ };
255
+ const evidencePath = requiredPath("evidence");
256
+ const bundlePath = requiredPath("bundle");
257
+ const platformManifestPath = requiredPath("platform-manifest");
258
+ const releasePassportPath = requiredPath("release-passport");
259
+ const evidence = readJsonInput(evidencePath, { label: "evidence" });
260
+ const plan = createGitHubArtifactAttestationVerificationPlan({
261
+ artifactPath: location,
262
+ bundlePath,
263
+ evidence,
264
+ });
265
+ const verified = spawnSync(plan.command, plan.args, {
266
+ cwd: process.cwd(),
267
+ encoding: "utf8",
268
+ maxBuffer: 32 * 1024 * 1024,
269
+ });
270
+ if (verified.error) throw verified.error;
271
+ if (verified.status !== 0) {
272
+ throw new Error(`gh attestation verify failed: ${(verified.stderr || verified.stdout || "unknown error").trim()}`);
273
+ }
274
+ let verificationResults;
275
+ try {
276
+ verificationResults = JSON.parse(verified.stdout);
277
+ } catch (error) {
278
+ throw new Error(`gh attestation verify returned invalid JSON: ${error.message}`);
279
+ }
280
+ const report = verifyGitHubArtifactAttestationEvidence({
281
+ artifactPath: path.resolve(location),
282
+ platformManifestPath,
283
+ releasePassportPath,
284
+ bundlePath,
285
+ evidence,
286
+ verificationResults,
287
+ });
288
+ if (readBooleanFlag(verifyArgs, "json")) {
289
+ printJson(report);
290
+ } else {
291
+ process.stdout.write(`GitHub artifact attestation: ${report.outcome}\n`);
292
+ for (const entry of report.issues) {
293
+ process.stdout.write(`- ${entry.code}: ${entry.message}\n`);
294
+ }
295
+ }
296
+ process.exitCode = report.ok ? 0 : 1;
297
+ return;
298
+ }
228
299
  if (subcommand === "publication-admission") {
229
300
  if (!location) {
230
301
  throw new Error("usage: buildchain verify publication-admission <file-or-json> --registry-json <file-or-json> --runner-json <file-or-json> --control-plane-audit-json <file-or-json> --publication-evidence-json <file-or-json>");
@@ -0,0 +1,168 @@
1
+ {
2
+ "schema": "buildchain.auditable-demo-media-profiles/v1",
3
+ "profiles": {
4
+ "archive-v1": {
5
+ "mode": "archive",
6
+ "renditions": [
7
+ {
8
+ "path": "demo.gif",
9
+ "role": "readme-compatibility",
10
+ "mimeType": "image/gif"
11
+ },
12
+ {
13
+ "path": "demo.mp4",
14
+ "role": "archive-video",
15
+ "mimeType": "video/mp4"
16
+ },
17
+ {
18
+ "path": "demo.webm",
19
+ "role": "archive-video-alternate",
20
+ "mimeType": "video/webm"
21
+ },
22
+ {
23
+ "path": "poster.png",
24
+ "role": "evidence-poster",
25
+ "mimeType": "image/png"
26
+ }
27
+ ],
28
+ "singletonRoles": [
29
+ "evidence-poster",
30
+ "readme-compatibility"
31
+ ]
32
+ },
33
+ "web-delivery-v1": {
34
+ "extends": "archive-v1",
35
+ "mode": "web-delivery",
36
+ "renditions": [
37
+ {
38
+ "path": "demo.gif",
39
+ "role": "readme-compatibility",
40
+ "mimeType": "image/gif",
41
+ "container": "gif",
42
+ "videoCodec": "gif",
43
+ "audioStreams": 0,
44
+ "maximumBytes": 1048576,
45
+ "budgetBasis": {
46
+ "evidence": "contracts/evidence/auditable-demo-web-delivery-v1.json",
47
+ "observedPath": "demo.gif",
48
+ "observedBytes": 40826,
49
+ "multiplier": 16,
50
+ "rounding": "next-power-of-two"
51
+ }
52
+ },
53
+ {
54
+ "path": "demo.mp4",
55
+ "role": "primary-video",
56
+ "mimeType": "video/mp4",
57
+ "container": "mp4",
58
+ "videoCodec": "h264",
59
+ "pixelFormat": "yuv420p",
60
+ "audioStreams": 0,
61
+ "maximumBytes": 524288,
62
+ "budgetBasis": {
63
+ "evidence": "contracts/evidence/auditable-demo-web-delivery-v1.json",
64
+ "observedPath": "demo.mp4",
65
+ "observedBytes": 27038,
66
+ "multiplier": 16,
67
+ "rounding": "next-power-of-two"
68
+ },
69
+ "progressiveDownload": "moov-before-mdat",
70
+ "frameRatePolicy": "scene-exact"
71
+ },
72
+ {
73
+ "path": "demo.webm",
74
+ "role": "alternate-video",
75
+ "mimeType": "video/webm",
76
+ "container": "webm",
77
+ "videoCodec": "vp9",
78
+ "pixelFormat": "yuv420p",
79
+ "audioStreams": 0,
80
+ "maximumBytes": 524288,
81
+ "budgetBasis": {
82
+ "evidence": "contracts/evidence/auditable-demo-web-delivery-v1.json",
83
+ "observedPath": "demo.webm",
84
+ "observedBytes": 23383,
85
+ "multiplier": 16,
86
+ "rounding": "next-power-of-two"
87
+ },
88
+ "frameRatePolicy": "scene-exact"
89
+ },
90
+ {
91
+ "path": "poster.png",
92
+ "role": "evidence-poster",
93
+ "mimeType": "image/png",
94
+ "container": "png",
95
+ "videoCodec": "png",
96
+ "audioStreams": 0,
97
+ "maximumBytes": 1048576,
98
+ "budgetBasis": {
99
+ "evidence": "contracts/evidence/auditable-demo-web-delivery-v1.json",
100
+ "observedPath": "poster.png",
101
+ "observedBytes": 34769,
102
+ "multiplier": 16,
103
+ "rounding": "next-power-of-two"
104
+ }
105
+ }
106
+ ],
107
+ "singletonRoles": [
108
+ "primary-video",
109
+ "alternate-video",
110
+ "evidence-poster",
111
+ "readme-compatibility",
112
+ "browser-poster"
113
+ ],
114
+ "additionalRenditions": {
115
+ "allowedRoles": [
116
+ "primary-video",
117
+ "responsive-video",
118
+ "browser-poster"
119
+ ],
120
+ "allowedMimeTypes": [
121
+ "video/mp4",
122
+ "video/webm",
123
+ "image/webp",
124
+ "image/avif"
125
+ ],
126
+ "maximumBytesByMimeType": {
127
+ "video/mp4": 524288,
128
+ "video/webm": 524288,
129
+ "image/webp": 524288,
130
+ "image/avif": 524288
131
+ }
132
+ }
133
+ },
134
+ "site-hero-v1": {
135
+ "extends": "web-delivery-v1",
136
+ "mode": "web-delivery",
137
+ "renditions": [
138
+ {
139
+ "path": "poster.webp",
140
+ "role": "browser-poster",
141
+ "mimeType": "image/webp",
142
+ "container": "webp",
143
+ "videoCodec": "webp",
144
+ "audioStreams": 0,
145
+ "maximumBytes": 524288,
146
+ "budgetBasis": {
147
+ "evidence": "contracts/evidence/auditable-demo-web-delivery-v1.json",
148
+ "observedPath": "poster.png",
149
+ "observedBytes": 34769,
150
+ "multiplier": 8,
151
+ "rounding": "next-power-of-two"
152
+ }
153
+ }
154
+ ]
155
+ }
156
+ },
157
+ "qualification": {
158
+ "dimensions": "exact-scene",
159
+ "durationToleranceMs": 600,
160
+ "memberRootAlgorithm": "sha256",
161
+ "nonClaims": [
162
+ "browser-playback-success",
163
+ "responsive-layout",
164
+ "reduced-motion-behavior",
165
+ "production-site-deployment"
166
+ ]
167
+ }
168
+ }
@@ -0,0 +1,103 @@
1
+ {
2
+ "evidenceRoot": "sha256:451adc20c423fbf680caeb14dcc4850990a3317dd5a77f94ee451a7a26edf3fb",
3
+ "inputs": {
4
+ "complete-transcript.txt": "sha256:f3723a3eda614134ab724ce9fbe1e0e5f916d809a8a3096f5e37c1458cb3656c",
5
+ "public-projection.json": "sha256:127f9877f9750a85eada4338f088bee5460c5c71a83302652d3321667002c3c7",
6
+ "scene.json": "sha256:ea65ec39177aac7e5341d330d61e81fcd523c9f2c7a7d4dd5ac43fb457a51977"
7
+ },
8
+ "qualification": {
9
+ "inspectionRoot": "sha256:3cf9f7c710f4fcbd307b116cf279675a37210905d6d0fc7459d11933e98e6ea4",
10
+ "nonClaims": [
11
+ "browser-playback-success",
12
+ "responsive-layout",
13
+ "reduced-motion-behavior",
14
+ "production-site-deployment"
15
+ ],
16
+ "profile": {
17
+ "catalogRoot": "sha256:b2cf52c7b087be73ea852bbbe574e1a50bb7d64d26b8bc211a2c7d53e2ff9cae",
18
+ "id": "web-delivery-v1",
19
+ "mode": "web-delivery",
20
+ "profileRoot": "sha256:b6fb0a83414d03a7222fc50429e60ed68b6d47758b86ceaa316ecc659a01ae2b"
21
+ },
22
+ "qualificationRoot": "sha256:f2133bab4a3a5937ec3863972049d0a7247a8e108681d4bd247f47d766c461ae",
23
+ "renditions": [
24
+ {
25
+ "audioStreams": 0,
26
+ "bytes": 40826,
27
+ "container": "gif",
28
+ "durationMs": 2500,
29
+ "frameRate": 12.5,
30
+ "height": 720,
31
+ "maximumBytes": 1048576,
32
+ "mimeType": "image/gif",
33
+ "path": "demo.gif",
34
+ "pixelFormat": "bgra",
35
+ "progressiveDownload": "not-applicable",
36
+ "role": "readme-compatibility",
37
+ "root": "sha256:d835fbd3068f672b3aaffc904d1488540f661c48e0429c8887397d1ae531880f",
38
+ "videoCodec": "gif",
39
+ "width": 1280
40
+ },
41
+ {
42
+ "audioStreams": 0,
43
+ "bytes": 27038,
44
+ "container": "mp4",
45
+ "durationMs": 2533,
46
+ "frameRate": 15,
47
+ "height": 720,
48
+ "maximumBytes": 524288,
49
+ "mimeType": "video/mp4",
50
+ "path": "demo.mp4",
51
+ "pixelFormat": "yuv420p",
52
+ "progressiveDownload": "moov-before-mdat",
53
+ "role": "primary-video",
54
+ "root": "sha256:a82c3ed61b101528a07689227dc8af65e8c809aa6de2b749fd53915d97c99ac9",
55
+ "videoCodec": "h264",
56
+ "width": 1280
57
+ },
58
+ {
59
+ "audioStreams": 0,
60
+ "bytes": 23383,
61
+ "container": "webm",
62
+ "durationMs": 2534,
63
+ "frameRate": 15,
64
+ "height": 720,
65
+ "maximumBytes": 524288,
66
+ "mimeType": "video/webm",
67
+ "path": "demo.webm",
68
+ "pixelFormat": "yuv420p",
69
+ "progressiveDownload": "not-applicable",
70
+ "role": "alternate-video",
71
+ "root": "sha256:935deb66eb4734371b21c2fc8c55acd596e79c832a9a7963ab0922b3925564c3",
72
+ "videoCodec": "vp9",
73
+ "width": 1280
74
+ },
75
+ {
76
+ "audioStreams": 0,
77
+ "bytes": 34769,
78
+ "container": "png",
79
+ "durationMs": 0,
80
+ "frameRate": 25,
81
+ "height": 720,
82
+ "maximumBytes": 1048576,
83
+ "mimeType": "image/png",
84
+ "path": "poster.png",
85
+ "pixelFormat": "rgb24",
86
+ "progressiveDownload": "not-applicable",
87
+ "role": "evidence-poster",
88
+ "root": "sha256:7141a41c2b84d074477844d9c8d12e6f44173074829796cefdf8119b21be2de9",
89
+ "videoCodec": "png",
90
+ "width": 1280
91
+ }
92
+ ],
93
+ "schema": "buildchain.auditable-demo-media-qualification/v1"
94
+ },
95
+ "renderer": {
96
+ "image": "ghcr.io/kungfu-systems/build-images/demo-renderer@sha256:cb5e1dec368d21c7d4e8baded99ac75f12f7eff0d19505751888cf974086efa6",
97
+ "sourceRef": "refs/tags/v1.3.0-alpha.16",
98
+ "sourceRepository": "kungfu-systems/build-images",
99
+ "sourceSha": "999b370743f3e64e4f0b634d5131bd1d3d6b83ba"
100
+ },
101
+ "rendererManifestRoot": "sha256:2d3e4e2fcdfd17419e866e99d5e29cef65166b594cc5a5bdf2e5d9454cfb3a49",
102
+ "schema": "buildchain.auditable-demo-media-profile-fixture/v1"
103
+ }
@@ -0,0 +1,2 @@
1
+ buildchain auditable demo media profile qualification
2
+ immutable renderer fixture completed
@@ -0,0 +1,16 @@
1
+ {
2
+ "schema": "build-images.demo-projection/v1",
3
+ "evidenceClass": "qualified-build-output",
4
+ "claimBoundary": "Fixture media qualifies delivery properties only; it does not prove a production deployment.",
5
+ "cues": [
6
+ {
7
+ "startMs": 0,
8
+ "endMs": 2500,
9
+ "transcriptLines": [
10
+ 1,
11
+ 2
12
+ ],
13
+ "annotation": "fixed qualification fixture"
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "schema": "build-images.demo-scene/v1",
3
+ "id": "buildchain-web-delivery-qualification",
4
+ "width": 1280,
5
+ "height": 720,
6
+ "fps": 15,
7
+ "durationMs": 2500,
8
+ "title": "Buildchain web delivery qualification",
9
+ "commandLabel": "buildchain qualify-media-fixture",
10
+ "background": "#0B1020",
11
+ "accent": "#67E8A5"
12
+ }
@@ -16,7 +16,11 @@
16
16
  "check-report.json",
17
17
  "llms.txt",
18
18
  "buildchain-release-bundle.json",
19
- "buildchain-release-bundle.tar.gz"
19
+ "buildchain-release-bundle.tar.gz",
20
+ "github-artifact-attestation.policy.json",
21
+ "github-artifact-attestation.predicate.json",
22
+ "github-artifact-attestation.evidence.json",
23
+ "attestation.sigstore.json"
20
24
  ],
21
25
  "site": [
22
26
  "buildchain-site.json",