@pulse-compute/wasm-compiler 0.0.0 → 1.0.0-beta.2

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 (104) hide show
  1. package/README.md +53 -1
  2. package/bin/provider-proof-composition.js +34 -0
  3. package/bin/pulsewasm-extract.js +20 -0
  4. package/package.json +60 -5
  5. package/src/artifacts-dir.js +13 -0
  6. package/src/ast-json.js +52 -0
  7. package/src/build-manifest.js +354 -0
  8. package/src/canonical-api-compiler.js +269 -0
  9. package/src/canonical-native-compiler.js +411 -0
  10. package/src/canonical-native-plan.js +1478 -0
  11. package/src/canonical-project-compiler.js +1224 -0
  12. package/src/canonical-router-compiler.js +25 -0
  13. package/src/cli-intents.js +1235 -0
  14. package/src/cli.js +1927 -0
  15. package/src/codegen/assemblyscript-compile.js +3 -0
  16. package/src/codegen/assemblyscript-core.js +3 -0
  17. package/src/codegen/assemblyscript-shape.js +3 -0
  18. package/src/codegen/assemblyscript-wasm-smoke.js +3 -0
  19. package/src/codegen/backend-capabilities.js +3 -0
  20. package/src/codegen/channel-broadcaster.js +3 -0
  21. package/src/codegen/compiled-handlers.js +3 -0
  22. package/src/codegen/compiled-wasm-runtime.js +3 -0
  23. package/src/codegen/config-references.js +248 -0
  24. package/src/codegen/dispatch-ts.js +145 -0
  25. package/src/codegen/effect-composition.js +331 -0
  26. package/src/codegen/effect-runtime.js +418 -0
  27. package/src/codegen/execution-harness-ts.js +467 -0
  28. package/src/codegen/handler-bindings-ts.js +298 -0
  29. package/src/codegen/handler-library-contracts.js +3 -0
  30. package/src/codegen/host-capabilities.js +3 -0
  31. package/src/codegen/host-runtime-kernel.js +3 -0
  32. package/src/codegen/integrated-compiled-app.js +3 -0
  33. package/src/codegen/json-body.js +3 -0
  34. package/src/codegen/library-sidecars.js +3 -0
  35. package/src/codegen/local-harness-ts.js +453 -0
  36. package/src/codegen/pulse-wrapper.js +217 -0
  37. package/src/codegen/request-result-headers.js +3 -0
  38. package/src/codegen/schema-json-compile.js +3 -0
  39. package/src/codegen/schema-json-sidecar-v2.js +3 -0
  40. package/src/codegen/schema-json-sidecar.js +3 -0
  41. package/src/codegen/streaming-passthrough.js +3 -0
  42. package/src/codegen/wasm-host-abi.js +3 -0
  43. package/src/codegen/wasm-host-bridge.js +3 -0
  44. package/src/compiled-wasm-host-runtime-kv.js +3 -0
  45. package/src/config-resolver.js +813 -0
  46. package/src/crypto-requirement-planner.js +89 -0
  47. package/src/definitions/config-schema.js +14 -0
  48. package/src/definitions/handler-roles.js +14 -0
  49. package/src/definitions/path-grammar.js +14 -0
  50. package/src/definitions/router-api.js +14 -0
  51. package/src/diagnostics/codes.js +14 -0
  52. package/src/diagnostics/reporter.js +14 -0
  53. package/src/diagnostics.js +14 -0
  54. package/src/dispatch-table.js +400 -0
  55. package/src/events/event-emit.js +265 -0
  56. package/src/events/event-topology.js +127 -0
  57. package/src/execution-plan.js +463 -0
  58. package/src/extractor.js +2816 -0
  59. package/src/handler-eval.js +1154 -0
  60. package/src/handler-table.js +326 -0
  61. package/src/index.js +19 -0
  62. package/src/javascript-application-plan.js +181 -0
  63. package/src/kv-provider.js +3 -0
  64. package/src/path-table.js +60 -0
  65. package/src/path.js +14 -0
  66. package/src/patterns/config-define.js +30 -0
  67. package/src/patterns/dependency-call.js +18 -0
  68. package/src/patterns/env-lookup.js +13 -0
  69. package/src/patterns/handler-reference.js +29 -0
  70. package/src/patterns/path-literal.js +35 -0
  71. package/src/patterns/result.js +15 -0
  72. package/src/patterns/router-chain-call.js +50 -0
  73. package/src/patterns/router-construction.js +19 -0
  74. package/src/project/package-reachability.js +782 -0
  75. package/src/project/reachable-graph-builder.js +992 -0
  76. package/src/project/reachable-graph-contract.js +54 -0
  77. package/src/project/reachable-graph-implementation.js +36 -0
  78. package/src/project/router-module-linker.js +710 -0
  79. package/src/project-config-compiler.js +222 -0
  80. package/src/project-target-support.js +500 -0
  81. package/src/provider-toolchain.js +299 -0
  82. package/src/spine/async-surface-normalizer.js +328 -0
  83. package/src/spine/canonical-handler-ir.js +336 -0
  84. package/src/spine/canonical-native-module.js +87 -0
  85. package/src/spine/canonical-native-plan.js +89 -0
  86. package/src/spine/canonical-project.js +76 -0
  87. package/src/spine/canonical-router.js +155 -0
  88. package/src/spine/canonical-source.js +165 -0
  89. package/src/spine/diagnostic-authority.js +290 -0
  90. package/src/spine/equivalence.js +262 -0
  91. package/src/spine/guest-unit-stage.js +87 -0
  92. package/src/spine/handler-ir-emitter.js +455 -0
  93. package/src/spine/handler-ir-managed.js +1598 -0
  94. package/src/spine/handler-ir.js +797 -0
  95. package/src/spine/handler-surface-authority.js +588 -0
  96. package/src/spine/package-operation-seam.js +1015 -0
  97. package/src/spine/pipeline.js +202 -0
  98. package/src/spine/plain-handler-frontend.js +545 -0
  99. package/src/spine/provider-requirement-authority.js +208 -0
  100. package/src/spine/router-control-contract.js +17 -0
  101. package/src/spine/router-handler-frontend.js +514 -0
  102. package/src/spine/router-handler-ir.js +372 -0
  103. package/src/spine/router-topology-frontend.js +638 -0
  104. package/src/stable-id.js +14 -0
@@ -0,0 +1,1235 @@
1
+ 'use strict';
2
+
3
+ const CLI_INTENT_VERSION = 'pulsewasm.cli-intent.v1';
4
+ const CLI_DOCTOR_VERSION = 'pulsewasm.cli-doctor.v1';
5
+ const CLI_EXPLAIN_VERSION = 'pulsewasm.cli-explain.v1';
6
+ const CLI_ARTIFACTS_VERSION = 'pulsewasm.cli-artifacts.v1';
7
+
8
+
9
+ function loadDoctorReadinessAggregatorContract() {
10
+ try {
11
+ return require('@pulse-compute/wasm-contracts/handler/doctor-readiness-aggregator');
12
+ } catch (_) {
13
+ return require('../../contracts/src/handler/doctor-readiness-aggregator.js');
14
+ }
15
+ }
16
+
17
+ const { DOCTOR_READINESS_AGGREGATOR_VERSION } = loadDoctorReadinessAggregatorContract();
18
+
19
+ const INTENT_COMMANDS = ['build', 'plan', 'doctor', 'explain', 'artifacts', 'resolve-config'];
20
+ const PLAN_DEFAULT_FEATURES = ['routes', 'libraries', 'assets', 'route-context', 'route-effects', 'handler-io', 'request-json', 'schema-decode-result', 'schema-response-codec', 'backend-json-request-body'];
21
+ const DOCTOR_DEFAULT_FEATURES = ['routes', 'libraries', 'assets', 'route-context', 'route-effects', 'handler-io', 'request-json', 'schema-decode-result', 'schema-response-codec', 'backend-json-request-body'];
22
+
23
+ function splitList(value) {
24
+ return String(value || '')
25
+ .split(',')
26
+ .map((item) => item.trim())
27
+ .filter(Boolean);
28
+ }
29
+
30
+ function pushUnique(list, values) {
31
+ for (const value of values) {
32
+ if (!list.includes(value)) list.push(value);
33
+ }
34
+ return list;
35
+ }
36
+
37
+ function normalizeFeatureName(feature) {
38
+ return String(feature || '').trim().toLowerCase().replace(/_/g, '-');
39
+ }
40
+
41
+ function enableDispatch(args) {
42
+ args.emitDispatchTs = true;
43
+ }
44
+
45
+ function enableHandlerBindings(args) {
46
+ args.emitHandlerBindings = true;
47
+ enableDispatch(args);
48
+ }
49
+
50
+ function enableExecutionHarness(args) {
51
+ args.emitExecutionHarness = true;
52
+ enableHandlerBindings(args);
53
+ }
54
+
55
+ function enableAsShape(args) {
56
+ args.emitAssemblyScriptShape = true;
57
+ }
58
+
59
+ function enableAsCore(args) {
60
+ args.emitAssemblyScriptCore = true;
61
+ enableAsShape(args);
62
+ }
63
+
64
+ function enableHostAbi(args) {
65
+ args.emitWasmHostAbi = true;
66
+ }
67
+
68
+ function enableJsonBody(args) {
69
+ args.emitJsonBody = true;
70
+ args.emitRequestResultHeaders = true;
71
+ enableHostAbi(args);
72
+ }
73
+
74
+ function enableLibraries(args) {
75
+ args.emitHandlerLibraryContracts = true;
76
+ }
77
+
78
+ function enableAssets(args) {
79
+ args.emitAssetsLoweringPlan = true;
80
+ enableLibraries(args);
81
+ }
82
+
83
+ function enableHostCapabilities(args) {
84
+ args.emitHostCapabilities = true;
85
+ enableLibraries(args);
86
+ args.emitRequestResultHeaders = true;
87
+ args.emitChannelBroadcaster = true;
88
+ enableJsonBody(args);
89
+ args.emitBackendCapabilities = true;
90
+ }
91
+
92
+ function enableEffects(args) {
93
+ args.emitEffectComposition = true;
94
+ args.emitEffectRuntime = true;
95
+ args.emitRouteHandlerEffectPlan = true;
96
+ enableHostCapabilities(args);
97
+ }
98
+
99
+ function enableRouteHandlerContextLowering(args) {
100
+ args.emitRouteHandlerContextLoweringPlan = true;
101
+ }
102
+
103
+ function enableRouteHandlerEffects(args) {
104
+ args.emitRouteHandlerContextLoweringPlan = true;
105
+ args.emitRouteHandlerEffectPlan = true;
106
+ args.emitEffectComposition = true;
107
+ args.emitEffectRuntime = true;
108
+ }
109
+
110
+ function enableHandlerIoLifecycle(args) {
111
+ args.emitHandlerIoLifecyclePlan = true;
112
+ enableRouteHandlerEffects(args);
113
+ }
114
+
115
+ function enableRequestJsonBody(args) {
116
+ args.emitRequestJsonBodyPlan = true;
117
+ enableJsonBody(args);
118
+ enableRouteHandlerContextLowering(args);
119
+ }
120
+
121
+
122
+ function enableSchemaDecodeResult(args) {
123
+ args.emitSchemaDecodeResultPlan = true;
124
+ enableRequestJsonBody(args);
125
+ }
126
+
127
+ function enableNodeSchemaDecodeResultProof(args) {
128
+ args.emitNodeSchemaDecodeResultProof = true;
129
+ enableSchemaDecodeResult(args);
130
+ enableRouteHandlerEffects(args);
131
+ enableCompiledHandlers(args);
132
+ }
133
+
134
+ function enableSchemaResponseCodec(args) {
135
+ args.emitSchemaResponseCodecPlan = true;
136
+ enableSchemaDecodeResult(args);
137
+ enableRouteHandlerEffects(args);
138
+ }
139
+
140
+ function enableNodeSchemaResponseCodecProof(args) {
141
+ args.emitNodeSchemaResponseCodecProof = true;
142
+ enableSchemaResponseCodec(args);
143
+ enableCompiledHandlers(args);
144
+ }
145
+
146
+ function enableBackendJsonRequestBody(args) {
147
+ args.emitBackendJsonRequestBodyPlan = true;
148
+ enableSchemaResponseCodec(args);
149
+ enableRouteHandlerEffects(args);
150
+ }
151
+
152
+ function enableNodeBackendJsonRequestBodyProof(args) {
153
+ args.emitNodeBackendJsonRequestBodyProof = true;
154
+ enableBackendJsonRequestBody(args);
155
+ }
156
+
157
+ function enableNodeRequestJsonBodyProof(args) {
158
+ args.emitNodeRequestJsonBodyProof = true;
159
+ enableRequestJsonBody(args);
160
+ enableRouteHandlerEffects(args);
161
+ enableCompiledHandlers(args);
162
+ }
163
+
164
+ function enableNodeRouteHandlerEffectProof(args) {
165
+ args.emitNodeRouteHandlerEffectProof = true;
166
+ enableRouteHandlerEffects(args);
167
+ }
168
+
169
+ function enableNodeLiveOriginRouteHandlerEffectProof(args) {
170
+ args.emitNodeLiveOriginRouteHandlerEffectProof = true;
171
+ enableRouteHandlerEffects(args);
172
+ }
173
+
174
+ function enableNodeCompiledRouteHandlerEffectBridge(args) {
175
+ args.emitNodeCompiledRouteHandlerEffectBridge = true;
176
+ enableRouteHandlerEffects(args);
177
+ enableCompiledHandlers(args);
178
+ }
179
+
180
+ function enableFastlyRouteHandlerEffectProof(args) {
181
+ args.emitFastlyRouteHandlerEffectProof = true;
182
+ enableRouteHandlerEffects(args);
183
+ }
184
+
185
+ function enableFastlyLifecycleParityProof(args) {
186
+ args.emitFastlyLifecycleParityProof = true;
187
+ enableBackendJsonRequestBody(args);
188
+ enableHandlerIoLifecycle(args);
189
+ }
190
+
191
+ function enableSchema(args) {
192
+ args.emitSchemaJsonSidecar = true;
193
+ enableJsonBody(args);
194
+ }
195
+
196
+ function enableSchemaJsonGenericParser(args) {
197
+ args.emitSchemaJsonGenericParser = true;
198
+ enableJsonBody(args);
199
+ }
200
+
201
+ function enableStreaming(args) {
202
+ args.emitStreamingPassthrough = true;
203
+ args.emitNodeAdapter = true;
204
+ args.emitHostRuntimeKernel = true;
205
+ args.emitWasmHostBridge = true;
206
+ enableHostAbi(args);
207
+ args.emitRequestResultHeaders = true;
208
+ args.emitChannelBroadcaster = true;
209
+ args.emitBackendCapabilities = true;
210
+ enableJsonBody(args);
211
+ enableAsCore(args);
212
+ }
213
+
214
+ function enableCompiledHandlers(args) {
215
+ args.emitCompiledHandlers = true;
216
+ enableRouteHandlerContextLowering(args);
217
+ enableAsCore(args);
218
+ }
219
+
220
+ function enableNodeAdapter(args) {
221
+ args.emitNodeAdapter = true;
222
+ args.emitHostRuntimeKernel = true;
223
+ args.emitWasmHostBridge = true;
224
+ enableHostAbi(args);
225
+ enableAsCore(args);
226
+ enableJsonBody(args);
227
+ args.emitBackendCapabilities = true;
228
+ args.emitChannelBroadcaster = true;
229
+ }
230
+
231
+ function enableFastlyReadiness(args) {
232
+ args.emitFastlyReadiness = true;
233
+ args.emitPulseWrapper = true;
234
+ args.emitCompiledWasmRuntime = true;
235
+ args.emitIntegratedCompiledApp = true;
236
+ enableAsCore(args);
237
+ enableSchema(args);
238
+ args.emitLibrarySidecars = true;
239
+ enableLibraries(args);
240
+ enableHostAbi(args);
241
+ enableHostCapabilities(args);
242
+ enableEffects(args);
243
+ }
244
+
245
+ function enableAssetsCompiledWasmSidecar(args) {
246
+ args.emitAssetsCompiledWasmSidecarPlan = true;
247
+ enableAssets(args);
248
+ }
249
+
250
+ function enableAssetsSidecarCompileLinkProof(args) {
251
+ args.emitAssetsSidecarCompileLinkProof = true;
252
+ enableAssetsCompiledWasmSidecar(args);
253
+ }
254
+
255
+ function enableNodeAssetsProof(args) {
256
+ args.emitNodeAssetsProviderProof = true;
257
+ enableAssets(args);
258
+ }
259
+
260
+ function enableNodeCompiledWasmAssetsLifecycleProof(args) {
261
+ args.emitNodeCompiledWasmAssetsLifecycleProof = true;
262
+ enableAssetsCompiledWasmSidecar(args);
263
+ }
264
+
265
+ function enableFastlyAssetsProof(args) {
266
+ args.emitFastlyAssetsProviderProof = true;
267
+ enableAssets(args);
268
+ }
269
+
270
+ function enableFastlyAssetsPackageOutParityProof(args) {
271
+ args.emitFastlyAssetsPackageOutParityProof = true;
272
+ enableFastlyAssetsProof(args);
273
+ enableAssetsCompiledWasmSidecar(args);
274
+ }
275
+
276
+ function enableDoctorReadiness(args) {
277
+ enableHandlerIoLifecycle(args);
278
+ enableNodeBackendJsonRequestBodyProof(args);
279
+ enableFastlyLifecycleParityProof(args);
280
+ enableAssetsSidecarCompileLinkProof(args);
281
+ enableNodeCompiledWasmAssetsLifecycleProof(args);
282
+ enableFastlyAssetsProof(args);
283
+ }
284
+
285
+
286
+ const FEATURE_ENABLERS = {
287
+ routes() {},
288
+ route() {},
289
+ ast(args) { args.includeAst = true; },
290
+ dispatch: enableDispatch,
291
+ 'dispatch-ts': enableDispatch,
292
+ handlers: enableHandlerBindings,
293
+ 'handler-bindings': enableHandlerBindings,
294
+ harness: enableExecutionHarness,
295
+ 'execution-harness': enableExecutionHarness,
296
+ libraries: enableLibraries,
297
+ library: enableLibraries,
298
+ 'library-contracts': enableLibraries,
299
+ assets: enableAssets,
300
+ 'assets-plan': enableAssets,
301
+ 'assets-compiled-wasm-sidecar': enableAssetsCompiledWasmSidecar,
302
+ 'assets-compiled-wasm-sidecar-plan': enableAssetsCompiledWasmSidecar,
303
+ 'assets-sidecar': enableAssetsCompiledWasmSidecar,
304
+ 'assets-sidecar-plan': enableAssetsCompiledWasmSidecar,
305
+ 'assets-sidecar-compile-link': enableAssetsSidecarCompileLinkProof,
306
+ 'assets-sidecar-compile-link-proof': enableAssetsSidecarCompileLinkProof,
307
+ 'assets-sidecar-link-proof': enableAssetsSidecarCompileLinkProof,
308
+ host: enableHostCapabilities,
309
+ 'host-capabilities': enableHostCapabilities,
310
+ effects: enableEffects,
311
+ effect: enableEffects,
312
+ 'effect-composition': enableEffects,
313
+ 'route-context': enableRouteHandlerContextLowering,
314
+ 'route-handler-context': enableRouteHandlerContextLowering,
315
+ 'route-handler-context-lowering': enableRouteHandlerContextLowering,
316
+ 'context-lowering': enableRouteHandlerContextLowering,
317
+ 'ctx-lowering': enableRouteHandlerContextLowering,
318
+ 'sync-context': enableRouteHandlerContextLowering,
319
+ 'route-effects': enableRouteHandlerEffects,
320
+ 'route-handler-effects': enableRouteHandlerEffects,
321
+ 'route-handler-effect-plan': enableRouteHandlerEffects,
322
+ 'ctx-resolve': enableRouteHandlerEffects,
323
+ 'fetch-effects': enableRouteHandlerEffects,
324
+ 'handler-io': enableHandlerIoLifecycle,
325
+ 'handler-io-lifecycle': enableHandlerIoLifecycle,
326
+ 'io-lifecycle': enableHandlerIoLifecycle,
327
+ 'handler-lifecycle': enableHandlerIoLifecycle,
328
+ 'lifecycle': enableHandlerIoLifecycle,
329
+ 'request-lifecycle': enableHandlerIoLifecycle,
330
+ 'request-json': enableRequestJsonBody,
331
+ 'request-json-body': enableRequestJsonBody,
332
+ 'request-json-body-plan': enableRequestJsonBody,
333
+ 'ctx-req-json': enableRequestJsonBody,
334
+ 'lazy-request-json': enableRequestJsonBody,
335
+ 'schema-decode': enableSchemaDecodeResult,
336
+ 'schema-decode-result': enableSchemaDecodeResult,
337
+ 'schema-decode-result-plan': enableSchemaDecodeResult,
338
+ 'ctx-req-json-schema': enableSchemaDecodeResult,
339
+ 'node-request-json': enableNodeRequestJsonBodyProof,
340
+ 'node-request-json-body': enableNodeRequestJsonBodyProof,
341
+ 'node-request-json-body-proof': enableNodeRequestJsonBodyProof,
342
+ 'node-ctx-req-json-proof': enableNodeRequestJsonBodyProof,
343
+ 'node-schema-decode': enableNodeSchemaDecodeResultProof,
344
+ 'node-schema-decode-result': enableNodeSchemaDecodeResultProof,
345
+ 'node-schema-decode-result-proof': enableNodeSchemaDecodeResultProof,
346
+ 'node-ctx-req-json-schema-proof': enableNodeSchemaDecodeResultProof,
347
+ 'schema-response': enableSchemaResponseCodec,
348
+ 'schema-response-codec': enableSchemaResponseCodec,
349
+ 'schema-response-codec-plan': enableSchemaResponseCodec,
350
+ 'ctx-result-json-schema': enableSchemaResponseCodec,
351
+ 'node-schema-response': enableNodeSchemaResponseCodecProof,
352
+ 'node-schema-response-codec': enableNodeSchemaResponseCodecProof,
353
+ 'node-schema-response-codec-proof': enableNodeSchemaResponseCodecProof,
354
+ 'node-ctx-result-json-schema-proof': enableNodeSchemaResponseCodecProof,
355
+ 'backend-json-request-body': enableBackendJsonRequestBody,
356
+ 'backend-json-request-body-plan': enableBackendJsonRequestBody,
357
+ 'fetch-json-body': enableBackendJsonRequestBody,
358
+ 'ctx-fetch-json': enableBackendJsonRequestBody,
359
+ 'node-backend-json-request-body': enableNodeBackendJsonRequestBodyProof,
360
+ 'node-backend-json-request-body-proof': enableNodeBackendJsonRequestBodyProof,
361
+ 'node-fetch-json-body-proof': enableNodeBackendJsonRequestBodyProof,
362
+ 'node-route-effects': enableNodeRouteHandlerEffectProof,
363
+ 'node-route-handler-effects': enableNodeRouteHandlerEffectProof,
364
+ 'node-route-handler-effect-proof': enableNodeRouteHandlerEffectProof,
365
+ 'node-ctx-resolve-proof': enableNodeRouteHandlerEffectProof,
366
+ 'node-fetch-effects': enableNodeRouteHandlerEffectProof,
367
+ 'node-live-origin-route-effects': enableNodeLiveOriginRouteHandlerEffectProof,
368
+ 'node-live-origin-route-handler-effects': enableNodeLiveOriginRouteHandlerEffectProof,
369
+ 'node-live-origin-route-handler-effect-proof': enableNodeLiveOriginRouteHandlerEffectProof,
370
+ 'node-live-origin-ctx-resolve-proof': enableNodeLiveOriginRouteHandlerEffectProof,
371
+ 'node-live-origin-fetch-effects': enableNodeLiveOriginRouteHandlerEffectProof,
372
+ 'node-compiled-route-effects': enableNodeCompiledRouteHandlerEffectBridge,
373
+ 'node-compiled-route-handler-effects': enableNodeCompiledRouteHandlerEffectBridge,
374
+ 'node-compiled-route-handler-effect-bridge': enableNodeCompiledRouteHandlerEffectBridge,
375
+ 'node-compiled-ctx-resolve-bridge': enableNodeCompiledRouteHandlerEffectBridge,
376
+ 'node-compiled-fetch-effects': enableNodeCompiledRouteHandlerEffectBridge,
377
+ 'fastly-route-effects': enableFastlyRouteHandlerEffectProof,
378
+ 'fastly-route-handler-effects': enableFastlyRouteHandlerEffectProof,
379
+ 'fastly-route-handler-effect-proof': enableFastlyRouteHandlerEffectProof,
380
+ 'fastly-ctx-resolve-proof': enableFastlyRouteHandlerEffectProof,
381
+ 'fastly-fetch-effects': enableFastlyRouteHandlerEffectProof,
382
+ 'fastly-lifecycle-parity': enableFastlyLifecycleParityProof,
383
+ 'fastly-lifecycle-parity-proof': enableFastlyLifecycleParityProof,
384
+ 'fastly-provider-lifecycle': enableFastlyLifecycleParityProof,
385
+ 'fastly-reference-lifecycle': enableFastlyLifecycleParityProof,
386
+ schema: enableSchema,
387
+ 'schema-json': enableSchema,
388
+ 'schema-json-generic-parser': enableSchemaJsonGenericParser,
389
+ 'schema-json-parser': enableSchemaJsonGenericParser,
390
+ 'schema-json-generic': enableSchemaJsonGenericParser,
391
+ 'schema-generic-parser': enableSchemaJsonGenericParser,
392
+ 'generic-json': enableSchemaJsonGenericParser,
393
+ 'generic-json-parser': enableSchemaJsonGenericParser,
394
+ 'as-json-parser': enableSchemaJsonGenericParser,
395
+ streaming: enableStreaming,
396
+ stream: enableStreaming,
397
+ 'node-adapter': enableNodeAdapter,
398
+ 'fastly-readiness': enableFastlyReadiness,
399
+ compiled: enableCompiledHandlers,
400
+ 'compiled-handlers': enableCompiledHandlers,
401
+ 'node-assets-proof': enableNodeAssetsProof,
402
+ 'node-assets-provider-proof': enableNodeAssetsProof,
403
+ 'node-compiled-wasm-assets-lifecycle': enableNodeCompiledWasmAssetsLifecycleProof,
404
+ 'node-compiled-wasm-assets-lifecycle-proof': enableNodeCompiledWasmAssetsLifecycleProof,
405
+ 'node-compiled-assets-proof': enableNodeCompiledWasmAssetsLifecycleProof,
406
+ 'node-assets-compiled-wasm': enableNodeCompiledWasmAssetsLifecycleProof,
407
+ 'fastly-assets-proof': enableFastlyAssetsProof,
408
+ 'fastly-assets-provider-proof': enableFastlyAssetsProof,
409
+ 'fastly-assets-package-out-parity': enableFastlyAssetsPackageOutParityProof,
410
+ 'fastly-assets-package-out-parity-proof': enableFastlyAssetsPackageOutParityProof,
411
+ 'fastly-assets-package-parity': enableFastlyAssetsPackageOutParityProof,
412
+ 'fastly-assets-package-proof': enableFastlyAssetsPackageOutParityProof,
413
+ 'doctor-readiness': enableDoctorReadiness,
414
+ 'readiness': enableDoctorReadiness,
415
+ 'lifecycle-readiness': enableDoctorReadiness,
416
+ 'beta-readiness': enableDoctorReadiness,
417
+ 'beta-lifecycle-readiness': enableDoctorReadiness
418
+ };
419
+
420
+ function applyFeature(args, feature) {
421
+ const normalized = normalizeFeatureName(feature);
422
+ if (!normalized) return;
423
+ if (normalized === 'none') return;
424
+ if (normalized === 'default' || normalized === 'defaults') {
425
+ const defaults = args.command === 'doctor' ? DOCTOR_DEFAULT_FEATURES : PLAN_DEFAULT_FEATURES;
426
+ applyFeatures(args, defaults);
427
+ return;
428
+ }
429
+ if (normalized === 'all') {
430
+ applyFeatures(args, ['routes', 'libraries', 'assets', 'effects', 'handler-io', 'schema', 'host']);
431
+ return;
432
+ }
433
+ const enable = FEATURE_ENABLERS[normalized];
434
+ if (!enable) {
435
+ throw new Error(`Unknown --features value "${feature}". Known features: ${knownFeatures().join(', ')}`);
436
+ }
437
+ enable(args);
438
+ }
439
+
440
+ function applyFeatures(args, features) {
441
+ for (const feature of features || []) {
442
+ applyFeature(args, feature);
443
+ }
444
+ }
445
+
446
+ function applyTargetPreset(args) {
447
+ const target = args.targetIntent ? String(args.targetIntent).toLowerCase() : undefined;
448
+ if (!target) return;
449
+ if (target === 'js' || target === 'javascript') {
450
+ enableDispatch(args);
451
+ return;
452
+ }
453
+ if (target === 'wasm' || target === 'as' || target === 'assemblyscript') {
454
+ enableAsCore(args);
455
+ enableHostAbi(args);
456
+ enableLibraries(args);
457
+ return;
458
+ }
459
+ if (target === 'wasm-smoke' || target === 'compiled-wasm') {
460
+ args.emitWasmSmoke = true;
461
+ args.emitAssemblyScriptCompile = true;
462
+ enableAsCore(args);
463
+ return;
464
+ }
465
+ if (target === 'plan' || target === 'metadata') {
466
+ applyFeatures(args, PLAN_DEFAULT_FEATURES);
467
+ return;
468
+ }
469
+ throw new Error(`Unknown --target value "${args.targetIntent}". Expected js, wasm, wasm-smoke, or plan.`);
470
+ }
471
+
472
+ function applyProviderPreset(args) {
473
+ const provider = args.providerIntent ? String(args.providerIntent).toLowerCase() : undefined;
474
+ if (!provider || provider === 'none') return;
475
+ if (provider === 'node' || provider === 'local') {
476
+ enableHostCapabilities(args);
477
+ return;
478
+ }
479
+ if (provider === 'fastly') {
480
+ enableHostCapabilities(args);
481
+ return;
482
+ }
483
+ throw new Error(`Unknown --provider value "${args.providerIntent}". Expected none, node, local, or fastly.`);
484
+ }
485
+
486
+ function applyIntentDefaults(args) {
487
+ if (args.command === 'plan') {
488
+ applyFeatures(args, PLAN_DEFAULT_FEATURES);
489
+ }
490
+ if (args.command === 'doctor') {
491
+ args.includeAst = true;
492
+ applyFeatures(args, DOCTOR_DEFAULT_FEATURES);
493
+ }
494
+ }
495
+
496
+ function applyCliIntent(args) {
497
+ if (!args || args.command === 'explain' || args.command === 'artifacts' || args.command === 'resolve-config') return args;
498
+ applyIntentDefaults(args);
499
+ applyTargetPreset(args);
500
+ applyProviderPreset(args);
501
+ applyFeatures(args, args.features || []);
502
+ return args;
503
+ }
504
+
505
+ function knownFeatures() {
506
+ return Object.keys(FEATURE_ENABLERS).filter((name) => !['route', 'library', 'effect', 'stream'].includes(name)).sort();
507
+ }
508
+
509
+ function commandSummary(args) {
510
+ return {
511
+ version: CLI_INTENT_VERSION,
512
+ command: args.command || 'build',
513
+ target: args.targetIntent,
514
+ provider: args.providerIntent,
515
+ features: args.features || [],
516
+ defaultsApplied: args.command === 'plan' ? PLAN_DEFAULT_FEATURES : args.command === 'doctor' ? DOCTOR_DEFAULT_FEATURES : []
517
+ };
518
+ }
519
+
520
+ function diagnosticCounts(diagnostics) {
521
+ const list = Array.isArray(diagnostics) ? diagnostics : [];
522
+ const counts = { total: list.length, error: 0, warning: 0, info: 0 };
523
+ for (const diag of list) {
524
+ const severity = diag.severity || 'error';
525
+ if (counts[severity] === undefined) counts[severity] = 0;
526
+ counts[severity] += 1;
527
+ }
528
+ return counts;
529
+ }
530
+
531
+
532
+ function lifecycleName(value) {
533
+ if (typeof value === 'string') return value;
534
+ if (value && typeof value.name === 'string') return value.name;
535
+ return undefined;
536
+ }
537
+
538
+ function routeLifecycleSummary(route) {
539
+ const sync = route && route.syncContext || {};
540
+ const requestBody = route && route.requestBody || {};
541
+ const effects = route && route.effects || {};
542
+ const originResponse = route && route.originResponse || {};
543
+ const finalResponse = route && route.finalResponse || {};
544
+ const schema = route && route.schema || {};
545
+ const providerExecution = effects.providerExecution || {};
546
+ return {
547
+ route: `${route.method || 'ANY'} ${route.path || '/'}`,
548
+ handler: route.handlerName,
549
+ syncCtxReads: sync.surfaces || [],
550
+ routeParamsRead: sync.paramsRead || [],
551
+ requestHeadersRead: sync.headersRead || [],
552
+ requestBodyRequirement: requestBody.required ? 'required' : 'none',
553
+ requestBodyModes: requestBody.modes || [],
554
+ schemaDecodeRequirement: (schema.requestDecode || []).length > 0,
555
+ genericJsonParserRequirement: Boolean(schema.genericParserNeeded),
556
+ backendOriginEffects: (effects.backendFetches || []).map((effect) => ({
557
+ name: effect.name || '$default',
558
+ backend: effect.backend,
559
+ method: effect.method || effect.request?.method,
560
+ path: effect.path || effect.request?.path,
561
+ bodyMode: effect.bodyMode || effect.requestBody?.mode || 'none'
562
+ })),
563
+ continuationHandler: (effects.resolveBoundaries || []).map((resolve) => lifecycleName(resolve.continuation)).filter(Boolean)[0],
564
+ resolvedResponseReads: originResponse.reads || [],
565
+ resolvedResponseModes: originResponse.modes || [],
566
+ finalResponseEncoding: finalResponse.encodes || [],
567
+ finalResponseModes: finalResponse.modes || [],
568
+ reservedPayloadModes: route.reserved || {},
569
+ providerReadiness: {
570
+ node: providerExecution.nodeProofAvailable ? 'proof-available' : (effects.required ? 'planned' : 'not-required'),
571
+ fastly: providerExecution.fastlyProofAvailable ? 'proof-available' : (effects.required ? 'planned' : 'not-required')
572
+ },
573
+ compiledWasmReadiness: providerExecution.compiledWasmSuspendResumeBridgeImplemented ? 'ready' : (effects.required ? 'planned' : 'not-required'),
574
+ diagnostics: route.diagnostics || []
575
+ };
576
+ }
577
+
578
+
579
+ function assetsDoctorSummary(result) {
580
+ const plan = result && result.assetsLoweringPlan && result.assetsLoweringPlan.artifact;
581
+ if (!plan) return undefined;
582
+ const compilerBuilder = plan.policy && plan.policy.compilerBuilder || {};
583
+ const sidecarCompileLinked = Boolean(result.assetsSidecarCompileLinkProof && result.assetsSidecarCompileLinkProof.artifact && result.assetsSidecarCompileLinkProof.artifact.summary && result.assetsSidecarCompileLinkProof.artifact.summary.linkedModuleExecuted === true);
584
+ const nodeCompiledReady = Boolean(result.nodeCompiledWasmAssetsLifecycleProof && result.nodeCompiledWasmAssetsLifecycleProof.artifact && result.nodeCompiledWasmAssetsLifecycleProof.artifact.compiledWasmRuntimeBehaviorImplemented === true);
585
+ const fastlyParity = result.fastlyAssetsPackageOutParityProof && result.fastlyAssetsPackageOutParityProof.artifact;
586
+ const fastlyCompiledReadiness = fastlyParity && fastlyParity.compiledWasmAssetsReadiness ? fastlyParity.compiledWasmAssetsReadiness : 'plan-only';
587
+ let compiledWasmReadiness = 'not-ready-until-assets-compiled-wasm-sidecar-lifecycle';
588
+ if (nodeCompiledReady && fastlyCompiledReadiness === 'plan-only') compiledWasmReadiness = 'node-ready-fastly-plan-only';
589
+ else if (nodeCompiledReady) compiledWasmReadiness = 'node-ready-fastly-classified-on-request';
590
+ else if (result.assetsCompiledWasmSidecarPlan) compiledWasmReadiness = 'sidecar-ready-provider-lifecycle-next';
591
+ return {
592
+ version: 'pulsewasm.doctor-assets-package.v1',
593
+ sourceArtifact: 'assets-lowering-plan.json',
594
+ status: plan.status || 'unknown',
595
+ package: plan.npmPackage,
596
+ lowerableSubpath: plan.lowerableSubpath,
597
+ compilerBuilder: {
598
+ owner: plan.policy && plan.policy.builderOwner,
599
+ entry: compilerBuilder.entry,
600
+ export: compilerBuilder.export,
601
+ trust: compilerBuilder.trust
602
+ },
603
+ packageIdentityOwnedByManifest: Boolean(plan.policy && plan.policy.packageIdentityOwnedByManifest),
604
+ compilerOwnsPackageMapping: Boolean(plan.policy && plan.policy.compilerOwnsPackageMapping),
605
+ summary: plan.summary || {},
606
+ authoringAlignment: plan.authoringAlignment || {
607
+ routeMethodConsistency: true,
608
+ entriesChecked: 0,
609
+ mismatches: 0
610
+ },
611
+ providerReadiness: {
612
+ node: result.nodeAssetsProviderProof ? 'proof-available' : 'provider-proof-available-on-request',
613
+ fastly: result.fastlyAssetsProviderProof ? 'proof-available' : 'provider-proof-available-on-request',
614
+ nodeCompiledWasm: nodeCompiledReady ? 'ready-narrow-terminal-get-head-text' : (result.assetsCompiledWasmSidecarPlan ? 'sidecar-ready-provider-lifecycle-next' : 'not-ready'),
615
+ fastlyCompiledWasm: fastlyCompiledReadiness,
616
+ streamCompiledWasm: 'plan-only',
617
+ binary: 'reserved'
618
+ },
619
+ compiledWasmReadiness,
620
+ providerCompiledWasmReadiness: {
621
+ node: nodeCompiledReady ? 'implemented-narrow' : (result.assetsCompiledWasmSidecarPlan ? 'sidecar-ready-provider-lifecycle-next' : 'not-ready'),
622
+ fastly: fastlyCompiledReadiness,
623
+ stream: 'plan-only',
624
+ binary: 'reserved'
625
+ },
626
+ compiledWasmSidecarPlan: result.assetsCompiledWasmSidecarPlan ? {
627
+ sourceArtifact: 'assets-compiled-wasm-sidecar-plan.json',
628
+ summary: result.assetsCompiledWasmSidecarPlan.artifact.summary
629
+ } : undefined,
630
+ sidecarCompileLinkProof: result.assetsSidecarCompileLinkProof ? {
631
+ sourceArtifact: 'assets-sidecar-compile-link-proof.json',
632
+ summary: result.assetsSidecarCompileLinkProof.artifact.summary,
633
+ linkedModuleExecuted: sidecarCompileLinked
634
+ } : undefined,
635
+ fastlyPackageOutParity: fastlyParity ? {
636
+ sourceArtifact: 'fastly-assets-package-out-parity-proof.json',
637
+ compiledWasmAssetsReadiness: fastlyParity.compiledWasmAssetsReadiness,
638
+ diagnostic: fastlyParity.compiledWasmPlanOnlyDiagnostic
639
+ } : undefined
640
+ };
641
+ }
642
+
643
+ function lifecycleDoctorSummary(result) {
644
+ const lifecycle = result && result.handlerIoLifecyclePlan && result.handlerIoLifecyclePlan.artifact;
645
+ if (!lifecycle || !Array.isArray(lifecycle.routes)) return undefined;
646
+ return {
647
+ version: 'pulsewasm.doctor-handler-io-lifecycle.v1',
648
+ sourceArtifact: lifecycle.artifact || 'handler-io-lifecycle-plan.json',
649
+ status: lifecycle.status || 'unknown',
650
+ summary: lifecycle.summary || {},
651
+ lazyEvaluation: lifecycle.lazyEvaluation || {},
652
+ routes: lifecycle.routes.map(routeLifecycleSummary)
653
+ };
654
+ }
655
+
656
+
657
+ function asArray(value) {
658
+ return Array.isArray(value) ? value : [];
659
+ }
660
+
661
+ function artifactPresent(result, key) {
662
+ return Boolean(result && result[key] && result[key].artifact && (result[key].artifact.status || 'ok') === 'ok');
663
+ }
664
+
665
+ function asArray(value) {
666
+ return Array.isArray(value) ? value : [];
667
+ }
668
+
669
+ function assetEntriesByRoute(result) {
670
+ const out = new Map();
671
+ const plan = result && result.assetsLoweringPlan && result.assetsLoweringPlan.artifact;
672
+ const entries = Array.isArray(plan && plan.entries) ? plan.entries : [];
673
+ for (const entry of entries) {
674
+ const routes = entry && entry.routeAlignment && Array.isArray(entry.routeAlignment.routes) ? entry.routeAlignment.routes : [];
675
+ for (const route of routes) {
676
+ const key = route.route || `${String(route.method || entry.lookup?.method || 'GET').toUpperCase()} ${route.path || entry.lookup?.key || '/'}`;
677
+ if (!out.has(key)) out.set(key, []);
678
+ out.get(key).push(entry);
679
+ }
680
+ }
681
+ return out;
682
+ }
683
+
684
+ function providerProofSources(result) {
685
+ return {
686
+ handlerIoLifecyclePlan: artifactPresent(result, 'handlerIoLifecyclePlan'),
687
+ nodeRouteHandlerEffectProof: artifactPresent(result, 'nodeRouteHandlerEffectProof'),
688
+ nodeLiveOriginRouteHandlerEffectProof: artifactPresent(result, 'nodeLiveOriginRouteHandlerEffectProof'),
689
+ nodeCompiledRouteHandlerEffectBridge: artifactPresent(result, 'nodeCompiledRouteHandlerEffectBridge'),
690
+ nodeBackendJsonRequestBodyProof: artifactPresent(result, 'nodeBackendJsonRequestBodyProof'),
691
+ fastlyLifecycleParityProof: artifactPresent(result, 'fastlyLifecycleParityProof'),
692
+ assetsLoweringPlan: artifactPresent(result, 'assetsLoweringPlan'),
693
+ assetsCompiledWasmSidecarPlan: artifactPresent(result, 'assetsCompiledWasmSidecarPlan'),
694
+ assetsSidecarCompileLinkProof: artifactPresent(result, 'assetsSidecarCompileLinkProof'),
695
+ nodeCompiledWasmAssetsLifecycleProof: artifactPresent(result, 'nodeCompiledWasmAssetsLifecycleProof'),
696
+ fastlyAssetsPackageOutParityProof: artifactPresent(result, 'fastlyAssetsPackageOutParityProof')
697
+ };
698
+ }
699
+
700
+ function sourceArtifactNames(sources) {
701
+ const names = {
702
+ handlerIoLifecyclePlan: 'handler-io-lifecycle-plan.json',
703
+ nodeRouteHandlerEffectProof: 'node-route-handler-effect-proof.json',
704
+ nodeLiveOriginRouteHandlerEffectProof: 'node-live-origin-route-handler-effect-proof.json',
705
+ nodeCompiledRouteHandlerEffectBridge: 'node-compiled-route-handler-effect-bridge.json',
706
+ nodeBackendJsonRequestBodyProof: 'node-backend-json-request-body-proof.json',
707
+ fastlyLifecycleParityProof: 'fastly-lifecycle-parity-proof.json',
708
+ assetsLoweringPlan: 'assets-lowering-plan.json',
709
+ assetsCompiledWasmSidecarPlan: 'assets-compiled-wasm-sidecar-plan.json',
710
+ assetsSidecarCompileLinkProof: 'assets-sidecar-compile-link-proof.json',
711
+ nodeCompiledWasmAssetsLifecycleProof: 'node-compiled-wasm-assets-lifecycle-proof.json',
712
+ fastlyAssetsPackageOutParityProof: 'fastly-assets-package-out-parity-proof.json'
713
+ };
714
+ return Object.entries(sources).filter(([, present]) => present).map(([key]) => names[key] || key);
715
+ }
716
+
717
+ function routeReadinessForDoctor(route, assetEntries, sources) {
718
+ const backendEffects = asArray(route.backendOriginEffects);
719
+ const hasBackendEffects = backendEffects.length > 0;
720
+ const hasPostJsonBackend = backendEffects.some((effect) => String(effect.method || '').toUpperCase() === 'POST' && effect.bodyMode === 'json');
721
+ const hasAssetEffects = assetEntries.length > 0;
722
+ const effectKinds = [];
723
+ if (hasBackendEffects) effectKinds.push('backend-origin-fetch');
724
+ if (hasPostJsonBackend) effectKinds.push('backend-json-request-body');
725
+ if (hasAssetEffects) effectKinds.push('assets-terminal-response');
726
+ if (effectKinds.length === 0) effectKinds.push('sync-result');
727
+
728
+ const diagnostics = [];
729
+ if (hasPostJsonBackend) diagnostics.push('PULSEWASM_FASTLY_POST_JSON_BODY_PLAN_ONLY');
730
+ if (hasAssetEffects) diagnostics.push('PULSEWASM_FASTLY_ASSETS_COMPILED_WASM_PLAN_ONLY');
731
+
732
+ const node = {
733
+ routeHandlerEffects: 'not-required',
734
+ liveOrigin: 'not-required',
735
+ compiledWasm: 'not-required',
736
+ assetsCompiledWasm: 'not-required',
737
+ backendJsonRequestBodies: 'not-required',
738
+ requestJsonDecode: route.requestBodyRequirement === 'required' ? 'implemented-lazy' : 'not-required'
739
+ };
740
+ const fastly = {
741
+ routeHandlerEffects: 'not-required',
742
+ compiledWasm: 'not-required',
743
+ assetsCompiledWasm: 'not-required',
744
+ backendJsonRequestBodies: 'not-required'
745
+ };
746
+
747
+ if (hasBackendEffects) {
748
+ node.routeHandlerEffects = sources.nodeLiveOriginRouteHandlerEffectProof ? 'implemented-live-origin-proof' : (sources.nodeRouteHandlerEffectProof ? 'provider-proof' : 'planned');
749
+ node.liveOrigin = sources.nodeLiveOriginRouteHandlerEffectProof ? 'implemented' : 'proof-available-on-request';
750
+ node.compiledWasm = sources.nodeCompiledRouteHandlerEffectBridge ? 'implemented-resolve-resume-bridge' : 'available-via-reference-golden-split-proof';
751
+ fastly.routeHandlerEffects = sources.fastlyLifecycleParityProof ? 'symbolic-parity' : 'symbolic-parity-available-on-request';
752
+ fastly.compiledWasm = 'symbolic-parity-or-plan-only';
753
+ }
754
+ if (hasPostJsonBackend) {
755
+ node.backendJsonRequestBodies = sources.nodeBackendJsonRequestBodyProof ? 'implemented-node-proof' : 'implemented-in-reference-golden-split-proof';
756
+ fastly.backendJsonRequestBodies = 'plan-only';
757
+ }
758
+ if (hasAssetEffects) {
759
+ node.assetsCompiledWasm = sources.nodeCompiledWasmAssetsLifecycleProof ? 'implemented-narrow-terminal-get-head-text' : (sources.assetsCompiledWasmSidecarPlan ? 'sidecar-ready-provider-lifecycle-next' : 'planned');
760
+ node.compiledWasm = node.assetsCompiledWasm;
761
+ fastly.assetsCompiledWasm = 'plan-only';
762
+ fastly.compiledWasm = 'plan-only';
763
+ }
764
+ if (!hasBackendEffects && !hasAssetEffects) {
765
+ node.routeHandlerEffects = 'ready-no-host-effects';
766
+ node.compiledWasm = 'ready-no-host-effects';
767
+ fastly.routeHandlerEffects = 'ready-no-host-effects';
768
+ fastly.compiledWasm = 'ready-no-host-effects';
769
+ }
770
+
771
+ const readiness = hasAssetEffects
772
+ ? 'node-ready-fastly-plan-only'
773
+ : (hasBackendEffects ? 'node-ready-fastly-symbolic-or-plan-only' : 'ready-no-host-effects');
774
+
775
+ return {
776
+ route: route.route,
777
+ handler: route.handler,
778
+ lifecycleKind: hasAssetEffects ? 'terminal-package-effect' : (hasBackendEffects ? 'backend-origin-continuation' : 'sync-result'),
779
+ readiness,
780
+ effectKinds,
781
+ lifecycle: {
782
+ syncCtxReads: route.syncCtxReads || [],
783
+ requestBody: route.requestBodyRequirement,
784
+ schemaDecode: route.schemaDecodeRequirement ? 'required' : 'not-required',
785
+ genericJsonParser: route.genericJsonParserRequirement ? 'explicitly-configured' : 'not-required',
786
+ backendEffects,
787
+ assetEffects: assetEntries.map((entry) => ({
788
+ id: entry.id,
789
+ store: entry.lookup && entry.lookup.store,
790
+ key: entry.lookup && entry.lookup.key,
791
+ method: entry.lookup && entry.lookup.method,
792
+ payloadMode: entry.lookup && entry.lookup.payloadMode,
793
+ routeAlignment: entry.routeAlignment && entry.routeAlignment.status
794
+ })),
795
+ continuation: route.continuationHandler || null,
796
+ finalResponseModes: route.finalResponseModes || []
797
+ },
798
+ node: {
799
+ ...node,
800
+ compiledWasmResolveResume: hasBackendEffects ? (sources.nodeCompiledRouteHandlerEffectBridge ? 'implemented' : 'implemented-in-reference-golden-split-proof') : 'not-required',
801
+ backendJsonRequestBodies: hasPostJsonBackend ? node.backendJsonRequestBodies : node.backendJsonRequestBodies
802
+ },
803
+ fastly: {
804
+ ...fastly,
805
+ postJsonRequestBodies: hasPostJsonBackend ? fastly.backendJsonRequestBodies : 'not-required'
806
+ },
807
+ backendReadiness: hasBackendEffects ? {
808
+ node: node.routeHandlerEffects,
809
+ nodePostJson: hasPostJsonBackend ? node.backendJsonRequestBodies : 'not-required',
810
+ fastly: fastly.routeHandlerEffects,
811
+ fastlyPostJson: hasPostJsonBackend ? fastly.backendJsonRequestBodies : 'not-required',
812
+ compiledWasm: node.compiledWasm
813
+ } : undefined,
814
+ assetsReadiness: hasAssetEffects ? {
815
+ entries: assetEntries.map((entry) => ({
816
+ id: entry.id,
817
+ store: entry.lookup && entry.lookup.store,
818
+ key: entry.lookup && entry.lookup.key,
819
+ method: entry.lookup && entry.lookup.method,
820
+ payloadMode: entry.lookup && entry.lookup.payloadMode,
821
+ routeAlignment: entry.routeAlignment && entry.routeAlignment.status
822
+ })),
823
+ node: node.assetsCompiledWasm,
824
+ fastly: fastly.assetsCompiledWasm,
825
+ streamCompiledWasm: 'plan-only',
826
+ binary: 'reserved'
827
+ } : undefined,
828
+ readiness: hasAssetEffects ? (node.assetsCompiledWasm === 'implemented-narrow-terminal-get-head-text' ? 'node-ready-fastly-plan-only' : 'sidecar-ready') : (hasBackendEffects ? 'split-proof-ready' : 'ready-sync'),
829
+ diagnostics: Array.from(new Set([...(route.diagnostics || []), ...diagnostics]))
830
+ };
831
+ }
832
+
833
+ function packageReadinessForDoctor(assetsPackage, sources) {
834
+ if (!assetsPackage) return [];
835
+ return [{
836
+ package: assetsPackage.package,
837
+ lowerableSubpath: assetsPackage.lowerableSubpath,
838
+ compilerBuilderOwner: assetsPackage.compilerBuilder && assetsPackage.compilerBuilder.owner,
839
+ lowerer: {
840
+ packageOwned: assetsPackage.compilerOwnsPackageMapping === false && assetsPackage.packageIdentityOwnedByManifest === true,
841
+ builderOwner: assetsPackage.compilerBuilder && assetsPackage.compilerBuilder.owner,
842
+ packageOutDiscovery: 'validated-by-assets-package-out-proof'
843
+ },
844
+ packageOwnedLowering: assetsPackage.compilerOwnsPackageMapping === false && assetsPackage.packageIdentityOwnedByManifest === true,
845
+ packageOutDiscovery: 'validated-by-assets-package-out-proof',
846
+ authoringAlignment: assetsPackage.authoringAlignment,
847
+ node: {
848
+ providerProof: sources.nodeCompiledWasmAssetsLifecycleProof ? 'implemented-narrow-terminal-get-head-text' : 'available-on-request',
849
+ compiledWasm: sources.nodeCompiledWasmAssetsLifecycleProof ? 'implemented-narrow-terminal-get-head-text' : (assetsPackage.providerCompiledWasmReadiness && assetsPackage.providerCompiledWasmReadiness.node || 'not-ready')
850
+ },
851
+ fastly: {
852
+ providerProof: 'symbolic-provider-proof',
853
+ compiledWasm: assetsPackage.providerCompiledWasmReadiness && assetsPackage.providerCompiledWasmReadiness.fastly || 'plan-only'
854
+ },
855
+ streamCompiledWasm: assetsPackage.providerCompiledWasmReadiness && assetsPackage.providerCompiledWasmReadiness.stream || 'plan-only',
856
+ binary: assetsPackage.providerCompiledWasmReadiness && assetsPackage.providerCompiledWasmReadiness.binary || 'reserved'
857
+ }];
858
+ }
859
+
860
+ function buildDoctorReadiness({ result, lifecycle, assetsPackage, diagnostics }) {
861
+ const sources = providerProofSources(result);
862
+ const sidecarCompileLinkReadiness = result && result.assetsSidecarCompileLinkProof && result.assetsSidecarCompileLinkProof.artifact && result.assetsSidecarCompileLinkProof.artifact.summary
863
+ ? (result.assetsSidecarCompileLinkProof.artifact.summary.actualAssemblyScriptCompileReadiness || (result.assetsSidecarCompileLinkProof.artifact.summary.linkedModuleExecuted ? 'link-proof-validated' : 'future-proof'))
864
+ : 'future-proof';
865
+ const assetRouteMap = assetEntriesByRoute(result);
866
+ const routes = asArray(lifecycle && lifecycle.routes).map((route) => routeReadinessForDoctor(route, assetRouteMap.get(route.route) || [], sources));
867
+ const backendRoutes = routes.filter((route) => route.effectKinds.includes('backend-origin-fetch'));
868
+ const assetRoutes = routes.filter((route) => route.effectKinds.includes('assets-terminal-response'));
869
+ const planOnly = [];
870
+ if (!sources.nodeCompiledRouteHandlerEffectBridge) planOnly.push({ surface: 'combined beta app unified compiled route bridge', status: 'split-proof-required', reason: 'backend compiled bridge and assets terminal effect proofs are validated separately today' });
871
+ planOnly.push({ surface: 'Fastly backend POST JSON request bodies', status: 'plan-only', diagnostic: 'PULSEWASM_FASTLY_POST_JSON_BODY_PLAN_ONLY' });
872
+ planOnly.push({ surface: 'Fastly compiled-Wasm assets', status: 'plan-only', diagnostic: 'PULSEWASM_FASTLY_ASSETS_COMPILED_WASM_PLAN_ONLY' });
873
+ planOnly.push({ surface: 'compiled-Wasm stream asset bodies', status: 'plan-only' });
874
+ const reserved = [
875
+ 'binary bodies',
876
+ 'multipart',
877
+ 'uploads',
878
+ 'async/await',
879
+ 'Promise lowering',
880
+ 'dynamic backend names',
881
+ 'dynamic asset keys',
882
+ 'arbitrary object lowering',
883
+ 'automatic schema generation'
884
+ ];
885
+ const list = diagnostics?.diagnostics || diagnostics || [];
886
+ const hasErrors = Array.isArray(list) && list.some((diag) => (diag.severity || 'error') === 'error');
887
+ const nodeReadyRoutes = routes.filter((route) => {
888
+ const needsBackend = route.effectKinds.includes('backend-origin-fetch');
889
+ const needsAsset = route.effectKinds.includes('assets-terminal-response');
890
+ const backendReady = !needsBackend || route.node.routeHandlerEffects === 'implemented-live-origin-proof' || route.node.routeHandlerEffects === 'provider-proof' || route.node.routeHandlerEffects === 'planned' || route.node.routeHandlerEffects === 'ready-no-host-effects';
891
+ const assetReady = !needsAsset || route.node.assetsCompiledWasm === 'implemented-narrow-terminal-get-head-text';
892
+ return backendReady && assetReady;
893
+ }).length;
894
+
895
+ return {
896
+ version: DOCTOR_READINESS_AGGREGATOR_VERSION,
897
+ status: hasErrors ? 'error' : 'ok',
898
+ source: 'cli-doctor-current-command',
899
+ sourceArtifacts: sourceArtifactNames(sources),
900
+ routeCount: routes.length,
901
+ routes,
902
+ packages: packageReadinessForDoctor(assetsPackage, sources),
903
+ providers: {
904
+ node: {
905
+ backendLifecycle: sources.nodeCompiledRouteHandlerEffectBridge ? 'implemented-compiled-wasm-resolve-resume' : (sources.nodeLiveOriginRouteHandlerEffectProof ? 'implemented-live-origin-proof' : 'implemented-in-reference-golden-split-proof'),
906
+ backendJsonRequestBodies: sources.nodeBackendJsonRequestBodyProof ? 'implemented' : 'implemented-in-reference-golden-split-proof',
907
+ assetsCompiledWasm: sources.nodeCompiledWasmAssetsLifecycleProof ? 'implemented-narrow-terminal-get-head-text' : (sources.assetsCompiledWasmSidecarPlan ? 'sidecar-ready-provider-lifecycle-next' : 'planned'),
908
+ readyRoutes: nodeReadyRoutes
909
+ },
910
+ fastly: {
911
+ backendLifecycle: sources.fastlyLifecycleParityProof ? 'symbolic-parity' : 'symbolic-parity-available-on-request',
912
+ postJsonRequestBodies: 'plan-only',
913
+ assetsCompiledWasm: 'plan-only',
914
+ externalServiceRequired: false,
915
+ classifiedRoutes: routes.filter((route) => route.fastly.compiledWasm !== undefined).length
916
+ }
917
+ },
918
+ providerSummary: undefined,
919
+ authoringSubset: {
920
+ asyncAwait: false,
921
+ promises: false,
922
+ dynamicBackends: false,
923
+ dynamicAssetKeys: false,
924
+ arbitraryObjectLowering: false,
925
+ binaryBodies: false,
926
+ streamBodies: false,
927
+ multipart: false,
928
+ uploads: false
929
+ },
930
+ unsupportedEdges: {
931
+ asyncAwait: false,
932
+ promises: false,
933
+ dynamicBackends: false,
934
+ dynamicAssetKeys: false,
935
+ arbitraryObjectLowering: false,
936
+ automaticSchemaGeneration: false,
937
+ binaryBodies: false,
938
+ streamBodies: false,
939
+ multipart: false,
940
+ uploads: false
941
+ },
942
+ knownBreaks: {
943
+ combinedAppCompiledRouteBridge: 'split-proof-required-assets-handlers-not-yet-in-pass38-compiled-handler-lowerer',
944
+ realAssemblyScriptAssetsSidecarCompileLink: sidecarCompileLinkReadiness,
945
+ fastlyPostJsonRequestBodies: 'plan-only',
946
+ fastlyCompiledWasmAssets: 'plan-only'
947
+ },
948
+ unsupportedModes: {
949
+ binaryBodies: 'reserved',
950
+ streamCompiledWasm: 'plan-only',
951
+ dynamicAssetKeys: 'diagnostic',
952
+ dynamicBackends: 'diagnostic',
953
+ arbitraryObjectLowering: 'diagnostic-or-reserved'
954
+ },
955
+ planOnly,
956
+ planOnlySurfaces: planOnly,
957
+ reserved,
958
+ diagnostics: {
959
+ fastlyPlanOnly: ['PULSEWASM_FASTLY_POST_JSON_BODY_PLAN_ONLY', 'PULSEWASM_FASTLY_ASSETS_COMPILED_WASM_PLAN_ONLY'],
960
+ errors: hasErrors ? 1 : 0
961
+ },
962
+ actionableNextSteps: [
963
+ 'Use route rows to see which provider path is implemented, symbolic, or plan-only.',
964
+ 'Use package rows to see package-owned lowerer and provider compiled-Wasm readiness.',
965
+ 'Use diagnostics and unsupportedEdges before widening the lowerable authoring subset.'
966
+ ],
967
+ summary: {
968
+ routes: routes.length,
969
+ backendRoutes: backendRoutes.length,
970
+ assetRoutes: assetRoutes.length,
971
+ packages: assetsPackage ? 1 : 0,
972
+ packageReadinessEntries: assetsPackage ? 1 : 0,
973
+ nodeImplementedRoutes: nodeReadyRoutes,
974
+ splitProofRequired: !sources.nodeCompiledRouteHandlerEffectBridge,
975
+ nodeBackendLifecycleClassified: true,
976
+ nodeAssetsCompiledWasmClassified: true,
977
+ fastlyLifecycleClassified: true,
978
+ fastlyPlanOnlySurfacesClassified: true,
979
+ unsupportedModesClassified: true,
980
+ routeReadinessAggregated: true,
981
+ packageReadinessAggregated: true,
982
+ providerReadinessAggregated: true,
983
+ assetsSidecarCompileLinkAggregated: sources.assetsSidecarCompileLinkProof === true,
984
+ doctorReadinessAggregator: true,
985
+ productionCompletenessRequired: false,
986
+ errors: hasErrors ? 1 : 0
987
+ }
988
+ };
989
+ }
990
+
991
+ function createDoctorArtifact({ args, diagnostics, result, resolvedConfig }) {
992
+ const list = diagnostics?.diagnostics || [];
993
+ const counts = diagnostics?.counts || diagnosticCounts(list);
994
+ const lifecycle = lifecycleDoctorSummary(result);
995
+ const assetsPackage = assetsDoctorSummary(result);
996
+ const readiness = buildDoctorReadiness({ result, lifecycle, assetsPackage, diagnostics });
997
+ const checks = [
998
+ {
999
+ name: 'config',
1000
+ status: resolvedConfig || !args.config ? 'ok' : 'skipped',
1001
+ summary: resolvedConfig ? {
1002
+ profile: resolvedConfig.profile || resolvedConfig.selectedProfile,
1003
+ entry: resolvedConfig.entry,
1004
+ rootRouter: resolvedConfig.rootRouter,
1005
+ target: resolvedConfig.target
1006
+ } : { reason: 'no config supplied' }
1007
+ },
1008
+ {
1009
+ name: 'entry',
1010
+ status: result ? 'ok' : 'error',
1011
+ summary: result ? { entry: result.summary?.entry, rootRouter: result.summary?.rootRouter } : { entry: args.entry }
1012
+ },
1013
+ {
1014
+ name: 'route-extraction',
1015
+ status: result ? 'ok' : 'error',
1016
+ summary: result ? {
1017
+ routes: result.routePlan?.routes?.length || 0,
1018
+ handlers: result.handlerTable?.handlers?.length || 0
1019
+ } : undefined
1020
+ },
1021
+ {
1022
+ name: 'diagnostics',
1023
+ status: counts.error > 0 ? 'error' : 'ok',
1024
+ summary: counts
1025
+ },
1026
+ {
1027
+ name: 'handler-io-lifecycle',
1028
+ status: lifecycle ? (lifecycle.status === 'ok' ? 'ok' : 'error') : 'skipped',
1029
+ summary: lifecycle ? lifecycle.summary : { reason: 'handler-io lifecycle plan not emitted' }
1030
+ },
1031
+ {
1032
+ name: 'assets-package',
1033
+ status: assetsPackage ? (assetsPackage.status === 'ok' ? 'ok' : 'error') : 'skipped',
1034
+ summary: assetsPackage ? {
1035
+ package: assetsPackage.package,
1036
+ lowerableSubpath: assetsPackage.lowerableSubpath,
1037
+ compilerBuilder: assetsPackage.compilerBuilder,
1038
+ entries: assetsPackage.summary.entries || 0,
1039
+ authoringAlignment: assetsPackage.authoringAlignment,
1040
+ compilerOwnsPackageMapping: assetsPackage.compilerOwnsPackageMapping,
1041
+ compiledWasmReadiness: assetsPackage.compiledWasmReadiness,
1042
+ providerCompiledWasmReadiness: assetsPackage.providerCompiledWasmReadiness
1043
+ } : { reason: 'assets lowering plan not emitted' }
1044
+ },
1045
+ {
1046
+ name: 'doctor-readiness',
1047
+ status: readiness.status === 'ok' ? 'ok' : 'error',
1048
+ summary: readiness.summary
1049
+ },
1050
+ {
1051
+ name: 'readiness-aggregation',
1052
+ status: readiness.status === 'ok' ? 'ok' : 'error',
1053
+ summary: readiness.summary
1054
+ },
1055
+ {
1056
+ name: 'artifact-surface',
1057
+ status: 'ok',
1058
+ summary: commandSummary(args)
1059
+ }
1060
+ ];
1061
+ return {
1062
+ version: CLI_DOCTOR_VERSION,
1063
+ status: counts.error > 0 ? 'error' : 'ok',
1064
+ command: 'doctor',
1065
+ intent: commandSummary(args),
1066
+ checks,
1067
+ lifecycle,
1068
+ assetsPackage,
1069
+ readiness,
1070
+ diagnostics: list.map((diag) => ({
1071
+ code: diag.code,
1072
+ severity: diag.severity || 'error',
1073
+ message: diag.message,
1074
+ hint: diag.hint,
1075
+ loc: diag.loc
1076
+ }))
1077
+ };
1078
+ }
1079
+
1080
+ function groupDiagnostics(envelope) {
1081
+ const diagnostics = Array.isArray(envelope?.diagnostics) ? envelope.diagnostics : [];
1082
+ const groupsByKey = new Map();
1083
+ for (const diag of diagnostics) {
1084
+ const key = `${diag.severity || 'error'}:${diag.code || 'PULSEWASM_DIAGNOSTIC'}`;
1085
+ if (!groupsByKey.has(key)) {
1086
+ groupsByKey.set(key, {
1087
+ severity: diag.severity || 'error',
1088
+ code: diag.code || 'PULSEWASM_DIAGNOSTIC',
1089
+ count: 0,
1090
+ messages: []
1091
+ });
1092
+ }
1093
+ const group = groupsByKey.get(key);
1094
+ group.count += 1;
1095
+ const message = diag.message || '';
1096
+ if (message && !group.messages.includes(message)) group.messages.push(message);
1097
+ }
1098
+ return Array.from(groupsByKey.values()).sort((a, b) => {
1099
+ const severityRank = { error: 0, warning: 1, info: 2 };
1100
+ const ar = severityRank[a.severity] ?? 9;
1101
+ const br = severityRank[b.severity] ?? 9;
1102
+ if (ar !== br) return ar - br;
1103
+ return a.code.localeCompare(b.code);
1104
+ });
1105
+ }
1106
+
1107
+ function createExplainArtifact(envelope, source) {
1108
+ const groups = groupDiagnostics(envelope);
1109
+ return {
1110
+ version: CLI_EXPLAIN_VERSION,
1111
+ status: envelope?.status || (groups.some((group) => group.severity === 'error') ? 'error' : 'ok'),
1112
+ source,
1113
+ counts: envelope?.counts || diagnosticCounts(envelope?.diagnostics || []),
1114
+ groups
1115
+ };
1116
+ }
1117
+
1118
+ function producerForArtifact(fileName) {
1119
+ const file = String(fileName || '');
1120
+ if (file === 'build-manifest.json' || file === 'diagnostics.json' || file === 'resolved-config.json' || file === 'cli-doctor.json') return '@pulse-compute/wasm-compiler/cli';
1121
+ if (file.includes('reference-lifecycle-stabilization-proof')) return '@pulse-compute/wasm-workspace';
1122
+ if (file.includes('doctor-readiness-aggregator')) return '@pulse-compute/wasm-workspace';
1123
+ if (file.includes('lifecycle-readiness-aggregate')) return '@pulse-compute/wasm-workspace';
1124
+ if (file.includes('lifecycle-authoring-alignment')) return '@pulse-compute/wasm-workspace';
1125
+ if (file.includes('beta-lifecycle-golden')) return '@pulse-compute/wasm-workspace';
1126
+ if (file.includes('handler-io-lifecycle-plan')) return '@pulse-compute/wasm-runtime-core-as';
1127
+ if (file.includes('backend-json-request-body-plan')) return '@pulse-compute/wasm-runtime-core-as';
1128
+ if (file.includes('node-backend-json-request-body-proof')) return '@pulse-compute/provider-node';
1129
+ if (file.includes('schema-response-codec-plan')) return '@pulse-compute/wasm-runtime-core-as';
1130
+ if (file.includes('schema-decode-result-plan')) return '@pulse-compute/wasm-runtime-core-as';
1131
+ if (file.includes('request-json-body-plan')) return '@pulse-compute/wasm-runtime-core-as';
1132
+ if (file.includes('node-schema-response-codec-proof')) return '@pulse-compute/provider-node';
1133
+ if (file.includes('node-schema-decode-result-proof')) return '@pulse-compute/provider-node';
1134
+ if (file.includes('node-request-json-body-proof')) return '@pulse-compute/provider-node';
1135
+ if (file.includes('fastly-assets-package-out-parity-proof')) return '@pulse-compute/provider-fastly';
1136
+ if (file.includes('assets-compiled-wasm-sidecar-plan')) return '@pulse-compute/assets';
1137
+ if (file.includes('assets-package-out-discovery-proof')) return '@pulse-compute/assets';
1138
+ if (file.includes('assets-package-owned-lowering-proof')) return '@pulse-compute/assets';
1139
+ if (file.includes('assets-lowering-plan')) return '@pulse-compute/assets';
1140
+ if (file.includes('route-handler-context-lowering-plan')) return '@pulse-compute/wasm-runtime-core-as';
1141
+ if (file.includes('node-live-origin-route-handler-effect-proof')) return '@pulse-compute/provider-node';
1142
+ if (file.includes('node-compiled-route-handler-effect-bridge')) return '@pulse-compute/provider-node';
1143
+ if (file.includes('node-route-handler-effect-proof')) return '@pulse-compute/provider-node';
1144
+ if (file.includes('fastly-route-handler-effect-proof')) return '@pulse-compute/provider-fastly';
1145
+ if (file.includes('route-handler-effect-plan')) return '@pulse-compute/wasm-runtime-core-as';
1146
+ if (file.includes('route-handler-context-lowering')) return '@pulse-compute/wasm-runtime-core-as';
1147
+ if (file.includes('node-compiled-wasm-assets-lifecycle') || file.includes('node-assets-provider') || file.includes('node-adapter') || file.startsWith('generated/node/')) return '@pulse-compute/provider-node';
1148
+ if (file.includes('fastly') || file.startsWith('generated/fastly/')) return '@pulse-compute/provider-fastly';
1149
+ if (file.includes('schema-json')) return '@pulse-compute/wasm-schema-json';
1150
+ if (file.includes('host') || file.includes('headers') || file.includes('stream') || file.includes('backend-capabilities') || file.includes('json-body')) return '@pulse-compute/wasm-host-runtime';
1151
+ if (file.includes('library') || file.includes('capabilities')) return '@pulse-compute/wasm-library-kit';
1152
+ if (file.includes('assemblyscript') || file.startsWith('generated/as') || file.includes('compiled-handler')) return '@pulse-compute/wasm-runtime-core-as';
1153
+ if (file.includes('route') || file.includes('router') || file.includes('handler') || file.includes('dispatch') || file.includes('execution-plan') || file.includes('symbol-index')) return '@pulse-compute/wasm-compiler';
1154
+ return '@pulse-compute/wasm-compiler';
1155
+ }
1156
+
1157
+ function whyForArtifact(fileName) {
1158
+ const file = String(fileName || '');
1159
+ if (file === 'build-manifest.json') return 'records the build command, selected intent, artifacts, hashes, and status';
1160
+ if (file === 'diagnostics.json') return 'records deterministic diagnostics for the selected command';
1161
+ if (file === 'cli-doctor.json') return 'summarizes CLI doctor checks and user-actionable status';
1162
+ if (file.includes('reference-lifecycle-stabilization-proof')) return 'validates Pass 42 reference lifecycle stabilization, artifact freshness, CLI app-path config discovery, origin coverage, doctor lifecycle output, and schema-origin decode posture';
1163
+ if (file.includes('doctor-readiness-aggregator')) return 'validates Pass 53 doctor readiness aggregation across routes, lowerable packages, Node/Fastly provider posture, plan-only surfaces, and explicit beta known breaks';
1164
+ if (file.includes('lifecycle-readiness-aggregate')) return 'validates Pass 53 doctor readiness aggregation across routes, lowerable packages, Node/Fastly provider posture, and explicit beta known breaks';
1165
+ if (file.includes('lifecycle-authoring-alignment')) return 'validates Pass 52 beta authoring alignment: public router HEAD support, route/effect method consistency, doctor readiness output, and unsupported-edge diagnostics';
1166
+ if (file.includes('beta-lifecycle-golden')) return 'validates the Pass 51 beta lifecycle harness across the combined app, reference lifecycle, package-owned assets lowerers, provider readiness, docs, and unsupported-edge posture';
1167
+ if (file.includes('handler-io-lifecycle-plan')) return 'unifies route ctx reads, request body posture, backend/origin effects, schema JSON posture, and final response encoding in a plan-only lifecycle artifact';
1168
+ if (file.includes('backend-json-request-body-plan')) return 'plans schema-backed JSON request bodies for ctx.fetch backend effects with explicit backend body-mode policy';
1169
+ if (file.includes('node-backend-json-request-body-proof')) return 'proves the Node provider sends planned schema-encoded JSON request bodies to a live local origin without arbitrary object lowering';
1170
+ if (file.includes('schema-response-codec-plan')) return 'plans schema-backed ctx.result.json("Schema", ref) final response encoding and ctx.resolved(...).json("Schema") origin response decode refs';
1171
+ if (file.includes('schema-decode-result-plan')) return 'validates schema-backed ctx.req.json("Schema") / ctx.req.parse("Schema") result accessors against declared schema fields';
1172
+ if (file.includes('request-json-body-plan')) return 'plans lazy ctx.req.json/ctx.req.parse request body reads and records schema/generic parser requirements without eager parsing';
1173
+ if (file.includes('node-schema-response-codec-proof')) return 'proves the Node compiled-Wasm path can encode final JSON responses from opaque schema/generic decode refs without arbitrary JS object materialization';
1174
+ if (file.includes('node-schema-decode-result-proof')) return 'proves the Node compiled-Wasm path exposes schema-backed request JSON decode results with inspectable ok/error/accessor behavior';
1175
+ if (file.includes('node-request-json-body-proof')) return 'proves the Node compiled-Wasm path lazily reads/parses request JSON only for routes that use ctx.req.json or ctx.req.parse';
1176
+ if (file.includes('fastly-assets-package-out-parity-proof')) return 'validates Fastly consumes the packaged @pulse-compute/assets lowering surface, symbolic store config, GET/HEAD/cache/404 policy, and explicit compiled-Wasm plan-only readiness';
1177
+ if (file.includes('assets-compiled-wasm-sidecar-plan')) return 'validates the package-owned @pulse-compute/assets AssemblyScript sidecar declaration, exported symbols, terminal asset-response effect posture, and compiled-Wasm restrictions';
1178
+ if (file.includes('assets-package-out-discovery-proof')) return 'proves packaged @pulse-compute/assets is discovered from node_modules with its manifest and package-owned compiler builder, without npm registry or monorepo assets source paths';
1179
+ if (file.includes('assets-package-owned-lowering-proof')) return 'proves @pulse-compute/assets owns its PulseWasm lowering builder while library-kit only loads it generically';
1180
+ if (file.includes('assets-lowering-plan')) return 'plans lowerable pulse.assets facade usage through the package-owned assets builder without provider-owned behavior';
1181
+ if (file.includes('route-handler-context-lowering-plan')) return 'plans synchronous AS-clean ctx lowering for route handlers without provider effect execution';
1182
+ if (file.includes('node-live-origin-route-handler-effect-proof')) return 'proves the Node provider can execute planned ctx.fetch effects against a live local HTTP origin and expose ctx.resolved handles without user-authored async';
1183
+ if (file.includes('node-compiled-route-handler-effect-bridge')) return 'proves the compiled-Wasm Node bridge can suspend at ctx.resolve, execute live-origin ctx.fetch effects, inject resolved handles, and resume a continuation without async/await';
1184
+ if (file.includes('node-route-handler-effect-proof')) return 'proves the Node provider can execute planned ctx.fetch effects and expose ctx.resolved handles without compiled-Wasm suspension';
1185
+ if (file.includes('fastly-route-handler-effect-proof')) return 'proves the Fastly provider can execute planned ctx.fetch effects through symbolic backend refs and expose ctx.resolved handles without compiled-Wasm suspension';
1186
+ if (file.includes('route-handler-effect-plan')) return 'plans ctx.resolve/ctx.fetch route-handler effect lifecycle without runtime/provider execution';
1187
+ if (file.includes('route-handler-context-lowering')) return 'describes the Pass 31 synchronous ctx surface lowerable into AssemblyScript without effect execution';
1188
+ if (file.includes('node-compiled-wasm-assets-lifecycle')) return 'proves Node executes package-owned pulse.assets terminal response effects through a compiled WebAssembly boundary';
1189
+ if (file.includes('node-assets-provider')) return 'proves the Node provider consumes the assets lowering plan';
1190
+ if (file.includes('fastly-assets-provider')) return 'proves the Fastly provider consumes the assets lowering plan';
1191
+ if (file.includes('schema-json-generic-parser')) return 'describes the explicit generic AssemblyScript JSON parser fallback for schema-less payloads';
1192
+ if (file.includes('schema-json')) return 'describes schema JSON sidecar/parser integration';
1193
+ if (file.includes('host') || file.includes('headers') || file.includes('stream')) return 'describes host ABI/runtime bridge behavior';
1194
+ if (file.includes('route') || file.includes('router')) return 'describes route extraction and routing metadata';
1195
+ if (file.includes('handler')) return 'describes handler table, evaluation, or lowering metadata';
1196
+ return 'emitted by the selected PulseWasm command intent';
1197
+ }
1198
+
1199
+ function createArtifactsList(manifest, source) {
1200
+ const artifacts = Array.isArray(manifest?.artifacts) ? manifest.artifacts : [];
1201
+ return {
1202
+ version: CLI_ARTIFACTS_VERSION,
1203
+ status: manifest?.status || 'unknown',
1204
+ source,
1205
+ command: manifest?.command,
1206
+ outDir: manifest?.outDir,
1207
+ artifactCount: artifacts.length,
1208
+ artifacts: artifacts.map((artifact) => ({
1209
+ file: artifact.file,
1210
+ version: artifact.version,
1211
+ bytes: artifact.bytes,
1212
+ sha256: artifact.sha256,
1213
+ producer: producerForArtifact(artifact.file),
1214
+ why: whyForArtifact(artifact.file)
1215
+ }))
1216
+ };
1217
+ }
1218
+
1219
+ module.exports = {
1220
+ CLI_INTENT_VERSION,
1221
+ CLI_DOCTOR_VERSION,
1222
+ CLI_EXPLAIN_VERSION,
1223
+ CLI_ARTIFACTS_VERSION,
1224
+ INTENT_COMMANDS,
1225
+ PLAN_DEFAULT_FEATURES,
1226
+ DOCTOR_DEFAULT_FEATURES,
1227
+ applyCliIntent,
1228
+ commandSummary,
1229
+ createArtifactsList,
1230
+ createDoctorArtifact,
1231
+ createExplainArtifact,
1232
+ knownFeatures,
1233
+ splitList,
1234
+ pushUnique
1235
+ };