@kungfu-tech/buildchain 4.0.2-alpha.49 → 4.0.2-alpha.50

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.
@@ -27,11 +27,11 @@
27
27
  "repositoryBudgets": {
28
28
  "baselineRevision": "9569f69c2cb609372b8a3d65ce5dec8fb7b34a84",
29
29
  "maxHandMaintainedSourceFiles": 493,
30
- "maxHandMaintainedSourceLines": 174632,
30
+ "maxHandMaintainedSourceLines": 174638,
31
31
  "maxWorkflowFiles": 80,
32
32
  "maxWorkflowLines": 26791,
33
- "latestTransition": "Add verified multi-platform OCI and Compose preview publication.",
34
- "latestTransitionRationale": "Charge four additional production modules and 720 net source lines for recursive OCI graph validation, Compose qualification, registry transport separation and protected preview orchestration. New workflows retain their measured current metrics instead of borrowing the frozen facade baseline. File, function, complexity, debt and exception ceilings remain unchanged; independent governance review and negative authority tests are required.",
33
+ "latestTransition": "Verify bounded OCI embedded descriptor content without rewriting manifests.",
34
+ "latestTransitionRationale": "Charge six measured net production source lines for canonical embedded-content equality against the existing size- and digest-verified local blob, capped at 1 MiB. Reuse existing descriptor traversal and publication paths; split regression fixtures without increasing file, function, complexity, debt or exception limits. Require independent governance review and positive/negative OCI publication tests.",
35
35
  "rationale": "Bounded modules separate candidate, evidence, native proof and execution, canonical failure verification, closed-set execution transfer, process-boundary verification, Warrant state and qualification, authority state, qualification, Landing acquisition, verified-attempt admission, Landing settlement and fence validation, provider attempt and heartbeat readback, sealed terminal evidence, hosted heartbeat, resume, store, options, command-specific adapters, and CLI orchestration responsibilities. The protected delivery workflow gives candidate and seal jobs no provider write credential, recursively rejects transfer drift, scopes every transfer artifact to the exact provider run attempt, chains every durable heartbeat state and receipt root on a distinct hosted runner domain, and permits qualification or exact failure settlement only after the finalizer verifies live jobs and the latest durable authority state. Public Landing admission and heartbeat always perform non-injectable fresh exact-attempt provider readback, tolerate only a not-yet-materialized seal job while retaining exact native and duplicate-job rejection, and heartbeat-loss coordination never invokes GitHub's run-scoped cancellation API where a successor rerun could race. The hosted process boundary anchors trust in the kernel-resolved versioned Runner.Worker path while accepting an equivalent argv-zero spelling with the same basename; its public boundary marker is allowed only at the one exact non-secret value, so a forged value under the same credential-like name still fails closed. The credentialless transfer seal validates the rooted native reuse decision against the Warrant-bound source, closure, dependency, toolchain, environment and command inputs; qualifiedBase stays in the proof and decision where it is rooted and later independently rechecked, rather than being assumed on the Warrant schema. V2 mutation cannot initialize a second empty authority beside a legacy ref: migration reads and roots the canonical live v1 ref, rechecks it, applies the explicit configured v2 policy, and atomically replaces its bytes through one expected-old non-force update, so old v1 controllers fail closed while the prior commit remains immutable history. Candidate ancestry classifies the GitHub artifact runtime token as credential authority. Every Landing settlement, including an unexpired fence, requires product-owned terminal readback. Terminal cleanup reads the immutable historical attempt, derives workflow and hosted Landing job identity from live run data, reads the exact protected ref head and compares containment against that immutable SHA, and seals merged only when the admitted merge-group head is contained by that protected base; a later different-head merge settles the old attempt as dequeued. Terminal normalization preserves transfer, finalizer boundary, native and seal job, admitted provider attempt, protected-base head, containment result, and terminal readback coordinates. The public reusable workflow truthfully retains its single-flight v1 authority without advertising v2 migration, while bounded v2 remains a separate opt-in CLI, Node API, and schema contract; the tracked self-caller stays on public v4-alpha with matching stable and alpha locks, and transient train selection is dispatch-only. Next-development parity adds one versioned transition authority, one durable controller, one bounded reservation adapter, and pure public-contract recovery evidence while retaining the existing thin floating-channel callers byte-for-byte. The floating-consumer gate reuses the existing contract-world evaluator so SHA drift passes only under the selected lock's compatibility policy, breaking surface drift still fails closed, and external certification reconstructs the receipt from the observed workflow SHA rather than the lock's historical evidence SHA. Tail reseal adds no Stage Capsule effect or general rebuild authority: it verifies the exact retained four-platform bytes, admits one known macOS tail failure through live provider readback, fences signing and finalization to explicit credentials and Warrant identity, and requires standard candidate Passport plus provider and protected readback. Compatibility Facts parity isolates canonical encoding, temporal verification, lifecycle validation, fixture projection, public authority projection, and CLI adaptation into bounded modules; legacy digest and proof arrays are derived only from exact current Fact lineage. Publication Rehearsal adds no production release authority: the content-addressed capsule contract binds source, candidate, manifest, config, canonical data-only provider bindings, provider policy, observations and core version separately from filesystem, runtime and rehearsal-only provider authority; simulate, replay and explicitly authorized provider rehearsal all reuse the release-tail planner, while same-commit local dogfood resolves the new reusable contract and exact current runtime before external callers remain on floating v4-alpha. Cross-runtime candidate recovery preserves original runtime and provider roots and creates resume lineage only after exact public ref, tag, ancestry, npm version and integrity readback. Adopter Delivery restores the reviewed public v3 gate, drivers, Passport binding, N-1 bootstrap and exact archive loader through one public v4 surface while keeping provider and release authority explicit non-claims. Floating Alpha bootstrap uses only the existing exact resolver and protected Alpha private shell to move an otherwise stale floating shell, retains public v4 stable promotion, and removes itself after protected readback. CI lane change-budget enforcement adds a bounded parser, evaluator, guard, and tests without creating another merge authority.",
36
36
  "governance": "legacy-debt-sunset-2026q4"
37
37
  },
@@ -4,7 +4,7 @@
4
4
  "product": {
5
5
  "name": "Buildchain",
6
6
  "package": "@kungfu-tech/buildchain",
7
- "version": "4.0.2-alpha.49",
7
+ "version": "4.0.2-alpha.50",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "majorLine": "v4",
@@ -2279,7 +2279,7 @@
2279
2279
  "agents can discover supported Node APIs without importing internal file paths"
2280
2280
  ],
2281
2281
  "breakingDigest": "sha256:48f925608d3e2131d90936b07dc2a30341204cae3e6e785c0f77d61ad755c945",
2282
- "auditDigest": "sha256:4ace19480d9908b2c5a27663fb3dd78b4ca19aa1fb1219998c18d0ba8e2db5ab"
2282
+ "auditDigest": "sha256:e2a1ee7379ece294d1e012c4b2d51539550683ff6a147383dfcb7abe7735ce60"
2283
2283
  },
2284
2284
  {
2285
2285
  "contractVersion": 1,
@@ -5444,5 +5444,5 @@
5444
5444
  "compatibilityFactCutRoot": "sha256:f61b975d4a96c921cc4bd37fb3ed9a0596b47004fe34dc7219979d697e3707f9",
5445
5445
  "compatibilityProofRegistryRoot": "sha256:b7194b811e4d3af2df4390bc4d1731e16a86215bd64ee18cb630dd5492f4fb63",
5446
5446
  "compatibilityDigest": "sha256:20411029d83211dff426fb6535a608902129844a5ccb4788db77d3f81becb839",
5447
- "contractDigest": "sha256:5329e52fd5f7c583bfd6f618d40d4f9092f77b55bda4ef34c932953d29a72c90"
5447
+ "contractDigest": "sha256:1ffa084654fcf7d8f82f11b15b0fffb6da3a5d5c68ca0e8ea667f3fb08e2b0f6"
5448
5448
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-bundle",
4
- "generatedAt": "2026-09-06T21:59:58.000Z",
5
- "publishedAt": "2026-09-06T21:59:58.000Z",
4
+ "generatedAt": "2026-09-07T02:04:08.000Z",
5
+ "publishedAt": "2026-09-07T02:04:08.000Z",
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": "0eb5a97907da10cfc6f69b4f12f492bef351a105",
22
+ "sourceRevision": "b3481bbba92c6f4905f349a7cba239b32ea1db93",
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": "4.0.2-alpha.49",
40
+ "version": "4.0.2-alpha.50",
41
41
  "versionSource": "package.json#version"
42
42
  },
43
43
  "source": {
@@ -3562,7 +3562,7 @@
3562
3562
  ],
3563
3563
  "maturity": "stable",
3564
3564
  "sourcePath": "docs/oci-publication.md",
3565
- "digest": "sha256:8864376481c559147fb1f5d2f270018e9b35140b87f6925cb1d906d33cb42069",
3565
+ "digest": "sha256:261f32b71ac4aedd0b718fc04b7ecd486d8ebf08ccdec475af849b8ffcec5603",
3566
3566
  "headings": [
3567
3567
  {
3568
3568
  "level": 1,
@@ -3590,7 +3590,7 @@
3590
3590
  "anchor": "evidence-gated-compose-preview"
3591
3591
  }
3592
3592
  ],
3593
- "markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: oci-publication\ndoc_type: technical-reference\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-09-07\nai_provenance:\n model_family: GPT-6\n product: Codex\n generated_at: 2026-09-06\n invisible_context_boundary: No credentials or production registry state inspected.\n---\n\n# OCI image family publication\n\nBuildchain v4 can publish a sealed family of container images to GHCR through\n`publish-artifact-kind: oci` on the public release candidate promotion workflow.\nThe candidate build produces the image bytes and smoke evidence. The built-in\nprovider verifies and uploads those bytes, reads back every public image digest,\nthen allows release references and GitHub Release evidence to converge.\n\n## Candidate contract\n\nPublish exactly one `oci-family.json` alongside OCI layouts and smoke JSON files\nin the Build artifact. Import `sealOciPublicationBundle` from\n`@kungfu-tech/buildchain/oci-publication` to validate and seal the family. Its\n`body` contains:\n\n- `schema: kungfu-buildchain-oci-family/v1`, consumer `repository`, exact Git\n `sourceSha`, and candidate package `version`.\n- `expectedImages`: the complete set of image names.\n- `images`: one entry for each expected image, with `name`, `repository`,\n `digest`, `layout`, `platform`, `action`, `content`, and `smoke`.\n\nDestinations must be `ghcr.io/<consumer-owner>/<consumer-repo>/<image-name>`.\n`layout` is a relative OCI layout directory. Each image is a single Linux\namd64 or arm64 manifest; OCI and Docker schema 2 manifests are supported.\nLayouts may share blobs and an index; each shared index entry identifies its\nimage with the `org.opencontainers.image.ref.name` annotation.\n\n`content` records the image's original `sourceSha` and `version`, matching its\nOCI revision/version labels. For `action: built`, both equal the candidate.\nFor `action: reused`, they retain the original content provenance while the\nfamily binds the current candidate. `smoke` records a relative `path` and SHA256\n`sha256`; its JSON must identify the image and record `passed: true`. The\nconsumer owns the actual smoke command and must fail the build if it fails.\n\nSealing verifies all config/layer sizes and digests, platform and provenance\nlabels, smoke bytes, and family completeness. Absolute paths, traversal, and\nsymlinks are rejected. The resolver derives the exact required image artifacts\nfrom this sealed family, including when recovering a previous candidate run.\n\n## Authority and publication\n\nThe thin caller grants `packages: write` in addition to its existing promotion\npermissions. Reusable promotion wrappers inherit that caller envelope; npm\nconsumers do not need to request package registry authority. The provider uses\nthe action token only for GHCR, scoped to each declared consumer image.\nNo consumer publish command is executed.\n\nThe rooted product plan declares version-state materialization, OCI family\npublication, then release reference convergence. Each image uses the exact\n`v<version>` tag. A different existing digest aborts publication; a matching\nexisting image is reused. After a partial failure, recovery validates the same\ncandidate bytes and publishes only missing images. GHCR does not provide tag\ncompare-and-swap: callers must serialize publishers for a version, and external\nwriters must not race the publication workflow.\n\nSuccess requires anonymous readback of every declared image at its expected\ndigest. Existing GHCR packages must permit the repository token to write and\nanonymous clients to pull. The provider does not change package visibility or\naccess policy. It attaches `oci-publication-readback.json` to the GitHub Release;\nthe caller should also include the family and smoke JSON files in\n`github-release-payload-patterns`.\n\nSee [Runtime Train Validation](runtime-train-validation.md) for testing an\nunreleased runtime without persisting a train or exact SHA in the workflow.\n\n## Multi-platform images and Compose applications\n\nUse `schema: kungfu-buildchain-oci-family/v2` when the family includes an OCI\nindex or a Compose application. Existing v1 families keep their published\nsingle-platform contract.\n\nAn index entry declares `platform: multi-platform` and the complete `platforms`\narray, for example `[\"linux/amd64\", \"linux/arm64\"]`. Every runnable child must\nhave matching platform and content labels. Descriptor sizes, digests and media\ntypes are verified recursively; nested manifests are uploaded before their\nparent index. BuildKit attestation manifests must identify a runnable child and\ncontain matching in-toto subjects. Missing platforms, duplicate platforms,\nforeign URLs, inline descriptor data and broken blob references fail sealing.\n\nA Compose entry declares `kind: compose`, `platform: compose`, and `targetImage`\npointing to an image in the same family. Its unique family name may differ from\nthat image, but its destination repository must match it. The immutable tag is\n`compose-v<version>`; image entries retain `v<version>`.\n\nThe bounded Compose representation is an OCI 1.1 image manifest with\n`artifactType: application/vnd.docker.compose.project`, an empty JSON config\nand one `application/vnd.docker.compose.file+yaml` layer. That layer contains\nJSON, a YAML subset, so structural verification needs no executable YAML loader.\nEvery service image is pinned to a digest and at least one uses the exact\nfamily image. Environment interpolation inside other fields can remain intact.\nThese media types follow the [Docker Compose publisher](https://github.com/docker/compose/blob/v5.1.2/internal/oci/push.go).\n\nCandidate smoke evidence describes its actual pre-publication checks. It must\nnot claim that an unpublished public Compose reference was installed. Public\ninstallation qualification occurs after immutable publication and before a\npreview alias moves.\n\n## Evidence-gated Compose preview\n\nAn optional Compose `preview` declaration contains exactly the supported alias\n`compose-preview`, the previously accepted `previousDigest` (or `none`), and\n`qualificationWorkflow`, a repository workflow path. The immutable family seals\nthis policy before any publication effect.\n\nAfter v4 publication is complete, dispatch that qualification workflow on the\nexact published alpha tag. It must pull the immutable public image and Compose,\nrun fresh installation, restart, account-isolation, runtime-hardening, upgrade\nand rollback checks, and qualify both Linux architectures. The workflow has no\nregistry write authority. Upload one artifact named\n`oci-compose-qualification-<run-id>-<run-attempt>` containing `qualification.json`\nand its hash-bound JSON evidence files.\n\nThe receipt uses `schema: kungfu-buildchain-compose-qualification/v1` and binds\n`repository`, `tag`, published `sourceSha`, sealed `familyRoot`, `runId`,\n`runAttempt`, exact `image` and `application` repository/digest references,\n`previousDigest`, and `passed: true`. Its `checks` object requires all of\n`freshInstall`, `restartPersistence`, `upgradePersistence`, `rollbackPersistence`,\n`accountIsolation`, and `hardenedRuntime` to be true. Its `platforms` object\nrequires `linux/amd64` and `linux/arm64` entries with `passed: true`; `evidence`\ncontains nonempty `{path, sha256}` bindings to the actual JSON results.\n\nA thin consumer workflow listens to completion of that qualification workflow\nand calls `public-release-oci-compose-preview.yml@v4-alpha`, passing\n`BUILDCHAIN_PROMOTION_TOKEN`. The reusable workflow resolves its own exact\nruntime, enforces the dual floating-channel locks, verifies the public v4\nsettlement, family and provider readback roots, and checks the live GitHub run's\nrepository, source, workflow, event, attempt and successful conclusion. It never\nexecutes the consumer's artifact files. Only then does it copy the exact Compose\nmanifest bytes to the declared alias and verify the public digest.\n\nThe expected-old digest is checked immediately before mutation. An already\nmatching target is an idempotent success; any other drift blocks the move.\nPublishers for this alias share repository-level concurrency. GHCR has no atomic\ntag compare-and-swap, so external writers must also avoid racing this workflow.\nThe immutable release retains the appended\n`buildchain-compose-preview-<run-id>-<run-attempt>.json` receipt. A failed\nqualification leaves the existing preview intact, while the immutable alpha\nand its original publication evidence remain available for diagnosis."
3593
+ "markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: oci-publication\ndoc_type: technical-reference\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-09-07\nai_provenance:\n model_family: GPT-6\n product: Codex\n generated_at: 2026-09-06\n invisible_context_boundary: No credentials or production registry state inspected.\n---\n\n# OCI image family publication\n\nBuildchain v4 can publish a sealed family of container images to GHCR through\n`publish-artifact-kind: oci` on the public release candidate promotion workflow.\nThe candidate build produces the image bytes and smoke evidence. The built-in\nprovider verifies and uploads those bytes, reads back every public image digest,\nthen allows release references and GitHub Release evidence to converge.\n\n## Candidate contract\n\nPublish exactly one `oci-family.json` alongside OCI layouts and smoke JSON files\nin the Build artifact. Import `sealOciPublicationBundle` from\n`@kungfu-tech/buildchain/oci-publication` to validate and seal the family. Its\n`body` contains:\n\n- `schema: kungfu-buildchain-oci-family/v1`, consumer `repository`, exact Git\n `sourceSha`, and candidate package `version`.\n- `expectedImages`: the complete set of image names.\n- `images`: one entry for each expected image, with `name`, `repository`,\n `digest`, `layout`, `platform`, `action`, `content`, and `smoke`.\n\nDestinations must be `ghcr.io/<consumer-owner>/<consumer-repo>/<image-name>`.\n`layout` is a relative OCI layout directory. Each image is a single Linux\namd64 or arm64 manifest; OCI and Docker schema 2 manifests are supported.\nLayouts may share blobs and an index; each shared index entry identifies its\nimage with the `org.opencontainers.image.ref.name` annotation.\n\n`content` records the image's original `sourceSha` and `version`, matching its\nOCI revision/version labels. For `action: built`, both equal the candidate.\nFor `action: reused`, they retain the original content provenance while the\nfamily binds the current candidate. `smoke` records a relative `path` and SHA256\n`sha256`; its JSON must identify the image and record `passed: true`. The\nconsumer owns the actual smoke command and must fail the build if it fails.\n\nSealing verifies all config/layer sizes and digests, platform and provenance\nlabels, smoke bytes, and family completeness. Absolute paths, traversal, and\nsymlinks are rejected. The resolver derives the exact required image artifacts\nfrom this sealed family, including when recovering a previous candidate run.\n\n## Authority and publication\n\nThe thin caller grants `packages: write` in addition to its existing promotion\npermissions. Reusable promotion wrappers inherit that caller envelope; npm\nconsumers do not need to request package registry authority. The provider uses\nthe action token only for GHCR, scoped to each declared consumer image.\nNo consumer publish command is executed.\n\nThe rooted product plan declares version-state materialization, OCI family\npublication, then release reference convergence. Each image uses the exact\n`v<version>` tag. A different existing digest aborts publication; a matching\nexisting image is reused. After a partial failure, recovery validates the same\ncandidate bytes and publishes only missing images. GHCR does not provide tag\ncompare-and-swap: callers must serialize publishers for a version, and external\nwriters must not race the publication workflow.\n\nSuccess requires anonymous readback of every declared image at its expected\ndigest. Existing GHCR packages must permit the repository token to write and\nanonymous clients to pull. The provider does not change package visibility or\naccess policy. It attaches `oci-publication-readback.json` to the GitHub Release;\nthe caller should also include the family and smoke JSON files in\n`github-release-payload-patterns`.\n\nSee [Runtime Train Validation](runtime-train-validation.md) for testing an\nunreleased runtime without persisting a train or exact SHA in the workflow.\n\n## Multi-platform images and Compose applications\n\nUse `schema: kungfu-buildchain-oci-family/v2` when the family includes an OCI\nindex or a Compose application. Existing v1 families keep their published\nsingle-platform contract.\n\nAn index entry declares `platform: multi-platform` and the complete `platforms`\narray, for example `[\"linux/amd64\", \"linux/arm64\"]`. Every runnable child must\nhave matching platform and content labels. Descriptor sizes, digests and media\ntypes are verified recursively; nested manifests are uploaded before their\nparent index. BuildKit attestation manifests must identify a runnable child and\ncontain matching in-toto subjects. Missing platforms, duplicate platforms,\nforeign URLs and broken blob references fail sealing. Embedded descriptor `data`\nis accepted only as canonical Base64 for at most 1 MiB, with the declared size\nand digest matching the required local blob byte for byte. Malformed or\ninconsistent embedded content fails sealing; manifests are never rewritten.\nThis follows the [OCI embedded-content contract](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#embedded-content).\n\nA Compose entry declares `kind: compose`, `platform: compose`, and `targetImage`\npointing to an image in the same family. Its unique family name may differ from\nthat image, but its destination repository must match it. The immutable tag is\n`compose-v<version>`; image entries retain `v<version>`.\n\nThe bounded Compose representation is an OCI 1.1 image manifest with\n`artifactType: application/vnd.docker.compose.project`, an empty JSON config\nand one `application/vnd.docker.compose.file+yaml` layer. That layer contains\nJSON, a YAML subset, so structural verification needs no executable YAML loader.\nEvery service image is pinned to a digest and at least one uses the exact\nfamily image. Environment interpolation inside other fields can remain intact.\nThese media types follow the [Docker Compose publisher](https://github.com/docker/compose/blob/v5.1.2/internal/oci/push.go).\n\nCandidate smoke evidence describes its actual pre-publication checks. It must\nnot claim that an unpublished public Compose reference was installed. Public\ninstallation qualification occurs after immutable publication and before a\npreview alias moves.\n\n## Evidence-gated Compose preview\n\nAn optional Compose `preview` declaration contains exactly the supported alias\n`compose-preview`, the previously accepted `previousDigest` (or `none`), and\n`qualificationWorkflow`, a repository workflow path. The immutable family seals\nthis policy before any publication effect.\n\nAfter v4 publication is complete, dispatch that qualification workflow on the\nexact published alpha tag. It must pull the immutable public image and Compose,\nrun fresh installation, restart, account-isolation, runtime-hardening, upgrade\nand rollback checks, and qualify both Linux architectures. The workflow has no\nregistry write authority. Upload one artifact named\n`oci-compose-qualification-<run-id>-<run-attempt>` containing `qualification.json`\nand its hash-bound JSON evidence files.\n\nThe receipt uses `schema: kungfu-buildchain-compose-qualification/v1` and binds\n`repository`, `tag`, published `sourceSha`, sealed `familyRoot`, `runId`,\n`runAttempt`, exact `image` and `application` repository/digest references,\n`previousDigest`, and `passed: true`. Its `checks` object requires all of\n`freshInstall`, `restartPersistence`, `upgradePersistence`, `rollbackPersistence`,\n`accountIsolation`, and `hardenedRuntime` to be true. Its `platforms` object\nrequires `linux/amd64` and `linux/arm64` entries with `passed: true`; `evidence`\ncontains nonempty `{path, sha256}` bindings to the actual JSON results.\n\nA thin consumer workflow listens to completion of that qualification workflow\nand calls `public-release-oci-compose-preview.yml@v4-alpha`, passing\n`BUILDCHAIN_PROMOTION_TOKEN`. The reusable workflow resolves its own exact\nruntime, enforces the dual floating-channel locks, verifies the public v4\nsettlement, family and provider readback roots, and checks the live GitHub run's\nrepository, source, workflow, event, attempt and successful conclusion. It never\nexecutes the consumer's artifact files. Only then does it copy the exact Compose\nmanifest bytes to the declared alias and verify the public digest.\n\nThe expected-old digest is checked immediately before mutation. An already\nmatching target is an idempotent success; any other drift blocks the move.\nPublishers for this alias share repository-level concurrency. GHCR has no atomic\ntag compare-and-swap, so external writers must also avoid racing this workflow.\nThe immutable release retains the appended\n`buildchain-compose-preview-<run-id>-<run-attempt>.json` receipt. A failed\nqualification leaves the existing preview intact, while the immutable alpha\nand its original publication evidence remain available for diagnosis."
3594
3594
  },
3595
3595
  {
3596
3596
  "id": "manual:ownership",
@@ -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": "7526915e98433b479db2a2d6ee552df95ad2df267f6c93546a555c08ce1473a5",
24
+ "sha256": "233f353cc1de6036c90eab889ea673c1887903829810cfa0a7d844e196340c16",
25
25
  "summary": {
26
26
  "cliCommandCount": 117,
27
27
  "workflowCount": 115,
@@ -246,7 +246,7 @@
246
246
  "contract": "kungfu-buildchain-public-surface-reverse-audit",
247
247
  "path": "dist/site/public-surface-audit.json",
248
248
  "status": "passed",
249
- "sha256": "7526915e98433b479db2a2d6ee552df95ad2df267f6c93546a555c08ce1473a5",
249
+ "sha256": "233f353cc1de6036c90eab889ea673c1887903829810cfa0a7d844e196340c16",
250
250
  "summary": {
251
251
  "cliCommandCount": 117,
252
252
  "workflowCount": 115,
@@ -4,7 +4,7 @@
4
4
  "product": {
5
5
  "id": "kungfu-tech-buildchain",
6
6
  "name": "@kungfu-tech/buildchain",
7
- "version": "4.0.2-alpha.49",
7
+ "version": "4.0.2-alpha.50",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "source": {
@@ -31308,7 +31308,7 @@
31308
31308
  "specifier": "@kungfu-tech/buildchain/oci-publication",
31309
31309
  "export": "./oci-publication",
31310
31310
  "target": "./packages/core/oci-publication-bundle.js",
31311
- "digest": "sha256:3aea0ab4a83ffc47dd5248d19991e28e2fbb0309fed1a0934e46ad0176426df8",
31311
+ "digest": "sha256:b01e5f325705cce2a15d6a7bca5a66448c6fa4510ecf1eadcf380551caa73f50",
31312
31312
  "summary": "Sealed OCI image family verification, provenance, and smoke evidence APIs.",
31313
31313
  "capabilityGroup": "reusable-build",
31314
31314
  "audience": [
@@ -3496,7 +3496,7 @@
3496
3496
  ],
3497
3497
  "maturity": "stable",
3498
3498
  "sourcePath": "docs/oci-publication.md",
3499
- "digest": "sha256:8864376481c559147fb1f5d2f270018e9b35140b87f6925cb1d906d33cb42069",
3499
+ "digest": "sha256:261f32b71ac4aedd0b718fc04b7ecd486d8ebf08ccdec475af849b8ffcec5603",
3500
3500
  "headings": [
3501
3501
  {
3502
3502
  "level": 1,
@@ -3524,7 +3524,7 @@
3524
3524
  "anchor": "evidence-gated-compose-preview"
3525
3525
  }
3526
3526
  ],
3527
- "markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: oci-publication\ndoc_type: technical-reference\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-09-07\nai_provenance:\n model_family: GPT-6\n product: Codex\n generated_at: 2026-09-06\n invisible_context_boundary: No credentials or production registry state inspected.\n---\n\n# OCI image family publication\n\nBuildchain v4 can publish a sealed family of container images to GHCR through\n`publish-artifact-kind: oci` on the public release candidate promotion workflow.\nThe candidate build produces the image bytes and smoke evidence. The built-in\nprovider verifies and uploads those bytes, reads back every public image digest,\nthen allows release references and GitHub Release evidence to converge.\n\n## Candidate contract\n\nPublish exactly one `oci-family.json` alongside OCI layouts and smoke JSON files\nin the Build artifact. Import `sealOciPublicationBundle` from\n`@kungfu-tech/buildchain/oci-publication` to validate and seal the family. Its\n`body` contains:\n\n- `schema: kungfu-buildchain-oci-family/v1`, consumer `repository`, exact Git\n `sourceSha`, and candidate package `version`.\n- `expectedImages`: the complete set of image names.\n- `images`: one entry for each expected image, with `name`, `repository`,\n `digest`, `layout`, `platform`, `action`, `content`, and `smoke`.\n\nDestinations must be `ghcr.io/<consumer-owner>/<consumer-repo>/<image-name>`.\n`layout` is a relative OCI layout directory. Each image is a single Linux\namd64 or arm64 manifest; OCI and Docker schema 2 manifests are supported.\nLayouts may share blobs and an index; each shared index entry identifies its\nimage with the `org.opencontainers.image.ref.name` annotation.\n\n`content` records the image's original `sourceSha` and `version`, matching its\nOCI revision/version labels. For `action: built`, both equal the candidate.\nFor `action: reused`, they retain the original content provenance while the\nfamily binds the current candidate. `smoke` records a relative `path` and SHA256\n`sha256`; its JSON must identify the image and record `passed: true`. The\nconsumer owns the actual smoke command and must fail the build if it fails.\n\nSealing verifies all config/layer sizes and digests, platform and provenance\nlabels, smoke bytes, and family completeness. Absolute paths, traversal, and\nsymlinks are rejected. The resolver derives the exact required image artifacts\nfrom this sealed family, including when recovering a previous candidate run.\n\n## Authority and publication\n\nThe thin caller grants `packages: write` in addition to its existing promotion\npermissions. Reusable promotion wrappers inherit that caller envelope; npm\nconsumers do not need to request package registry authority. The provider uses\nthe action token only for GHCR, scoped to each declared consumer image.\nNo consumer publish command is executed.\n\nThe rooted product plan declares version-state materialization, OCI family\npublication, then release reference convergence. Each image uses the exact\n`v<version>` tag. A different existing digest aborts publication; a matching\nexisting image is reused. After a partial failure, recovery validates the same\ncandidate bytes and publishes only missing images. GHCR does not provide tag\ncompare-and-swap: callers must serialize publishers for a version, and external\nwriters must not race the publication workflow.\n\nSuccess requires anonymous readback of every declared image at its expected\ndigest. Existing GHCR packages must permit the repository token to write and\nanonymous clients to pull. The provider does not change package visibility or\naccess policy. It attaches `oci-publication-readback.json` to the GitHub Release;\nthe caller should also include the family and smoke JSON files in\n`github-release-payload-patterns`.\n\nSee [Runtime Train Validation](runtime-train-validation.md) for testing an\nunreleased runtime without persisting a train or exact SHA in the workflow.\n\n## Multi-platform images and Compose applications\n\nUse `schema: kungfu-buildchain-oci-family/v2` when the family includes an OCI\nindex or a Compose application. Existing v1 families keep their published\nsingle-platform contract.\n\nAn index entry declares `platform: multi-platform` and the complete `platforms`\narray, for example `[\"linux/amd64\", \"linux/arm64\"]`. Every runnable child must\nhave matching platform and content labels. Descriptor sizes, digests and media\ntypes are verified recursively; nested manifests are uploaded before their\nparent index. BuildKit attestation manifests must identify a runnable child and\ncontain matching in-toto subjects. Missing platforms, duplicate platforms,\nforeign URLs, inline descriptor data and broken blob references fail sealing.\n\nA Compose entry declares `kind: compose`, `platform: compose`, and `targetImage`\npointing to an image in the same family. Its unique family name may differ from\nthat image, but its destination repository must match it. The immutable tag is\n`compose-v<version>`; image entries retain `v<version>`.\n\nThe bounded Compose representation is an OCI 1.1 image manifest with\n`artifactType: application/vnd.docker.compose.project`, an empty JSON config\nand one `application/vnd.docker.compose.file+yaml` layer. That layer contains\nJSON, a YAML subset, so structural verification needs no executable YAML loader.\nEvery service image is pinned to a digest and at least one uses the exact\nfamily image. Environment interpolation inside other fields can remain intact.\nThese media types follow the [Docker Compose publisher](https://github.com/docker/compose/blob/v5.1.2/internal/oci/push.go).\n\nCandidate smoke evidence describes its actual pre-publication checks. It must\nnot claim that an unpublished public Compose reference was installed. Public\ninstallation qualification occurs after immutable publication and before a\npreview alias moves.\n\n## Evidence-gated Compose preview\n\nAn optional Compose `preview` declaration contains exactly the supported alias\n`compose-preview`, the previously accepted `previousDigest` (or `none`), and\n`qualificationWorkflow`, a repository workflow path. The immutable family seals\nthis policy before any publication effect.\n\nAfter v4 publication is complete, dispatch that qualification workflow on the\nexact published alpha tag. It must pull the immutable public image and Compose,\nrun fresh installation, restart, account-isolation, runtime-hardening, upgrade\nand rollback checks, and qualify both Linux architectures. The workflow has no\nregistry write authority. Upload one artifact named\n`oci-compose-qualification-<run-id>-<run-attempt>` containing `qualification.json`\nand its hash-bound JSON evidence files.\n\nThe receipt uses `schema: kungfu-buildchain-compose-qualification/v1` and binds\n`repository`, `tag`, published `sourceSha`, sealed `familyRoot`, `runId`,\n`runAttempt`, exact `image` and `application` repository/digest references,\n`previousDigest`, and `passed: true`. Its `checks` object requires all of\n`freshInstall`, `restartPersistence`, `upgradePersistence`, `rollbackPersistence`,\n`accountIsolation`, and `hardenedRuntime` to be true. Its `platforms` object\nrequires `linux/amd64` and `linux/arm64` entries with `passed: true`; `evidence`\ncontains nonempty `{path, sha256}` bindings to the actual JSON results.\n\nA thin consumer workflow listens to completion of that qualification workflow\nand calls `public-release-oci-compose-preview.yml@v4-alpha`, passing\n`BUILDCHAIN_PROMOTION_TOKEN`. The reusable workflow resolves its own exact\nruntime, enforces the dual floating-channel locks, verifies the public v4\nsettlement, family and provider readback roots, and checks the live GitHub run's\nrepository, source, workflow, event, attempt and successful conclusion. It never\nexecutes the consumer's artifact files. Only then does it copy the exact Compose\nmanifest bytes to the declared alias and verify the public digest.\n\nThe expected-old digest is checked immediately before mutation. An already\nmatching target is an idempotent success; any other drift blocks the move.\nPublishers for this alias share repository-level concurrency. GHCR has no atomic\ntag compare-and-swap, so external writers must also avoid racing this workflow.\nThe immutable release retains the appended\n`buildchain-compose-preview-<run-id>-<run-attempt>.json` receipt. A failed\nqualification leaves the existing preview intact, while the immutable alpha\nand its original publication evidence remain available for diagnosis."
3527
+ "markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: oci-publication\ndoc_type: technical-reference\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-09-07\nai_provenance:\n model_family: GPT-6\n product: Codex\n generated_at: 2026-09-06\n invisible_context_boundary: No credentials or production registry state inspected.\n---\n\n# OCI image family publication\n\nBuildchain v4 can publish a sealed family of container images to GHCR through\n`publish-artifact-kind: oci` on the public release candidate promotion workflow.\nThe candidate build produces the image bytes and smoke evidence. The built-in\nprovider verifies and uploads those bytes, reads back every public image digest,\nthen allows release references and GitHub Release evidence to converge.\n\n## Candidate contract\n\nPublish exactly one `oci-family.json` alongside OCI layouts and smoke JSON files\nin the Build artifact. Import `sealOciPublicationBundle` from\n`@kungfu-tech/buildchain/oci-publication` to validate and seal the family. Its\n`body` contains:\n\n- `schema: kungfu-buildchain-oci-family/v1`, consumer `repository`, exact Git\n `sourceSha`, and candidate package `version`.\n- `expectedImages`: the complete set of image names.\n- `images`: one entry for each expected image, with `name`, `repository`,\n `digest`, `layout`, `platform`, `action`, `content`, and `smoke`.\n\nDestinations must be `ghcr.io/<consumer-owner>/<consumer-repo>/<image-name>`.\n`layout` is a relative OCI layout directory. Each image is a single Linux\namd64 or arm64 manifest; OCI and Docker schema 2 manifests are supported.\nLayouts may share blobs and an index; each shared index entry identifies its\nimage with the `org.opencontainers.image.ref.name` annotation.\n\n`content` records the image's original `sourceSha` and `version`, matching its\nOCI revision/version labels. For `action: built`, both equal the candidate.\nFor `action: reused`, they retain the original content provenance while the\nfamily binds the current candidate. `smoke` records a relative `path` and SHA256\n`sha256`; its JSON must identify the image and record `passed: true`. The\nconsumer owns the actual smoke command and must fail the build if it fails.\n\nSealing verifies all config/layer sizes and digests, platform and provenance\nlabels, smoke bytes, and family completeness. Absolute paths, traversal, and\nsymlinks are rejected. The resolver derives the exact required image artifacts\nfrom this sealed family, including when recovering a previous candidate run.\n\n## Authority and publication\n\nThe thin caller grants `packages: write` in addition to its existing promotion\npermissions. Reusable promotion wrappers inherit that caller envelope; npm\nconsumers do not need to request package registry authority. The provider uses\nthe action token only for GHCR, scoped to each declared consumer image.\nNo consumer publish command is executed.\n\nThe rooted product plan declares version-state materialization, OCI family\npublication, then release reference convergence. Each image uses the exact\n`v<version>` tag. A different existing digest aborts publication; a matching\nexisting image is reused. After a partial failure, recovery validates the same\ncandidate bytes and publishes only missing images. GHCR does not provide tag\ncompare-and-swap: callers must serialize publishers for a version, and external\nwriters must not race the publication workflow.\n\nSuccess requires anonymous readback of every declared image at its expected\ndigest. Existing GHCR packages must permit the repository token to write and\nanonymous clients to pull. The provider does not change package visibility or\naccess policy. It attaches `oci-publication-readback.json` to the GitHub Release;\nthe caller should also include the family and smoke JSON files in\n`github-release-payload-patterns`.\n\nSee [Runtime Train Validation](runtime-train-validation.md) for testing an\nunreleased runtime without persisting a train or exact SHA in the workflow.\n\n## Multi-platform images and Compose applications\n\nUse `schema: kungfu-buildchain-oci-family/v2` when the family includes an OCI\nindex or a Compose application. Existing v1 families keep their published\nsingle-platform contract.\n\nAn index entry declares `platform: multi-platform` and the complete `platforms`\narray, for example `[\"linux/amd64\", \"linux/arm64\"]`. Every runnable child must\nhave matching platform and content labels. Descriptor sizes, digests and media\ntypes are verified recursively; nested manifests are uploaded before their\nparent index. BuildKit attestation manifests must identify a runnable child and\ncontain matching in-toto subjects. Missing platforms, duplicate platforms,\nforeign URLs and broken blob references fail sealing. Embedded descriptor `data`\nis accepted only as canonical Base64 for at most 1 MiB, with the declared size\nand digest matching the required local blob byte for byte. Malformed or\ninconsistent embedded content fails sealing; manifests are never rewritten.\nThis follows the [OCI embedded-content contract](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#embedded-content).\n\nA Compose entry declares `kind: compose`, `platform: compose`, and `targetImage`\npointing to an image in the same family. Its unique family name may differ from\nthat image, but its destination repository must match it. The immutable tag is\n`compose-v<version>`; image entries retain `v<version>`.\n\nThe bounded Compose representation is an OCI 1.1 image manifest with\n`artifactType: application/vnd.docker.compose.project`, an empty JSON config\nand one `application/vnd.docker.compose.file+yaml` layer. That layer contains\nJSON, a YAML subset, so structural verification needs no executable YAML loader.\nEvery service image is pinned to a digest and at least one uses the exact\nfamily image. Environment interpolation inside other fields can remain intact.\nThese media types follow the [Docker Compose publisher](https://github.com/docker/compose/blob/v5.1.2/internal/oci/push.go).\n\nCandidate smoke evidence describes its actual pre-publication checks. It must\nnot claim that an unpublished public Compose reference was installed. Public\ninstallation qualification occurs after immutable publication and before a\npreview alias moves.\n\n## Evidence-gated Compose preview\n\nAn optional Compose `preview` declaration contains exactly the supported alias\n`compose-preview`, the previously accepted `previousDigest` (or `none`), and\n`qualificationWorkflow`, a repository workflow path. The immutable family seals\nthis policy before any publication effect.\n\nAfter v4 publication is complete, dispatch that qualification workflow on the\nexact published alpha tag. It must pull the immutable public image and Compose,\nrun fresh installation, restart, account-isolation, runtime-hardening, upgrade\nand rollback checks, and qualify both Linux architectures. The workflow has no\nregistry write authority. Upload one artifact named\n`oci-compose-qualification-<run-id>-<run-attempt>` containing `qualification.json`\nand its hash-bound JSON evidence files.\n\nThe receipt uses `schema: kungfu-buildchain-compose-qualification/v1` and binds\n`repository`, `tag`, published `sourceSha`, sealed `familyRoot`, `runId`,\n`runAttempt`, exact `image` and `application` repository/digest references,\n`previousDigest`, and `passed: true`. Its `checks` object requires all of\n`freshInstall`, `restartPersistence`, `upgradePersistence`, `rollbackPersistence`,\n`accountIsolation`, and `hardenedRuntime` to be true. Its `platforms` object\nrequires `linux/amd64` and `linux/arm64` entries with `passed: true`; `evidence`\ncontains nonempty `{path, sha256}` bindings to the actual JSON results.\n\nA thin consumer workflow listens to completion of that qualification workflow\nand calls `public-release-oci-compose-preview.yml@v4-alpha`, passing\n`BUILDCHAIN_PROMOTION_TOKEN`. The reusable workflow resolves its own exact\nruntime, enforces the dual floating-channel locks, verifies the public v4\nsettlement, family and provider readback roots, and checks the live GitHub run's\nrepository, source, workflow, event, attempt and successful conclusion. It never\nexecutes the consumer's artifact files. Only then does it copy the exact Compose\nmanifest bytes to the declared alias and verify the public digest.\n\nThe expected-old digest is checked immediately before mutation. An already\nmatching target is an idempotent success; any other drift blocks the move.\nPublishers for this alias share repository-level concurrency. GHCR has no atomic\ntag compare-and-swap, so external writers must also avoid racing this workflow.\nThe immutable release retains the appended\n`buildchain-compose-preview-<run-id>-<run-attempt>.json` receipt. A failed\nqualification leaves the existing preview intact, while the immutable alpha\nand its original publication evidence remain available for diagnosis."
3528
3528
  },
3529
3529
  {
3530
3530
  "id": "manual:ownership",
@@ -10948,8 +10948,8 @@
10948
10948
  "workflowRegistryPath": "dist/site/workflow-registry.json",
10949
10949
  "pageRegistryPath": "dist/site/page-registry.json",
10950
10950
  "cliRegistryDigest": "fbc23073bbae240489a2f826b2c26daadc58e704050c5f8df366509f5c5a1c3e",
10951
- "workflowRegistryDigest": "2a7365a6d6a2a418650106289e309e598a77851158abf237d13276a38654178e",
10952
- "pageRegistryDigest": "0a523efc8b3f009003cb9005636f7c1eb754909610a29d47386afef4e9d94fe3"
10951
+ "workflowRegistryDigest": "fa9ab9e9e45d7099071563d380eb8b1050cd32e03f30d450b7b763c567fd15e2",
10952
+ "pageRegistryDigest": "545a66bc71a8a2a56589aabf3fb48c9cae13752fddf802b9bdfe7659b4eddc30"
10953
10953
  },
10954
10954
  "comparison": {
10955
10955
  "missingCliRegistry": [],
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-publication-release-registry",
4
- "generatedAt": "2026-09-06T21:59:58.000Z",
5
- "publishedAt": "2026-09-06T21:59:58.000Z",
4
+ "generatedAt": "2026-09-07T02:04:08.000Z",
5
+ "publishedAt": "2026-09-07T02:04:08.000Z",
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": "0eb5a97907da10cfc6f69b4f12f492bef351a105",
22
+ "sourceRevision": "b3481bbba92c6f4905f349a7cba239b32ea1db93",
23
23
  "timestampPolicyDetails": {
24
24
  "contract": "kungfu-buildchain-surface-timestamp-policy",
25
25
  "timestampFields": [
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "package": {
34
34
  "name": "@kungfu-tech/buildchain",
35
- "version": "4.0.2-alpha.49",
35
+ "version": "4.0.2-alpha.50",
36
36
  "versionSource": "package.json#version"
37
37
  },
38
38
  "sourceKind": "package-site-bundle",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-manifest",
4
- "generatedAt": "2026-09-06T21:59:58.000Z",
5
- "publishedAt": "2026-09-06T21:59:58.000Z",
4
+ "generatedAt": "2026-09-07T02:04:08.000Z",
5
+ "publishedAt": "2026-09-07T02:04:08.000Z",
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": "0eb5a97907da10cfc6f69b4f12f492bef351a105",
22
+ "sourceRevision": "b3481bbba92c6f4905f349a7cba239b32ea1db93",
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": "4.0.2-alpha.49",
40
+ "version": "4.0.2-alpha.50",
41
41
  "versionSource": "package.json#version"
42
42
  },
43
43
  "entrypoint": "buildchain-site.json",
@@ -2746,7 +2746,7 @@
2746
2746
  "status": "preview",
2747
2747
  "owner": "buildchain-workflows",
2748
2748
  "maturity": "preview",
2749
- "introducedVersion": "4.0.2-alpha.49",
2749
+ "introducedVersion": "4.0.2-alpha.50",
2750
2750
  "compatibilityPromise": "preserved-through-the-v3-major-line",
2751
2751
  "deprecationReplacement": "",
2752
2752
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -3943,7 +3943,7 @@
3943
3943
  "status": "preview",
3944
3944
  "owner": "buildchain-workflows",
3945
3945
  "maturity": "preview",
3946
- "introducedVersion": "4.0.2-alpha.49",
3946
+ "introducedVersion": "4.0.2-alpha.50",
3947
3947
  "compatibilityPromise": "preserved-through-the-v3-major-line",
3948
3948
  "deprecationReplacement": "",
3949
3949
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -6004,7 +6004,7 @@
6004
6004
  "status": "preview",
6005
6005
  "owner": "buildchain-workflows",
6006
6006
  "maturity": "preview",
6007
- "introducedVersion": "4.0.2-alpha.49",
6007
+ "introducedVersion": "4.0.2-alpha.50",
6008
6008
  "compatibilityPromise": "preserved-through-the-v3-major-line",
6009
6009
  "deprecationReplacement": "",
6010
6010
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -6035,7 +6035,7 @@
6035
6035
  "status": "preview",
6036
6036
  "owner": "buildchain-workflows",
6037
6037
  "maturity": "preview",
6038
- "introducedVersion": "4.0.2-alpha.49",
6038
+ "introducedVersion": "4.0.2-alpha.50",
6039
6039
  "compatibilityPromise": "preserved-through-the-v3-major-line",
6040
6040
  "deprecationReplacement": "",
6041
6041
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -6066,7 +6066,7 @@
6066
6066
  "status": "preview",
6067
6067
  "owner": "buildchain-workflows",
6068
6068
  "maturity": "preview",
6069
- "introducedVersion": "4.0.2-alpha.49",
6069
+ "introducedVersion": "4.0.2-alpha.50",
6070
6070
  "compatibilityPromise": "preserved-through-the-v3-major-line",
6071
6071
  "deprecationReplacement": "",
6072
6072
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -93,7 +93,11 @@ have matching platform and content labels. Descriptor sizes, digests and media
93
93
  types are verified recursively; nested manifests are uploaded before their
94
94
  parent index. BuildKit attestation manifests must identify a runnable child and
95
95
  contain matching in-toto subjects. Missing platforms, duplicate platforms,
96
- foreign URLs, inline descriptor data and broken blob references fail sealing.
96
+ foreign URLs and broken blob references fail sealing. Embedded descriptor `data`
97
+ is accepted only as canonical Base64 for at most 1 MiB, with the declared size
98
+ and digest matching the required local blob byte for byte. Malformed or
99
+ inconsistent embedded content fails sealing; manifests are never rewritten.
100
+ This follows the [OCI embedded-content contract](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#embedded-content).
97
101
 
98
102
  A Compose entry declares `kind: compose`, `platform: compose`, and `targetImage`
99
103
  pointing to an image in the same family. Its unique family name may differ from
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungfu-tech/buildchain",
3
- "version": "4.0.2-alpha.49",
3
+ "version": "4.0.2-alpha.50",
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",
@@ -178,8 +178,7 @@ export function verifyOciPublicationBundle({
178
178
  digestPattern.test(descriptor.digest) &&
179
179
  Number.isSafeInteger(descriptor.size) &&
180
180
  descriptor.size >= 0 &&
181
- !descriptor.urls &&
182
- !descriptor.data,
181
+ !descriptor.urls,
183
182
  "invalid OCI descriptor",
184
183
  );
185
184
  const relative = `${prefix}/blobs/sha256/${descriptor.digest.slice(7)}`;
@@ -193,6 +192,13 @@ export function verifyOciPublicationBundle({
193
192
  fileDigest(file) === descriptor.digest,
194
193
  "OCI blob digest mismatch",
195
194
  );
195
+ if (Object.hasOwn(descriptor, "data")) {
196
+ requireValue(
197
+ descriptor.size <= 1024 * 1024 &&
198
+ descriptor.data === fs.readFileSync(file).toString("base64"),
199
+ "embedded OCI content mismatch",
200
+ );
201
+ }
196
202
  files.set(file, descriptor);
197
203
  return file;
198
204
  };