@kungfu-tech/buildchain 3.0.9-alpha.8 → 4.0.0-alpha.0

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 (255) hide show
  1. package/AGENTS.md +39 -0
  2. package/README.md +17 -13
  3. package/actions/promote-buildchain-ref/README.md +0 -10
  4. package/actions/release-tail/README.md +6 -10
  5. package/architecture/internal-capabilities.json +502 -0
  6. package/architecture/maintainability-baseline.json +59 -0
  7. package/architecture/maintainability-policy.json +1384 -0
  8. package/architecture/release-tail-contract-inventory.json +587 -0
  9. package/architecture/v3-core-mechanism-inventory.json +1043 -0
  10. package/architecture/v3-core-mechanism-inventory.md +67 -0
  11. package/architecture/v4-adopter-delivery-parity.json +47 -0
  12. package/architecture/v4-architecture-constitution.md +210 -0
  13. package/architecture/v4-bootstrap-authority.json +56 -0
  14. package/architecture/v4-canonical-contract-fixtures.json +105 -0
  15. package/architecture/v4-capability-state-machine-manifest.json +480 -0
  16. package/architecture/v4-capability-state-machine-manifest.schema.json +202 -0
  17. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.json +830 -0
  18. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.md +223 -0
  19. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.schema.json +318 -0
  20. package/architecture/v4-delivery-warrant-shadow-fixtures.json +227 -0
  21. package/architecture/v4-delivery-warrant-shadow-fixtures.schema.json +67 -0
  22. package/architecture/v4-exception-ledger.json +5 -0
  23. package/architecture/v4-exception-ledger.schema.json +56 -0
  24. package/architecture/v4-partial-mutation-recovery-qualification.json +65 -0
  25. package/architecture/v4-platform-stage-checkpoints.json +97 -0
  26. package/architecture/v4-provider-operation-journal-contract.json +113 -0
  27. package/architecture/v4-release-activation-shadow-domain.json +61 -0
  28. package/architecture/v4-release-train-parity.json +68 -0
  29. package/architecture/v4-rust-libnode-bridge-evaluation.json +107 -0
  30. package/architecture/v4-rust-libnode-bridge-spike.md +85 -0
  31. package/architecture/v4-stable-publication-fence.json +66 -0
  32. package/architecture/v4-stage-capsule-contract.json +90 -0
  33. package/architecture/v4-stage-capsule-qualification.json +99 -0
  34. package/architecture/v4-stage-capsule-resume-planner.json +52 -0
  35. package/architecture/v4-stage-capsule-store-contract.json +72 -0
  36. package/bin/buildchain.mjs +15 -6
  37. package/contracts/auditable-demo-scenario-v1.schema.json +1 -1
  38. package/contracts/buildchain-v2-residuals-v1.json +2 -2
  39. package/contracts/fixtures/v4-delivery-warrant-trace-v1/golden.json +158 -0
  40. package/contracts/fixtures/v4-delivery-warrant-trace-v1/property.json +380 -0
  41. package/contracts/fixtures/v4-delivery-warrant-trace-v1/replay.json +163 -0
  42. package/contracts/fixtures/v4-partial-mutation-recovery-v1/shared.json +155 -0
  43. package/contracts/fixtures/v4-provider-operation-journal-v1/shared.json +457 -0
  44. package/contracts/fixtures/v4-provider-readback-idempotency-v1/shared.json +682 -0
  45. package/contracts/fixtures/v4-release-activation-shadow-v1/shared.json +53 -0
  46. package/contracts/fixtures/v4-stable-publication-fence-v1/shared.json +56 -0
  47. package/contracts/fixtures/v4-stage-capsule-resume-v1/late-platform-failure.json +176 -0
  48. package/contracts/fixtures/v4-stage-capsule-store-v1/shared.json +132 -0
  49. package/contracts/fixtures/v4-stage-capsule-v1/shared.json +111 -0
  50. package/contracts/v4-canonical-contracts-v1.schema.json +182 -0
  51. package/contracts/v4-delivery-warrant-semantic-diff-report-v1.schema.json +284 -0
  52. package/contracts/v4-delivery-warrant-trace-v1.schema.json +215 -0
  53. package/contracts/v4-host-contract-v1.schema.json +135 -0
  54. package/contracts/v4-partial-mutation-recovery-v1.schema.json +168 -0
  55. package/contracts/v4-provider-operation-journal-v1.schema.json +381 -0
  56. package/contracts/v4-release-activation-shadow-v1.schema.json +186 -0
  57. package/contracts/v4-stable-publication-fence-v1.schema.json +125 -0
  58. package/contracts/v4-stage-capsule-resume-v1.schema.json +225 -0
  59. package/contracts/v4-stage-capsule-store-v1.schema.json +154 -0
  60. package/contracts/v4-stage-capsule-v1.schema.json +178 -0
  61. package/crates/buildchain-v4-bridge/Cargo.lock +213 -0
  62. package/crates/buildchain-v4-bridge/Cargo.toml +12 -0
  63. package/crates/buildchain-v4-bridge/src/main.rs +495 -0
  64. package/dist/site/agent-index.json +0 -3
  65. package/dist/site/artifact-schemas.json +0 -6
  66. package/dist/site/buildchain-contract.json +103 -397
  67. package/dist/site/buildchain-site.json +302 -270
  68. package/dist/site/capability-registry.json +9 -11
  69. package/dist/site/cli-registry.json +8 -30
  70. package/dist/site/controller-registry.json +48 -8
  71. package/dist/site/kfd-claims.json +129 -142
  72. package/dist/site/kfd-upstream-aggregate.json +9 -9
  73. package/dist/site/manual-registry.json +18 -49
  74. package/dist/site/node-api-registry.json +1882 -4118
  75. package/dist/site/page-registry.json +278 -230
  76. package/dist/site/public-surface-audit.json +87 -185
  77. package/dist/site/publication-authority-registry.json +11 -1
  78. package/dist/site/publication-registry.json +4 -4
  79. package/dist/site/release-provenance.json +3 -7
  80. package/dist/site/schemas/kfd-support-projection-v1.schema.json +106 -0
  81. package/dist/site/site-manifest.json +22 -38
  82. package/dist/site/workflow-registry.json +80 -35
  83. package/docs/MAP.md +8 -4
  84. package/docs/auditable-demo.md +2 -2
  85. package/docs/aws-us-elastic-runner-burst-plane.md +7 -59
  86. package/docs/cli-reference.md +15 -92
  87. package/docs/cli.md +14 -14
  88. package/docs/dev-alpha-candidate-patrol.md +3 -11
  89. package/docs/dev-delivery-warrant.md +28 -100
  90. package/docs/engineering-housekeeper.md +12 -4
  91. package/docs/getting-started.md +1 -1
  92. package/docs/install.md +5 -5
  93. package/docs/kfd-support.md +2 -7
  94. package/docs/lifecycle-protocol.md +2 -4
  95. package/docs/node-api-reference.md +414 -523
  96. package/docs/release-flow.md +31 -31
  97. package/docs/release-governance.md +16 -28
  98. package/docs/release-passport.md +2 -15
  99. package/docs/release-tail-contract.md +13 -6
  100. package/docs/release-tail-provider-plane.md +13 -19
  101. package/docs/release-train.md +4 -4
  102. package/docs/reusable-build-surface.md +14 -27
  103. package/docs/site-bundle-contract.md +1 -5
  104. package/docs/stable-candidate-patrol.md +7 -7
  105. package/docs/v4-canonical-contracts.md +92 -0
  106. package/docs/v4-delivery-warrant-read-candidate.md +73 -0
  107. package/docs/v4-delivery-warrant-semantic-diff.md +75 -0
  108. package/docs/v4-production-release.md +63 -0
  109. package/docs/v4-stage-capsule.md +193 -0
  110. package/docs/versioning.md +3 -3
  111. package/package.json +19 -17
  112. package/packages/core/adopter-delivery-gate.js +576 -0
  113. package/packages/core/adopter-delivery-json.js +66 -0
  114. package/packages/core/artifact-signing.js +0 -61
  115. package/packages/core/artifact-verification-envelope.js +5 -5
  116. package/packages/core/build-facts.js +12 -4
  117. package/packages/core/buildchain-agent-manuals.js +0 -2
  118. package/packages/core/buildchain-config.js +4 -69
  119. package/packages/core/buildchain-contract.js +232 -46
  120. package/packages/core/buildchain-kfd-claims.js +1 -1
  121. package/packages/core/channel-candidate.js +0 -8
  122. package/packages/core/channel-promotion-baseline.js +0 -52
  123. package/packages/core/controller-evidence.js +3 -4
  124. package/packages/core/dev-alpha-candidate-selection.js +2 -10
  125. package/packages/core/dev-delivery-warrant-cancellation.js +0 -1
  126. package/packages/core/dev-delivery-warrant-settlement.js +1 -5
  127. package/packages/core/dev-delivery-warrant.js +12 -52
  128. package/packages/core/diagnostics.js +3 -8
  129. package/packages/core/github-governance-authority.js +3 -1
  130. package/packages/core/kfd-adopter-category-driver.js +167 -0
  131. package/packages/core/kfd-adopter-manifest.js +47 -46
  132. package/packages/core/kfd-gate.js +15 -45
  133. package/packages/core/paper-agent-entry.js +7 -16
  134. package/packages/core/paper-fleet.js +2 -2
  135. package/packages/core/paper-repository.js +2 -3
  136. package/packages/core/paper-scaffold-content.js +2 -23
  137. package/packages/core/paper.js +11 -43
  138. package/packages/core/publication-reproducibility.js +4 -4
  139. package/packages/core/release-line-bootstrap.js +21 -8
  140. package/packages/core/release-passport-contract.js +5 -5
  141. package/packages/core/release-passport.js +20 -131
  142. package/packages/core/self-dogfood-version.js +48 -35
  143. package/packages/core/spawn-command.js +232 -8
  144. package/packages/core/v4-adopter-delivery-parity.js +219 -0
  145. package/packages/core/v4-canonical-contracts.js +284 -0
  146. package/packages/core/v4-delivery-warrant-fixture-runner.js +371 -0
  147. package/packages/core/v4-delivery-warrant-read-candidate.js +279 -0
  148. package/packages/core/v4-delivery-warrant-semantic-diff-gate.js +352 -0
  149. package/packages/core/v4-delivery-warrant-shadow-adapter.js +447 -0
  150. package/packages/core/v4-partial-mutation-recovery-qualification.js +395 -0
  151. package/packages/core/v4-platform-stage-checkpoints.js +471 -0
  152. package/packages/core/v4-provider-operation-journal.js +531 -0
  153. package/packages/core/v4-provider-readback-idempotency.js +394 -0
  154. package/packages/core/v4-release-activation-shadow.js +519 -0
  155. package/packages/core/v4-stable-publication-fence.js +357 -0
  156. package/packages/core/v4-stage-capsule-local-store.js +426 -0
  157. package/packages/core/v4-stage-capsule-qualification-campaign.js +512 -0
  158. package/packages/core/v4-stage-capsule-qualification.js +456 -0
  159. package/packages/core/v4-stage-capsule-resume-planner.js +397 -0
  160. package/packages/core/v4-stage-capsule-store.js +401 -0
  161. package/packages/core/v4-stage-capsule.js +319 -0
  162. package/scripts/assemble-self-publication-admission.mjs +1 -1
  163. package/scripts/audit-publication-control-plane.mjs +5 -5
  164. package/scripts/auditable-demo-bundle-verification.mjs +3 -2
  165. package/scripts/auditable-demo-platform.mjs +2 -2
  166. package/scripts/auditable-demo-renditions.mjs +1 -1
  167. package/scripts/auditable-demo.mjs +2 -2
  168. package/scripts/aws-macos-jit-controller-core.mjs +13 -346
  169. package/scripts/aws-macos-jit-controller-runtime.mjs +2 -210
  170. package/scripts/aws-macos-jit-controller.mjs +37 -275
  171. package/scripts/aws-macos-jit-core.mjs +3 -41
  172. package/scripts/aws-macos-jit.mjs +0 -12
  173. package/scripts/aws-windows-jit-campaign.mjs +2 -2
  174. package/scripts/aws-windows-jit-controller-core.mjs +1 -1
  175. package/scripts/aws-windows-jit-controller.mjs +3 -3
  176. package/scripts/build-contract-core.mjs +3 -8
  177. package/scripts/build-standalone-binary.mjs +3 -14
  178. package/scripts/buildchain-channel-router.mjs +4 -0
  179. package/scripts/buildchain-cli-help.mjs +7 -13
  180. package/scripts/buildchain-contract-lock.mjs +0 -6
  181. package/scripts/check-action-bundles.mjs +3 -4
  182. package/scripts/check-internal-architecture.mjs +7 -6
  183. package/scripts/check-inventory.mjs +30 -25
  184. package/scripts/check-v4-public-dogfood-contract.mjs +270 -0
  185. package/scripts/create-release-bundle.mjs +8 -4
  186. package/scripts/dev-alpha-candidate-patrol.mjs +1 -22
  187. package/scripts/dev-delivery-proof.mjs +2 -54
  188. package/scripts/dev-delivery-warrant.mjs +59 -77
  189. package/scripts/dev-pr-auto-merge.mjs +4 -30
  190. package/scripts/dev-pr-delivery-warrant.mjs +0 -55
  191. package/scripts/dispatch-artifact-signing-authority.mjs +7 -4
  192. package/scripts/generate-buildchain-kfd-witnesses.mjs +94 -88
  193. package/scripts/generate-channel-build-workflow.mjs +54 -24
  194. package/scripts/generate-channel-promotion-workflow.mjs +15 -6
  195. package/scripts/generate-site-bundle.mjs +5 -21
  196. package/scripts/git-fetch-process-tree.mjs +34 -1
  197. package/scripts/init-repo.mjs +64 -159
  198. package/scripts/inspect-artifact-signing-requests.mjs +0 -6
  199. package/scripts/locked-source-checkout.mjs +3 -4
  200. package/scripts/maintainability-metrics.mjs +8 -2
  201. package/scripts/npm-publish-dry-run.mjs +2 -2
  202. package/scripts/npm-publish-transaction.mjs +2 -2
  203. package/scripts/publication-commit-evidence.mjs +23 -69
  204. package/scripts/release-candidate-resolver.mjs +11 -17
  205. package/scripts/release-tail.mjs +3 -49
  206. package/scripts/resume-from-candidate-run.mjs +9 -123
  207. package/scripts/run-lifecycle-core.mjs +12 -13
  208. package/scripts/seal-artifact-signing-requests.mjs +17 -21
  209. package/scripts/site-capability-metadata.mjs +2 -7
  210. package/scripts/stable-candidate-qualification.mjs +10 -10
  211. package/scripts/v4-architecture.mjs +12 -2
  212. package/scripts/v4-bridge-bootstrap.mjs +141 -0
  213. package/scripts/v4-bridge-evidence.mjs +141 -0
  214. package/scripts/v4-host-adapter.mjs +182 -0
  215. package/scripts/v4-platform-stage-checkpoint-rehearsal.mjs +207 -0
  216. package/scripts/v4-stage-capsule-qualification.mjs +528 -0
  217. package/scripts/v4-stage-capsule-resume-rehearsal.mjs +57 -0
  218. package/scripts/v4-warrant-shadow-plan.mjs +601 -0
  219. package/scripts/verify-golden-path.mjs +5 -5
  220. package/scripts/web-surface-cloudfront-rewrite.mjs +15 -15
  221. package/scripts/web-surface-core.mjs +2 -8
  222. package/scripts/workflow-call-contract.mjs +5 -184
  223. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-perspective.json +0 -16
  224. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-replay.json +0 -57
  225. package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +0 -47
  226. package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +0 -47
  227. package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +0 -40
  228. package/contracts/next-development-request-v1.schema.json +0 -66
  229. package/contracts/next-development-transition-v1.schema.json +0 -292
  230. package/contracts/publication-rehearsal-capsule-v1.schema.json +0 -173
  231. package/dist/site/schemas/publication-rehearsal-capsule-v1.schema.json +0 -269
  232. package/dist/site/schemas/release-tail-capabilities-v1.schema.json +0 -353
  233. package/dist/site/schemas/release-tail-provider-bindings-v1.schema.json +0 -94
  234. package/docs/next-development-transition.md +0 -119
  235. package/docs/publication-rehearsal.md +0 -94
  236. package/packages/core/buildchain-compatibility-proof.js +0 -631
  237. package/packages/core/dev-delivery-native-proof.js +0 -333
  238. package/packages/core/dev-delivery-warrant-shadow.js +0 -502
  239. package/packages/core/next-development-candidate-reservation.js +0 -186
  240. package/packages/core/next-development-controller.js +0 -726
  241. package/packages/core/next-development-projection.js +0 -288
  242. package/packages/core/next-development-transition.js +0 -738
  243. package/packages/core/publication-rehearsal-projection.js +0 -173
  244. package/packages/core/publication-rehearsal-runtime.js +0 -921
  245. package/scripts/aws-macos-jit-instance-rehydrate.mjs +0 -260
  246. package/scripts/aws-macos-jit-source-rebind.mjs +0 -724
  247. package/scripts/dev-delivery-native-run.mjs +0 -187
  248. package/scripts/dev-delivery-two-phase.mjs +0 -598
  249. package/scripts/generate-next-development-guidance.mjs +0 -49
  250. package/scripts/materialize-self-release-candidate-version.mjs +0 -137
  251. package/scripts/next-development-self-dogfood-harness.mjs +0 -409
  252. package/scripts/next-development-self-dogfood.mjs +0 -532
  253. package/scripts/next-development-transition.mjs +0 -47
  254. package/scripts/release-candidate-tail-reseal.mjs +0 -426
  255. package/templates/native-dev-delivery.yml +0 -82
@@ -0,0 +1,401 @@
1
+ import crypto from "node:crypto";
2
+
3
+ import {
4
+ V4ContractFault,
5
+ v4ContentRoot,
6
+ validateV4Clock,
7
+ validateV4Root,
8
+ } from "./v4-canonical-contracts.js";
9
+ import { validateV4StageCapsule } from "./v4-stage-capsule.js";
10
+
11
+ export const V4_STAGE_CAPSULE_OUTPUT_MANIFEST_CONTRACT =
12
+ "buildchain-v4-stage-capsule-output-manifest/v1";
13
+ export const V4_STAGE_CAPSULE_RETENTION_STATE_CONTRACT =
14
+ "buildchain-v4-stage-capsule-retention-state/v1";
15
+ export const V4_STAGE_CAPSULE_TRANSPORT_CONTRACT =
16
+ "buildchain-v4-stage-capsule-transport/v1";
17
+ export const V4_STAGE_CAPSULE_STORE_RECEIPT_CONTRACT =
18
+ "buildchain-v4-stage-capsule-store-receipt/v1";
19
+
20
+ const TOKEN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
21
+ const PROVIDERS = new Set([
22
+ "local-filesystem",
23
+ "github-artifacts",
24
+ "s3-compatible",
25
+ ]);
26
+ const TRANSPORT_MODES = new Set([
27
+ "local-reference",
28
+ "effect-disabled",
29
+ "fixture-backed",
30
+ ]);
31
+ const OPERATIONS = new Set(["put", "locate", "restore", "quarantine"]);
32
+ const OUTCOMES = new Set([
33
+ "stored",
34
+ "already-stored",
35
+ "located",
36
+ "restored",
37
+ "quarantined",
38
+ ]);
39
+
40
+ function fault(code, path, message) {
41
+ throw new V4ContractFault(code, path, message);
42
+ }
43
+
44
+ function exactKeys(value, keys, path) {
45
+ if (!value || typeof value !== "object" || Array.isArray(value))
46
+ fault(
47
+ "invalid-stage-capsule-store-shape",
48
+ path,
49
+ `${path} must be an object`,
50
+ );
51
+ const actual = Object.keys(value).sort();
52
+ const expected = [...keys].sort();
53
+ if (
54
+ actual.length !== expected.length ||
55
+ actual.some((key, index) => key !== expected[index])
56
+ )
57
+ fault(
58
+ "invalid-stage-capsule-store-shape",
59
+ path,
60
+ `${path} keys are not canonical`,
61
+ );
62
+ }
63
+
64
+ function token(value, path) {
65
+ if (typeof value !== "string" || !TOKEN.test(value))
66
+ fault(
67
+ "invalid-stage-capsule-store-token",
68
+ path,
69
+ `${path} must be an ASCII token`,
70
+ );
71
+ return value;
72
+ }
73
+
74
+ export function v4StageCapsuleBlobRoot(bytes) {
75
+ const value = Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes);
76
+ return `sha256:${crypto.createHash("sha256").update(value).digest("hex")}`;
77
+ }
78
+
79
+ function manifestPayload(value) {
80
+ return { schema: value.schema, entries: value.entries };
81
+ }
82
+
83
+ export function v4StageCapsuleOutputManifestRoot(value) {
84
+ validateV4StageCapsuleOutputManifest(value, { verifyRoot: false });
85
+ return v4ContentRoot("stage-capsule-output-manifest", manifestPayload(value));
86
+ }
87
+
88
+ export function validateV4StageCapsuleOutputManifest(
89
+ value,
90
+ { verifyRoot = true } = {},
91
+ ) {
92
+ exactKeys(value, ["schema", "entries", "manifestRoot"], "$/manifest");
93
+ if (value.schema !== V4_STAGE_CAPSULE_OUTPUT_MANIFEST_CONTRACT)
94
+ fault(
95
+ "unsupported-stage-capsule-store-version",
96
+ "$/manifest/schema",
97
+ "unsupported output manifest schema",
98
+ );
99
+ if (!Array.isArray(value.entries) || value.entries.length === 0)
100
+ fault(
101
+ "invalid-stage-capsule-store-shape",
102
+ "$/manifest/entries",
103
+ "output manifest entries must be non-empty",
104
+ );
105
+ let prior = null;
106
+ for (const [index, entry] of value.entries.entries()) {
107
+ const entryPath = `$/manifest/entries/${index}`;
108
+ exactKeys(entry, ["name", "root", "size"], entryPath);
109
+ token(entry.name, `${entryPath}/name`);
110
+ validateV4Root(entry.root, `${entryPath}/root`);
111
+ if (!Number.isSafeInteger(entry.size) || entry.size < 0)
112
+ fault(
113
+ "invalid-stage-capsule-content-size",
114
+ `${entryPath}/size`,
115
+ "content size must be a non-negative safe integer",
116
+ );
117
+ if (prior !== null && entry.name <= prior)
118
+ fault(
119
+ "unordered-stage-capsule-content",
120
+ `${entryPath}/name`,
121
+ "content names must be unique and byte-sorted",
122
+ );
123
+ prior = entry.name;
124
+ }
125
+ validateV4Root(value.manifestRoot, "$/manifest/manifestRoot");
126
+ if (
127
+ verifyRoot &&
128
+ value.manifestRoot !==
129
+ v4ContentRoot("stage-capsule-output-manifest", manifestPayload(value))
130
+ )
131
+ fault(
132
+ "stage-capsule-manifest-root-mismatch",
133
+ "$/manifest/manifestRoot",
134
+ "manifestRoot does not bind the canonical output manifest",
135
+ );
136
+ return value;
137
+ }
138
+
139
+ export function v4StageCapsuleRetentionPromiseRoot(promise) {
140
+ exactKeys(promise, ["class", "retainUntil"], "$/retentionPromise");
141
+ token(promise.class, "$/retentionPromise/class");
142
+ validateV4Clock(promise.retainUntil, "$/retentionPromise/retainUntil");
143
+ return v4ContentRoot("stage-capsule-retention-promise", promise);
144
+ }
145
+
146
+ export function createV4StageCapsuleRetentionState({ capsule, evaluatedAt }) {
147
+ validateV4StageCapsule(capsule);
148
+ validateV4Clock(evaluatedAt, "$/evaluatedAt");
149
+ const value = {
150
+ schema: V4_STAGE_CAPSULE_RETENTION_STATE_CONTRACT,
151
+ capsuleRoot: capsule.capsuleRoot,
152
+ promiseRoot: v4StageCapsuleRetentionPromiseRoot(capsule.retentionPromise),
153
+ evaluatedAt,
154
+ status:
155
+ evaluatedAt <= capsule.retentionPromise.retainUntil
156
+ ? "retained"
157
+ : "expired",
158
+ };
159
+ return {
160
+ ...value,
161
+ stateRoot: v4ContentRoot("stage-capsule-retention-state", value),
162
+ };
163
+ }
164
+
165
+ export function validateV4StageCapsuleRetentionState(value) {
166
+ exactKeys(
167
+ value,
168
+ [
169
+ "schema",
170
+ "capsuleRoot",
171
+ "promiseRoot",
172
+ "evaluatedAt",
173
+ "status",
174
+ "stateRoot",
175
+ ],
176
+ "$/retentionState",
177
+ );
178
+ if (value.schema !== V4_STAGE_CAPSULE_RETENTION_STATE_CONTRACT)
179
+ fault(
180
+ "unsupported-stage-capsule-store-version",
181
+ "$/retentionState/schema",
182
+ "unsupported retention-state schema",
183
+ );
184
+ validateV4Root(value.capsuleRoot, "$/retentionState/capsuleRoot");
185
+ validateV4Root(value.promiseRoot, "$/retentionState/promiseRoot");
186
+ validateV4Clock(value.evaluatedAt, "$/retentionState/evaluatedAt");
187
+ if (!new Set(["retained", "expired"]).has(value.status))
188
+ fault(
189
+ "invalid-stage-capsule-retention-state",
190
+ "$/retentionState/status",
191
+ "retention status must be retained or expired",
192
+ );
193
+ validateV4Root(value.stateRoot, "$/retentionState/stateRoot");
194
+ const { stateRoot, ...body } = value;
195
+ if (stateRoot !== v4ContentRoot("stage-capsule-retention-state", body))
196
+ fault(
197
+ "stage-capsule-retention-root-mismatch",
198
+ "$/retentionState/stateRoot",
199
+ "stateRoot does not bind the retention observation",
200
+ );
201
+ return value;
202
+ }
203
+
204
+ export function createV4StageCapsuleTransport({
205
+ provider,
206
+ mode,
207
+ locatorRoot,
208
+ observedAt,
209
+ }) {
210
+ token(provider, "$/transport/provider");
211
+ if (!PROVIDERS.has(provider) || !TRANSPORT_MODES.has(mode))
212
+ fault(
213
+ "unsupported-stage-capsule-transport",
214
+ "$/transport",
215
+ "unsupported transport provider or mode",
216
+ );
217
+ validateV4Root(locatorRoot, "$/transport/locatorRoot");
218
+ validateV4Clock(observedAt, "$/transport/observedAt");
219
+ const value = {
220
+ schema: V4_STAGE_CAPSULE_TRANSPORT_CONTRACT,
221
+ provider,
222
+ mode,
223
+ locatorRoot,
224
+ observedAt,
225
+ };
226
+ return {
227
+ ...value,
228
+ transportRoot: v4ContentRoot("stage-capsule-transport", value),
229
+ };
230
+ }
231
+
232
+ export function validateV4StageCapsuleTransport(value) {
233
+ exactKeys(
234
+ value,
235
+ [
236
+ "schema",
237
+ "provider",
238
+ "mode",
239
+ "locatorRoot",
240
+ "observedAt",
241
+ "transportRoot",
242
+ ],
243
+ "$/transport",
244
+ );
245
+ const rebuilt = createV4StageCapsuleTransport(value);
246
+ if (
247
+ rebuilt.schema !== value.schema ||
248
+ rebuilt.transportRoot !== value.transportRoot
249
+ )
250
+ fault(
251
+ "stage-capsule-transport-root-mismatch",
252
+ "$/transport/transportRoot",
253
+ "transportRoot does not bind the transport observation",
254
+ );
255
+ return value;
256
+ }
257
+
258
+ export function createV4StageCapsuleStoreReceipt(value) {
259
+ const body = {
260
+ schema: V4_STAGE_CAPSULE_STORE_RECEIPT_CONTRACT,
261
+ operation: value.operation,
262
+ recordedAt: value.recordedAt,
263
+ capsuleRoot: value.capsuleRoot,
264
+ manifestRoot: value.manifestRoot,
265
+ retentionStateRoot: value.retentionStateRoot,
266
+ availabilityRoot: value.availabilityRoot,
267
+ transportRoot: value.transportRoot,
268
+ qualificationRoot: value.qualificationRoot,
269
+ outcome: value.outcome,
270
+ faultCode: value.faultCode ?? null,
271
+ };
272
+ const receipt = {
273
+ ...body,
274
+ receiptRoot: v4ContentRoot("stage-capsule-store-receipt", body),
275
+ };
276
+ return validateV4StageCapsuleStoreReceipt(receipt);
277
+ }
278
+
279
+ export function validateV4StageCapsuleStoreReceipt(value) {
280
+ exactKeys(
281
+ value,
282
+ [
283
+ "schema",
284
+ "operation",
285
+ "recordedAt",
286
+ "capsuleRoot",
287
+ "manifestRoot",
288
+ "retentionStateRoot",
289
+ "availabilityRoot",
290
+ "transportRoot",
291
+ "qualificationRoot",
292
+ "outcome",
293
+ "faultCode",
294
+ "receiptRoot",
295
+ ],
296
+ "$/receipt",
297
+ );
298
+ if (value.schema !== V4_STAGE_CAPSULE_STORE_RECEIPT_CONTRACT)
299
+ fault(
300
+ "unsupported-stage-capsule-store-version",
301
+ "$/receipt/schema",
302
+ "unsupported store receipt schema",
303
+ );
304
+ if (!OPERATIONS.has(value.operation) || !OUTCOMES.has(value.outcome))
305
+ fault(
306
+ "invalid-stage-capsule-store-receipt",
307
+ "$/receipt",
308
+ "unsupported store operation or outcome",
309
+ );
310
+ validateV4Clock(value.recordedAt, "$/receipt/recordedAt");
311
+ for (const name of [
312
+ "capsuleRoot",
313
+ "manifestRoot",
314
+ "retentionStateRoot",
315
+ "availabilityRoot",
316
+ "transportRoot",
317
+ "qualificationRoot",
318
+ "receiptRoot",
319
+ ])
320
+ validateV4Root(value[name], `$/receipt/${name}`);
321
+ if (value.faultCode !== null)
322
+ fault(
323
+ "invalid-stage-capsule-store-receipt",
324
+ "$/receipt/faultCode",
325
+ "successful store receipts cannot carry a fault",
326
+ );
327
+ const { receiptRoot, ...body } = value;
328
+ if (receiptRoot !== v4ContentRoot("stage-capsule-store-receipt", body))
329
+ fault(
330
+ "stage-capsule-store-receipt-root-mismatch",
331
+ "$/receipt/receiptRoot",
332
+ "receiptRoot does not bind the store receipt",
333
+ );
334
+ return value;
335
+ }
336
+
337
+ function validateProviderRequest(operation, request) {
338
+ const keys =
339
+ operation === "put"
340
+ ? ["capsuleRoot", "manifestRoot", "locatorRoot", "recordedAt"]
341
+ : ["capsuleRoot", "locatorRoot", "recordedAt"];
342
+ exactKeys(request, keys, "$/adapter/request");
343
+ for (const name of keys.filter((name) => name.endsWith("Root")))
344
+ validateV4Root(request[name], `$/adapter/request/${name}`);
345
+ validateV4Clock(request.recordedAt, "$/adapter/request/recordedAt");
346
+ return request;
347
+ }
348
+
349
+ export function createV4StageCapsuleProviderAdapter({
350
+ provider,
351
+ mode = "effect-disabled",
352
+ fixture = null,
353
+ }) {
354
+ if (!new Set(["github-artifacts", "s3-compatible"]).has(provider))
355
+ fault(
356
+ "unsupported-stage-capsule-transport",
357
+ "$/provider",
358
+ "provider adapter must target GitHub artifacts or S3-compatible storage",
359
+ );
360
+ if (!new Set(["effect-disabled", "fixture-backed"]).has(mode))
361
+ fault(
362
+ "unsupported-stage-capsule-transport",
363
+ "$/mode",
364
+ "provider adapter mode is unsupported",
365
+ );
366
+ if (mode === "fixture-backed" && (!fixture || typeof fixture !== "object"))
367
+ fault(
368
+ "invalid-stage-capsule-store-shape",
369
+ "$/fixture",
370
+ "fixture-backed adapters require explicit fixture operations",
371
+ );
372
+ const invoke = (operation, request) => {
373
+ if (mode === "effect-disabled" || typeof fixture[operation] !== "function")
374
+ fault(
375
+ "stage-capsule-transport-disabled",
376
+ "$/adapter",
377
+ `${provider} ${operation} effects are disabled in this slice`,
378
+ );
379
+ const validated = validateProviderRequest(operation, request);
380
+ return {
381
+ authority: "fixture-only",
382
+ provider,
383
+ result: fixture[operation](validated),
384
+ };
385
+ };
386
+ return Object.freeze({
387
+ provider,
388
+ mode,
389
+ observe: (request) => {
390
+ exactKeys(request, ["locatorRoot", "observedAt"], "$/adapter/request");
391
+ return createV4StageCapsuleTransport({
392
+ provider,
393
+ mode,
394
+ locatorRoot: request.locatorRoot,
395
+ observedAt: request.observedAt,
396
+ });
397
+ },
398
+ put: (request) => invoke("put", request),
399
+ restore: (request) => invoke("restore", request),
400
+ });
401
+ }