@kungfu-tech/buildchain 3.0.9-alpha.9 → 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 (262) 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 -10
  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 -4
  65. package/dist/site/artifact-schemas.json +0 -8
  66. package/dist/site/buildchain-contract.json +103 -397
  67. package/dist/site/buildchain-site.json +302 -386
  68. package/dist/site/capability-registry.json +9 -11
  69. package/dist/site/cli-registry.json +8 -53
  70. package/dist/site/controller-registry.json +48 -8
  71. package/dist/site/kfd-claims.json +129 -167
  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 +4345 -7345
  75. package/dist/site/page-registry.json +278 -346
  76. package/dist/site/public-surface-audit.json +85 -404
  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 -9
  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 +78 -35
  83. package/docs/MAP.md +8 -5
  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 -213
  87. package/docs/cli.md +14 -14
  88. package/docs/dev-alpha-candidate-patrol.md +3 -11
  89. package/docs/dev-delivery-warrant.md +29 -194
  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 -554
  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 -5
  111. package/package.json +19 -19
  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-channel-identity.js +3 -2
  119. package/packages/core/buildchain-config.js +4 -69
  120. package/packages/core/buildchain-contract.js +232 -46
  121. package/packages/core/buildchain-kfd-claims.js +1 -1
  122. package/packages/core/channel-candidate.js +0 -8
  123. package/packages/core/channel-promotion-baseline.js +0 -52
  124. package/packages/core/controller-evidence.js +3 -4
  125. package/packages/core/dev-alpha-candidate-selection.js +2 -10
  126. package/packages/core/dev-delivery-warrant-cancellation.js +0 -1
  127. package/packages/core/dev-delivery-warrant-settlement.js +20 -67
  128. package/packages/core/dev-delivery-warrant.js +50 -138
  129. package/packages/core/diagnostics.js +3 -8
  130. package/packages/core/github-governance-authority.js +3 -1
  131. package/packages/core/kfd-adopter-category-driver.js +167 -0
  132. package/packages/core/kfd-adopter-manifest.js +47 -46
  133. package/packages/core/kfd-gate.js +15 -45
  134. package/packages/core/paper-agent-entry.js +7 -16
  135. package/packages/core/paper-fleet.js +2 -2
  136. package/packages/core/paper-repository.js +2 -3
  137. package/packages/core/paper-scaffold-content.js +2 -23
  138. package/packages/core/paper.js +11 -43
  139. package/packages/core/publication-reproducibility.js +4 -4
  140. package/packages/core/release-line-bootstrap.js +21 -8
  141. package/packages/core/release-passport-contract.js +5 -5
  142. package/packages/core/release-passport.js +20 -131
  143. package/packages/core/self-dogfood-version.js +48 -35
  144. package/packages/core/spawn-command.js +232 -8
  145. package/packages/core/v4-adopter-delivery-parity.js +219 -0
  146. package/packages/core/v4-canonical-contracts.js +284 -0
  147. package/packages/core/v4-delivery-warrant-fixture-runner.js +371 -0
  148. package/packages/core/v4-delivery-warrant-read-candidate.js +279 -0
  149. package/packages/core/v4-delivery-warrant-semantic-diff-gate.js +352 -0
  150. package/packages/core/v4-delivery-warrant-shadow-adapter.js +447 -0
  151. package/packages/core/v4-partial-mutation-recovery-qualification.js +395 -0
  152. package/packages/core/v4-platform-stage-checkpoints.js +471 -0
  153. package/packages/core/v4-provider-operation-journal.js +531 -0
  154. package/packages/core/v4-provider-readback-idempotency.js +394 -0
  155. package/packages/core/v4-release-activation-shadow.js +519 -0
  156. package/packages/core/v4-stable-publication-fence.js +357 -0
  157. package/packages/core/v4-stage-capsule-local-store.js +426 -0
  158. package/packages/core/v4-stage-capsule-qualification-campaign.js +512 -0
  159. package/packages/core/v4-stage-capsule-qualification.js +456 -0
  160. package/packages/core/v4-stage-capsule-resume-planner.js +397 -0
  161. package/packages/core/v4-stage-capsule-store.js +401 -0
  162. package/packages/core/v4-stage-capsule.js +319 -0
  163. package/scripts/assemble-self-publication-admission.mjs +1 -1
  164. package/scripts/audit-publication-control-plane.mjs +5 -5
  165. package/scripts/auditable-demo-bundle-verification.mjs +3 -2
  166. package/scripts/auditable-demo-platform.mjs +2 -2
  167. package/scripts/auditable-demo-renditions.mjs +1 -1
  168. package/scripts/auditable-demo.mjs +2 -2
  169. package/scripts/aws-macos-jit-controller-core.mjs +13 -346
  170. package/scripts/aws-macos-jit-controller-runtime.mjs +2 -210
  171. package/scripts/aws-macos-jit-controller.mjs +37 -275
  172. package/scripts/aws-macos-jit-core.mjs +3 -41
  173. package/scripts/aws-macos-jit.mjs +0 -12
  174. package/scripts/aws-windows-jit-campaign.mjs +2 -2
  175. package/scripts/aws-windows-jit-controller-core.mjs +1 -1
  176. package/scripts/aws-windows-jit-controller.mjs +3 -3
  177. package/scripts/build-contract-core.mjs +3 -8
  178. package/scripts/build-standalone-binary.mjs +3 -14
  179. package/scripts/buildchain-channel-router.mjs +4 -0
  180. package/scripts/buildchain-cli-help.mjs +7 -16
  181. package/scripts/buildchain-contract-lock.mjs +0 -6
  182. package/scripts/check-action-bundles.mjs +3 -4
  183. package/scripts/check-internal-architecture.mjs +7 -6
  184. package/scripts/check-inventory.mjs +30 -25
  185. package/scripts/check-v4-public-dogfood-contract.mjs +270 -0
  186. package/scripts/create-release-bundle.mjs +8 -4
  187. package/scripts/dev-alpha-candidate-patrol.mjs +1 -22
  188. package/scripts/dev-delivery-proof.mjs +2 -64
  189. package/scripts/dev-delivery-warrant.mjs +61 -86
  190. package/scripts/dev-pr-auto-merge.mjs +4 -30
  191. package/scripts/dev-pr-delivery-warrant.mjs +0 -55
  192. package/scripts/dispatch-artifact-signing-authority.mjs +7 -4
  193. package/scripts/generate-buildchain-kfd-witnesses.mjs +94 -88
  194. package/scripts/generate-channel-build-workflow.mjs +54 -24
  195. package/scripts/generate-channel-promotion-workflow.mjs +15 -6
  196. package/scripts/generate-site-bundle.mjs +8 -27
  197. package/scripts/git-fetch-process-tree.mjs +34 -1
  198. package/scripts/init-repo.mjs +64 -159
  199. package/scripts/inspect-artifact-signing-requests.mjs +0 -6
  200. package/scripts/locked-source-checkout.mjs +3 -4
  201. package/scripts/maintainability-metrics.mjs +8 -2
  202. package/scripts/npm-publish-dry-run.mjs +2 -2
  203. package/scripts/npm-publish-transaction.mjs +2 -2
  204. package/scripts/publication-commit-evidence.mjs +23 -69
  205. package/scripts/release-candidate-resolver.mjs +11 -17
  206. package/scripts/release-tail.mjs +3 -49
  207. package/scripts/resume-from-candidate-run.mjs +9 -123
  208. package/scripts/run-lifecycle-core.mjs +12 -13
  209. package/scripts/seal-artifact-signing-requests.mjs +17 -21
  210. package/scripts/site-capability-metadata.mjs +3 -20
  211. package/scripts/stable-candidate-qualification.mjs +10 -10
  212. package/scripts/v4-architecture.mjs +12 -2
  213. package/scripts/v4-bridge-bootstrap.mjs +141 -0
  214. package/scripts/v4-bridge-evidence.mjs +141 -0
  215. package/scripts/v4-host-adapter.mjs +182 -0
  216. package/scripts/v4-platform-stage-checkpoint-rehearsal.mjs +207 -0
  217. package/scripts/v4-stage-capsule-qualification.mjs +528 -0
  218. package/scripts/v4-stage-capsule-resume-rehearsal.mjs +57 -0
  219. package/scripts/v4-warrant-shadow-plan.mjs +601 -0
  220. package/scripts/verify-golden-path.mjs +5 -5
  221. package/scripts/web-surface-cloudfront-rewrite.mjs +15 -15
  222. package/scripts/web-surface-core.mjs +2 -8
  223. package/scripts/workflow-call-contract.mjs +5 -184
  224. package/contracts/dev-delivery-authority-v2.schema.json +0 -253
  225. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-perspective.json +0 -16
  226. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-replay.json +0 -57
  227. package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +0 -47
  228. package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +0 -47
  229. package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +0 -40
  230. package/contracts/next-development-request-v1.schema.json +0 -66
  231. package/contracts/next-development-transition-v1.schema.json +0 -292
  232. package/contracts/publication-rehearsal-capsule-v1.schema.json +0 -173
  233. package/dist/site/schemas/dev-delivery-authority-v2.schema.json +0 -442
  234. package/dist/site/schemas/publication-rehearsal-capsule-v1.schema.json +0 -269
  235. package/dist/site/schemas/release-tail-capabilities-v1.schema.json +0 -353
  236. package/dist/site/schemas/release-tail-provider-bindings-v1.schema.json +0 -94
  237. package/docs/dev-delivery-qualification-landing-adr.md +0 -137
  238. package/docs/next-development-transition.md +0 -119
  239. package/docs/publication-rehearsal.md +0 -94
  240. package/packages/core/buildchain-compatibility-proof.js +0 -631
  241. package/packages/core/dev-delivery-authority.js +0 -996
  242. package/packages/core/dev-delivery-native-proof.js +0 -418
  243. package/packages/core/dev-delivery-warrant-shadow.js +0 -502
  244. package/packages/core/next-development-candidate-reservation.js +0 -186
  245. package/packages/core/next-development-controller.js +0 -726
  246. package/packages/core/next-development-projection.js +0 -288
  247. package/packages/core/next-development-transition.js +0 -738
  248. package/packages/core/publication-rehearsal-projection.js +0 -173
  249. package/packages/core/publication-rehearsal-runtime.js +0 -921
  250. package/scripts/aws-macos-jit-instance-rehydrate.mjs +0 -260
  251. package/scripts/aws-macos-jit-source-rebind.mjs +0 -724
  252. package/scripts/dev-delivery-authority.mjs +0 -368
  253. package/scripts/dev-delivery-native-run.mjs +0 -235
  254. package/scripts/dev-delivery-two-phase-resume.mjs +0 -90
  255. package/scripts/dev-delivery-two-phase.mjs +0 -577
  256. package/scripts/generate-next-development-guidance.mjs +0 -49
  257. package/scripts/materialize-self-release-candidate-version.mjs +0 -137
  258. package/scripts/next-development-self-dogfood-harness.mjs +0 -409
  259. package/scripts/next-development-self-dogfood.mjs +0 -532
  260. package/scripts/next-development-transition.mjs +0 -47
  261. package/scripts/release-candidate-tail-reseal.mjs +0 -426
  262. package/templates/native-dev-delivery.yml +0 -86
@@ -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
+ }