@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,447 @@
1
+ import { spawn } from "node:child_process";
2
+ import crypto from "node:crypto";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ import { runV4DeliveryWarrantTraceFixture } from "./v4-delivery-warrant-fixture-runner.js";
7
+
8
+ export const V4_DELIVERY_WARRANT_SHADOW_OBSERVATION_CONTRACT =
9
+ "buildchain-v4-delivery-warrant-shadow-observation/v1";
10
+ export const V4_DELIVERY_WARRANT_SHADOW_RESULT_CONTRACT =
11
+ "buildchain-v4-delivery-warrant-shadow-result/v1";
12
+
13
+ const HOST_REQUEST_CONTRACT = "kungfu-buildchain-v4-host-request";
14
+ const HOST_RESPONSE_CONTRACT = "kungfu-buildchain-v4-host-response";
15
+ const PROJECTION_CONTRACT =
16
+ "buildchain-v4-delivery-warrant-semantic-projection/v1";
17
+ const REQUIRED_CAPABILITIES = Object.freeze([
18
+ "canonical-input-v1",
19
+ "delivery-warrant-trace-projection-v1",
20
+ "diagnostics-v1",
21
+ "effects-disabled-v1",
22
+ "structured-result-v1",
23
+ ]);
24
+ const MAX_RESPONSE_BYTES = 8 * 1024 * 1024;
25
+ const MAX_TIMEOUT_MS = 30_000;
26
+ const RETENTION_DAYS = 90;
27
+ const ROOT_PATTERN = /^sha256:[0-9a-f]{64}$/u;
28
+ const REVISION_PATTERN = /^[0-9a-f]{40,64}$/u;
29
+ const root = path.resolve(
30
+ path.dirname(fileURLToPath(import.meta.url)),
31
+ "../..",
32
+ );
33
+
34
+ class ShadowHostFault extends Error {
35
+ constructor(code, message) {
36
+ super(message);
37
+ this.name = "ShadowHostFault";
38
+ this.code = code;
39
+ }
40
+ }
41
+
42
+ function inputBytes(value) {
43
+ if (Buffer.isBuffer(value)) return Buffer.from(value);
44
+ if (value instanceof Uint8Array) return Buffer.from(value);
45
+ if (typeof value === "string") return Buffer.from(value, "utf8");
46
+ throw new TypeError("shadow input must be bytes or a UTF-8 string");
47
+ }
48
+
49
+ function sha256(bytes) {
50
+ return `sha256:${crypto.createHash("sha256").update(bytes).digest("hex")}`;
51
+ }
52
+
53
+ function diagnostic(code, retryable = false) {
54
+ const messages = {
55
+ "host-cancelled": "the non-authoritative Rust projection was cancelled",
56
+ "host-crashed": "the non-authoritative Rust projection host exited",
57
+ "host-response-invalid": "the Rust host response was malformed",
58
+ "host-response-mismatch": "the Rust host response correlation was invalid",
59
+ "host-spawn-failed":
60
+ "the non-authoritative Rust projection host could not start",
61
+ "host-timeout":
62
+ "the non-authoritative Rust projection exceeded its bounded timeout",
63
+ "input-not-public-safe":
64
+ "shadow input was not eligible for public-safe retention",
65
+ "retention-failed":
66
+ "the caller-owned shadow observation sink rejected the observation",
67
+ "rust-projection-failed":
68
+ "the Rust host did not produce a usable projection",
69
+ "shadow-config-invalid":
70
+ "the non-authoritative shadow configuration was invalid",
71
+ "shadow-disabled": "the non-authoritative Rust shadow is disabled",
72
+ "unsupported-capability":
73
+ "the Rust host did not support the effect-disabled projection contract",
74
+ };
75
+ return {
76
+ code,
77
+ message: messages[code] || "the Rust shadow was unavailable",
78
+ retryable,
79
+ };
80
+ }
81
+
82
+ function enabledByDefault(environment = process.env) {
83
+ return environment.BUILDCHAIN_V4_WARRANT_SHADOW === "enabled";
84
+ }
85
+
86
+ function publicRetention(retention = {}) {
87
+ if (retention.kind === "fixture") {
88
+ return { classification: "public-safe-fixture", publicSafe: true };
89
+ }
90
+ if (retention.kind === "captured-replay" && retention.publicSafe === true) {
91
+ return { classification: "public-safe-captured-replay", publicSafe: true };
92
+ }
93
+ throw new ShadowHostFault(
94
+ "input-not-public-safe",
95
+ "only fixtures and explicitly public-safe captured replays may enter shadow retention",
96
+ );
97
+ }
98
+
99
+ function exactSource(value, label) {
100
+ if (typeof value !== "string" || !REVISION_PATTERN.test(value)) {
101
+ throw new TypeError(`${label} must be an exact lowercase Git revision`);
102
+ }
103
+ return value;
104
+ }
105
+
106
+ function exactValidator(value) {
107
+ if (typeof value !== "string" || !/^[a-z0-9][a-z0-9._-]*$/u.test(value)) {
108
+ throw new TypeError("validatorVersion must be a public ASCII identifier");
109
+ }
110
+ return value;
111
+ }
112
+
113
+ function retainUntil(recordedAt) {
114
+ const time = Date.parse(recordedAt);
115
+ if (!Number.isFinite(time))
116
+ throw new TypeError("recordedAt must be an ISO timestamp");
117
+ return new Date(time + RETENTION_DAYS * 24 * 60 * 60 * 1000).toISOString();
118
+ }
119
+
120
+ export function createV4DeliveryWarrantShadowRequest(
121
+ bytes,
122
+ { requestId = crypto.randomUUID(), timeoutMs = 5_000 } = {},
123
+ ) {
124
+ if (
125
+ !Number.isInteger(timeoutMs) ||
126
+ timeoutMs < 1 ||
127
+ timeoutMs > MAX_TIMEOUT_MS
128
+ ) {
129
+ throw new RangeError(`timeoutMs must be between 1 and ${MAX_TIMEOUT_MS}`);
130
+ }
131
+ return {
132
+ schemaVersion: 1,
133
+ contract: HOST_REQUEST_CONTRACT,
134
+ protocolVersion: "1.0",
135
+ requestId,
136
+ command: { id: "delivery-warrant.trace-project", arguments: [] },
137
+ input: { encoding: "base64", bytes: inputBytes(bytes).toString("base64") },
138
+ requiredCapabilities: [...REQUIRED_CAPABILITIES],
139
+ timeoutMs,
140
+ };
141
+ }
142
+
143
+ function validateHostResponse(response, request) {
144
+ if (
145
+ !response ||
146
+ response.schemaVersion !== 1 ||
147
+ response.contract !== HOST_RESPONSE_CONTRACT ||
148
+ response.protocolVersion !== "1.0"
149
+ ) {
150
+ throw new ShadowHostFault(
151
+ "host-response-invalid",
152
+ "unsupported host response contract",
153
+ );
154
+ }
155
+ if (
156
+ response.requestId !== request.requestId ||
157
+ response.command?.id !== request.command.id
158
+ ) {
159
+ throw new ShadowHostFault(
160
+ "host-response-mismatch",
161
+ "host response correlation mismatch",
162
+ );
163
+ }
164
+ if (!Array.isArray(response.host?.capabilities)) {
165
+ throw new ShadowHostFault(
166
+ "host-response-invalid",
167
+ "host capabilities are missing",
168
+ );
169
+ }
170
+ const missing = REQUIRED_CAPABILITIES.filter(
171
+ (capability) => !response.host.capabilities.includes(capability),
172
+ );
173
+ if (response.status === "unsupported" || missing.length > 0) {
174
+ throw new ShadowHostFault(
175
+ "unsupported-capability",
176
+ "required host capability is missing",
177
+ );
178
+ }
179
+ if (response.status !== "ok") {
180
+ throw new ShadowHostFault(
181
+ "rust-projection-failed",
182
+ "Rust projection status was not ok",
183
+ );
184
+ }
185
+ const result = response.structuredResult;
186
+ if (
187
+ result?.projection?.schema !== PROJECTION_CONTRACT ||
188
+ !ROOT_PATTERN.test(String(result?.projectionRoot || ""))
189
+ ) {
190
+ throw new ShadowHostFault(
191
+ "host-response-invalid",
192
+ "Rust projection shape is invalid",
193
+ );
194
+ }
195
+ return result;
196
+ }
197
+
198
+ function defaultHost() {
199
+ return {
200
+ command: "cargo",
201
+ arguments: [
202
+ "run",
203
+ "--locked",
204
+ "--quiet",
205
+ "--manifest-path",
206
+ path.join(root, "crates", "buildchain-v4-contracts", "Cargo.toml"),
207
+ "--",
208
+ "host",
209
+ ],
210
+ };
211
+ }
212
+
213
+ export function invokeV4RustShadowHost(
214
+ request,
215
+ { command, arguments: commandArguments, cwd = root, signal } = {},
216
+ ) {
217
+ const selected = defaultHost();
218
+ const executable = command || selected.command;
219
+ const args = commandArguments || selected.arguments;
220
+ return new Promise((resolve, reject) => {
221
+ if (signal?.aborted) {
222
+ reject(
223
+ new ShadowHostFault(
224
+ "host-cancelled",
225
+ "shadow signal was already aborted",
226
+ ),
227
+ );
228
+ return;
229
+ }
230
+ let settled = false;
231
+ let terminationCode = "";
232
+ let stdoutBytes = 0;
233
+ const stdout = [];
234
+ const child = spawn(executable, args, {
235
+ cwd,
236
+ env: process.env,
237
+ stdio: ["pipe", "pipe", "ignore"],
238
+ });
239
+ const finish = (callback) => {
240
+ if (settled) return;
241
+ settled = true;
242
+ clearTimeout(timeout);
243
+ signal?.removeEventListener("abort", cancel);
244
+ callback();
245
+ };
246
+ const terminate = (code) => {
247
+ if (terminationCode) return;
248
+ terminationCode = code;
249
+ child.kill("SIGTERM");
250
+ const force = setTimeout(() => child.kill("SIGKILL"), 100);
251
+ force.unref?.();
252
+ };
253
+ const cancel = () => terminate("host-cancelled");
254
+ const timeout = setTimeout(
255
+ () => terminate("host-timeout"),
256
+ request.timeoutMs,
257
+ );
258
+ timeout.unref?.();
259
+ signal?.addEventListener("abort", cancel, { once: true });
260
+ child.once("error", () => {
261
+ finish(() =>
262
+ reject(new ShadowHostFault("host-spawn-failed", "host spawn failed")),
263
+ );
264
+ });
265
+ child.stdout.on("data", (chunk) => {
266
+ stdoutBytes += chunk.length;
267
+ if (stdoutBytes > MAX_RESPONSE_BYTES) {
268
+ terminate("host-response-invalid");
269
+ return;
270
+ }
271
+ stdout.push(chunk);
272
+ });
273
+ child.stdin.on("error", () => {
274
+ terminate("host-crashed");
275
+ });
276
+ child.once("close", (code) => {
277
+ finish(() => {
278
+ if (terminationCode) {
279
+ reject(
280
+ new ShadowHostFault(
281
+ terminationCode,
282
+ "shadow host terminated and reaped",
283
+ ),
284
+ );
285
+ return;
286
+ }
287
+ if (code !== 0) {
288
+ reject(
289
+ new ShadowHostFault(
290
+ "host-crashed",
291
+ "shadow host exited before a response",
292
+ ),
293
+ );
294
+ return;
295
+ }
296
+ try {
297
+ resolve(JSON.parse(Buffer.concat(stdout).toString("utf8")));
298
+ } catch {
299
+ reject(
300
+ new ShadowHostFault(
301
+ "host-response-invalid",
302
+ "shadow host returned invalid JSON",
303
+ ),
304
+ );
305
+ }
306
+ });
307
+ });
308
+ child.stdin.end(`${JSON.stringify(request)}\n`);
309
+ });
310
+ }
311
+
312
+ function skippedShadow(inputRoot, code) {
313
+ return {
314
+ status: "skipped",
315
+ authority: "typescript-v3",
316
+ rustAuthority: "none",
317
+ rustEffects: "disabled",
318
+ inputRoot,
319
+ observation: null,
320
+ diagnostics: [diagnostic(code)],
321
+ retention: { status: "not-attempted" },
322
+ };
323
+ }
324
+
325
+ export async function runV4DeliveryWarrantShadow(
326
+ value,
327
+ {
328
+ enabled = enabledByDefault(),
329
+ invokeLegacy = runV4DeliveryWarrantTraceFixture,
330
+ invokeRust = invokeV4RustShadowHost,
331
+ host = {},
332
+ requestId,
333
+ timeoutMs = 5_000,
334
+ signal,
335
+ retention = { kind: "fixture" },
336
+ retain,
337
+ recordedAt = new Date().toISOString(),
338
+ sources = {},
339
+ } = {},
340
+ ) {
341
+ const bytes = inputBytes(value);
342
+ const authoritativeResult = await invokeLegacy(Buffer.from(bytes));
343
+ const inputRoot = sha256(bytes);
344
+ if (!enabled) {
345
+ return {
346
+ schema: V4_DELIVERY_WARRANT_SHADOW_RESULT_CONTRACT,
347
+ authoritativeResult,
348
+ shadow: skippedShadow(inputRoot, "shadow-disabled"),
349
+ };
350
+ }
351
+
352
+ let retentionScope;
353
+ try {
354
+ retentionScope = publicRetention(retention);
355
+ } catch (error) {
356
+ return {
357
+ schema: V4_DELIVERY_WARRANT_SHADOW_RESULT_CONTRACT,
358
+ authoritativeResult,
359
+ shadow: skippedShadow(inputRoot, error.code || "input-not-public-safe"),
360
+ };
361
+ }
362
+
363
+ let sourceBinding;
364
+ let request;
365
+ try {
366
+ sourceBinding = {
367
+ typescriptRevision: exactSource(
368
+ sources.typescriptRevision,
369
+ "typescriptRevision",
370
+ ),
371
+ rustRevision: exactSource(sources.rustRevision, "rustRevision"),
372
+ validatorVersion: exactValidator(sources.validatorVersion),
373
+ };
374
+ request = createV4DeliveryWarrantShadowRequest(bytes, {
375
+ requestId,
376
+ timeoutMs,
377
+ });
378
+ } catch {
379
+ return {
380
+ schema: V4_DELIVERY_WARRANT_SHADOW_RESULT_CONTRACT,
381
+ authoritativeResult,
382
+ shadow: skippedShadow(inputRoot, "shadow-config-invalid"),
383
+ };
384
+ }
385
+ let rustProjection = null;
386
+ let status = "observed";
387
+ const diagnostics = [];
388
+ try {
389
+ const response = await invokeRust(request, { ...host, signal });
390
+ rustProjection = validateHostResponse(response, request);
391
+ } catch (error) {
392
+ const code =
393
+ error instanceof ShadowHostFault ? error.code : "rust-projection-failed";
394
+ diagnostics.push(diagnostic(code, code === "host-timeout"));
395
+ status = code === "host-cancelled" ? "cancelled" : "unavailable";
396
+ }
397
+
398
+ const observation = {
399
+ schema: V4_DELIVERY_WARRANT_SHADOW_OBSERVATION_CONTRACT,
400
+ authority: "typescript-v3",
401
+ rustAuthority: "none",
402
+ rustEffects: "disabled",
403
+ status,
404
+ recordedAt,
405
+ retainUntil: retainUntil(recordedAt),
406
+ retention: retentionScope,
407
+ input: {
408
+ encoding: "base64",
409
+ bytes: bytes.toString("base64"),
410
+ root: inputRoot,
411
+ },
412
+ sources: sourceBinding,
413
+ legacy: {
414
+ sourceRevision: sourceBinding.typescriptRevision,
415
+ projection: authoritativeResult,
416
+ },
417
+ rust: {
418
+ sourceRevision: sourceBinding.rustRevision,
419
+ projection: rustProjection,
420
+ },
421
+ diagnostics,
422
+ };
423
+ let retentionResult = { status: "returned-to-caller" };
424
+ if (retain) {
425
+ try {
426
+ await retain(structuredClone(observation));
427
+ retentionResult = { status: "retained" };
428
+ } catch {
429
+ diagnostics.push(diagnostic("retention-failed", true));
430
+ retentionResult = { status: "failed" };
431
+ }
432
+ }
433
+ return {
434
+ schema: V4_DELIVERY_WARRANT_SHADOW_RESULT_CONTRACT,
435
+ authoritativeResult,
436
+ shadow: {
437
+ status,
438
+ authority: "typescript-v3",
439
+ rustAuthority: "none",
440
+ rustEffects: "disabled",
441
+ inputRoot,
442
+ observation,
443
+ diagnostics,
444
+ retention: retentionResult,
445
+ },
446
+ };
447
+ }