@pulse-compute/cli 0.0.0 → 1.0.0-beta.1

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 (190) hide show
  1. package/API.md +539 -0
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +70 -1
  4. package/bin/pulse.js +15 -0
  5. package/bin/pulsewasm-extract.js +22 -0
  6. package/cli-spec.json +575 -0
  7. package/completions/_pulse +106 -0
  8. package/completions/pulse.bash +31 -0
  9. package/completions/pulse.fish +76 -0
  10. package/docs/README.md +77 -0
  11. package/docs/architecture/current-contracts.md +381 -0
  12. package/docs/architecture/overview.md +93 -0
  13. package/docs/architecture/vision.md +515 -0
  14. package/docs/concepts/bodies.md +186 -0
  15. package/docs/concepts/compilation-and-lowering.md +496 -0
  16. package/docs/concepts/contracts-and-providers.md +158 -0
  17. package/docs/concepts/effects-and-continuations.md +243 -0
  18. package/docs/concepts/entities-and-adapters.md +71 -0
  19. package/docs/concepts/package-owned-lowering.md +175 -0
  20. package/docs/concepts/targets-and-hosts.md +62 -0
  21. package/docs/contributing/README.md +38 -0
  22. package/docs/contributing/adding-core-provider.md +315 -0
  23. package/docs/contributing/adding-first-party-lowerer.md +327 -0
  24. package/docs/contributing/entities-lowering.md +91 -0
  25. package/docs/contributing/package-lowerer-contract.md +383 -0
  26. package/docs/contributing/pulse-aware-packages.md +149 -0
  27. package/docs/examples.md +112 -0
  28. package/docs/fixtures/inspect-fetch-composition.selected.json +181 -0
  29. package/docs/getting-started.md +128 -0
  30. package/docs/guides/compatibility-imports.md +60 -0
  31. package/docs/guides/deploying-fastly.md +188 -0
  32. package/docs/guides/deploying-node.md +143 -0
  33. package/docs/guides/events.md +233 -0
  34. package/docs/guides/fastly-capabilities.md +153 -0
  35. package/docs/guides/fetching-and-composition.md +101 -0
  36. package/docs/guides/grip.md +94 -0
  37. package/docs/guides/json-schemas.md +233 -0
  38. package/docs/guides/migrating-from-express.md +192 -0
  39. package/docs/guides/project-lifecycle.md +143 -0
  40. package/docs/guides/routing.md +184 -0
  41. package/docs/guides/troubleshooting.md +47 -0
  42. package/docs/maintainers/README.md +60 -0
  43. package/docs/maintainers/codex-maintainer.md +71 -0
  44. package/docs/maintainers/documentation-deployment.md +147 -0
  45. package/docs/maintainers/documentation-system.md +58 -0
  46. package/docs/maintainers/documentation-versioning.md +65 -0
  47. package/docs/maintainers/maintainer-charter.md +84 -0
  48. package/docs/maintainers/maintenance-policy.json +778 -0
  49. package/docs/maintainers/maintenance-policy.md +124 -0
  50. package/docs/maintainers/npm-publishing.md +154 -0
  51. package/docs/maintainers/plugin-readiness.json +19 -0
  52. package/docs/maintainers/plugin-readiness.md +31 -0
  53. package/docs/maintainers/public-site.md +158 -0
  54. package/docs/maintainers/release-acceptance.md +250 -0
  55. package/docs/maintainers/release-manifest.md +88 -0
  56. package/docs/maintainers/repository-setup.md +145 -0
  57. package/docs/maintainers/scope-policy.md +93 -0
  58. package/docs/maintainers/support-and-triage.md +74 -0
  59. package/docs/maintainers/testing.md +288 -0
  60. package/docs/packages/README.md +59 -0
  61. package/docs/packages/assets.md +85 -0
  62. package/docs/packages/cli.md +190 -0
  63. package/docs/packages/crypto.md +71 -0
  64. package/docs/packages/entities.md +129 -0
  65. package/docs/packages/grip.md +82 -0
  66. package/docs/packages/implementation-packages.md +113 -0
  67. package/docs/packages/jwt.md +55 -0
  68. package/docs/packages/provider-fastly.md +217 -0
  69. package/docs/packages/pulse.md +159 -0
  70. package/docs/packages/runtime.md +256 -0
  71. package/docs/preview-scope.md +142 -0
  72. package/docs/reference/README.md +33 -0
  73. package/docs/reference/cli-spec.json +575 -0
  74. package/docs/reference/cli.md +457 -0
  75. package/docs/reference/compatibility-matrix.md +169 -0
  76. package/docs/reference/diagnostics.md +1872 -0
  77. package/docs/reference/documentation-versions.json +14 -0
  78. package/docs/reference/environment.md +347 -0
  79. package/docs/reference/handler-authoring.md +264 -0
  80. package/docs/reference/project-config.md +554 -0
  81. package/docs/reference/project-config.schema.json +918 -0
  82. package/docs/reference/release-manifest.json +427 -0
  83. package/docs/reference/shell-completion.md +23 -0
  84. package/documentation-site.json +661 -0
  85. package/documentation-versions.json +14 -0
  86. package/examples/01-hello-json/.pulse/.gitignore +3 -0
  87. package/examples/01-hello-json/.pulse/config.ts +16 -0
  88. package/examples/01-hello-json/README.md +119 -0
  89. package/examples/01-hello-json/package.json +20 -0
  90. package/examples/01-hello-json/src/index.ts +9 -0
  91. package/examples/01-hello-json/tests/pulse.harness.ts +22 -0
  92. package/examples/01-hello-json/tsconfig.json +14 -0
  93. package/examples/02-request-schema/.pulse/.gitignore +3 -0
  94. package/examples/02-request-schema/.pulse/config.ts +17 -0
  95. package/examples/02-request-schema/README.md +145 -0
  96. package/examples/02-request-schema/package.json +20 -0
  97. package/examples/02-request-schema/src/index.ts +18 -0
  98. package/examples/02-request-schema/src/schemas.ts +20 -0
  99. package/examples/02-request-schema/tests/pulse.harness.ts +37 -0
  100. package/examples/02-request-schema/tsconfig.json +14 -0
  101. package/examples/03-fetch-composition/.pulse/.gitignore +3 -0
  102. package/examples/03-fetch-composition/.pulse/config.ts +31 -0
  103. package/examples/03-fetch-composition/README.md +210 -0
  104. package/examples/03-fetch-composition/package.json +20 -0
  105. package/examples/03-fetch-composition/src/index.ts +60 -0
  106. package/examples/03-fetch-composition/tests/pulse.harness.ts +47 -0
  107. package/examples/03-fetch-composition/tsconfig.json +14 -0
  108. package/examples/05-fastly-capabilities/.pulse/.gitignore +3 -0
  109. package/examples/05-fastly-capabilities/.pulse/config.ts +57 -0
  110. package/examples/05-fastly-capabilities/README.md +257 -0
  111. package/examples/05-fastly-capabilities/package.json +22 -0
  112. package/examples/05-fastly-capabilities/src/index.ts +55 -0
  113. package/examples/05-fastly-capabilities/tests/pulse.harness.ts +66 -0
  114. package/examples/05-fastly-capabilities/tsconfig.json +14 -0
  115. package/examples/07-opaque-proxy/.pulse/.gitignore +3 -0
  116. package/examples/07-opaque-proxy/.pulse/config.ts +38 -0
  117. package/examples/07-opaque-proxy/README.md +150 -0
  118. package/examples/07-opaque-proxy/package.json +21 -0
  119. package/examples/07-opaque-proxy/src/index.ts +9 -0
  120. package/examples/07-opaque-proxy/tests/pulse.harness.ts +25 -0
  121. package/examples/07-opaque-proxy/tsconfig.json +14 -0
  122. package/examples/09-router-lowering/.pulse/.gitignore +3 -0
  123. package/examples/09-router-lowering/.pulse/config.ts +22 -0
  124. package/examples/09-router-lowering/README.md +287 -0
  125. package/examples/09-router-lowering/package.json +22 -0
  126. package/examples/09-router-lowering/src/index.ts +65 -0
  127. package/examples/09-router-lowering/tests/pulse.harness.ts +91 -0
  128. package/examples/09-router-lowering/tsconfig.json +14 -0
  129. package/examples/10-entities-tools/.pulse/.gitignore +4 -0
  130. package/examples/10-entities-tools/.pulse/config.ts +23 -0
  131. package/examples/10-entities-tools/README.md +165 -0
  132. package/examples/10-entities-tools/package.json +21 -0
  133. package/examples/10-entities-tools/src/handlers.ts +15 -0
  134. package/examples/10-entities-tools/src/index.ts +31 -0
  135. package/examples/10-entities-tools/src/schemas.ts +18 -0
  136. package/examples/10-entities-tools/tests/pulse.harness.ts +40 -0
  137. package/examples/10-entities-tools/tools-facade.cjs +158 -0
  138. package/examples/10-entities-tools/tsconfig.json +14 -0
  139. package/examples/11-events/.pulse/.gitignore +4 -0
  140. package/examples/11-events/.pulse/config.ts +24 -0
  141. package/examples/11-events/README.md +194 -0
  142. package/examples/11-events/package.json +20 -0
  143. package/examples/11-events/src/index.ts +27 -0
  144. package/examples/11-events/src/schemas.ts +19 -0
  145. package/examples/11-events/tests/pulse.harness.ts +34 -0
  146. package/examples/11-events/tsconfig.json +15 -0
  147. package/examples/12-mcp-proxy/.pulse/.gitignore +3 -0
  148. package/examples/12-mcp-proxy/.pulse/config.ts +25 -0
  149. package/examples/12-mcp-proxy/README.md +149 -0
  150. package/examples/12-mcp-proxy/package.json +20 -0
  151. package/examples/12-mcp-proxy/src/index.ts +17 -0
  152. package/examples/12-mcp-proxy/tests/pulse.harness.ts +29 -0
  153. package/examples/12-mcp-proxy/tsconfig.json +14 -0
  154. package/examples/13-jwt-es256/.pulse/config.ts +19 -0
  155. package/examples/13-jwt-es256/README.md +195 -0
  156. package/examples/13-jwt-es256/package.json +21 -0
  157. package/examples/13-jwt-es256/src/index.ts +21 -0
  158. package/examples/13-jwt-es256/tests/pulse.harness.ts +54 -0
  159. package/examples/13-jwt-es256/tsconfig.json +14 -0
  160. package/examples/README.md +36 -0
  161. package/package.json +66 -6
  162. package/project-config.schema.json +918 -0
  163. package/release-manifest.json +427 -0
  164. package/src/command-spec.js +279 -0
  165. package/src/completion.js +113 -0
  166. package/src/diagnostics.js +350 -0
  167. package/src/documentation.js +45 -0
  168. package/src/index.d.ts +133 -0
  169. package/src/index.js +15 -0
  170. package/src/internal/command-executor.d.ts +29 -0
  171. package/src/internal/command-executor.js +143 -0
  172. package/src/internal/command-plan.d.ts +9 -0
  173. package/src/internal/command-plan.js +73 -0
  174. package/src/internal/command-reporter.d.ts +15 -0
  175. package/src/internal/command-reporter.js +133 -0
  176. package/src/internal/command-request.d.ts +35 -0
  177. package/src/internal/command-request.js +154 -0
  178. package/src/internal/node-http.js +54 -0
  179. package/src/internal/project-context.d.ts +66 -0
  180. package/src/internal/project-context.js +175 -0
  181. package/src/project-config-reference.js +4 -0
  182. package/src/project-config-schema.d.ts +23 -0
  183. package/src/project-config-schema.js +271 -0
  184. package/src/project-config.js +724 -0
  185. package/src/project-execution.js +2930 -0
  186. package/src/provider-drivers.js +3 -0
  187. package/src/target-support.js +3 -0
  188. package/src/typescript-module-loader.js +269 -0
  189. package/src/workflow.js +78 -0
  190. package/src/workspace.js +82 -0
@@ -0,0 +1,14 @@
1
+ {
2
+ "schemaVersion": "pulse.documentation-versions.v1",
3
+ "latest": "1.0.0-beta.1",
4
+ "versions": [
5
+ {
6
+ "version": "1.0.0-beta.1",
7
+ "segment": "v1.0.0-beta.1",
8
+ "channel": "beta",
9
+ "releasedAt": "2026-08-01",
10
+ "status": "current",
11
+ "sourceManifest": "release/pulse-release-manifest.json"
12
+ }
13
+ ]
14
+ }
@@ -0,0 +1,347 @@
1
+ # Environment-variable reference
2
+
3
+ <!-- Generated by wasm/scripts/sync-reference-docs.cjs. Edit the source catalog, not this file. -->
4
+
5
+ Pulse canonical handlers do not receive ambient process environment access. Handler authority comes only through the documented `ctx` capabilities and project/provider bindings. The variables here configure release tooling, compatibility helpers, or repository tests.
6
+
7
+ Do not use these variables as a substitute for `ctx.config`, `ctx.secret`, or provider bindings. Secret-bearing compatibility URIs must be handled as credentials and must not be copied into diagnostics.
8
+
9
+ ## Index
10
+
11
+ | Variable | Scope | Stability |
12
+ |---|---|---|
13
+ | [`PULSE_FASTLY_BIN`](#pulse-fastly-bin) | Supported tooling configuration | Supported Beta tooling override. |
14
+ | [`PULSE_VICEROY_BIN`](#pulse-viceroy-bin) | Supported tooling configuration | Supported Beta tooling override. |
15
+ | [`PULSE_PROFILE`](#pulse-profile) | Supported tooling configuration | Supported project-selection input. |
16
+ | [`PULSE_RELEASE_REF`](#pulse-release-ref) | Contributor and test-only configuration | Repository release-workflow internal; not an application setting. |
17
+ | [`PULSE_RELEASE_SHA`](#pulse-release-sha) | Contributor and test-only configuration | Repository release-workflow internal; not an application setting. |
18
+ | [`PULSEWASM_ARTIFACTS_DIR`](#pulsewasm-artifacts-dir) | Contributor and test-only configuration | Contributor/test-only. |
19
+ | [`PULSEWASM_TEST_TMP_ROOT`](#pulsewasm-test-tmp-root) | Contributor and test-only configuration | Contributor/test-only; may change with test-runner updates. |
20
+ | [`PULSE_FASTLY_REALITY_EVIDENCE`](#pulse-fastly-reality-evidence) | Contributor and test-only configuration | Contributor/release tooling override. |
21
+ | [`PULSE_FOUR_MODE_EVIDENCE`](#pulse-four-mode-evidence) | Contributor and test-only configuration | Contributor/release tooling override. |
22
+ | [`PULSE_SOURCE_REVISION`](#pulse-source-revision) | Contributor and test-only configuration | Repository release-evidence internal; not an application setting. |
23
+ | [`PULSE_SOURCE_IDENTITY_KIND`](#pulse-source-identity-kind) | Contributor and test-only configuration | Repository release-evidence internal; not an application setting. |
24
+ | [`PULSE_SOURCE_DIGEST_SHA256`](#pulse-source-digest-sha256) | Contributor and test-only configuration | Repository release-evidence internal; not an application setting. |
25
+ | [`PULSE_SOURCE_FILE_COUNT`](#pulse-source-file-count) | Contributor and test-only configuration | Repository release-evidence internal; not an application setting. |
26
+ | [`PULSE_FAKE_FASTLY_CAPTURE`](#pulse-fake-fastly-capture) | Contributor and test-only configuration | Fixture-only; not a public tooling setting. |
27
+ | [`PULSE_FAKE_VICEROY_CAPTURE`](#pulse-fake-viceroy-capture) | Contributor and test-only configuration | Fixture-only; not a public tooling setting. |
28
+ | [`PULSE_ES256_REPRODUCTION_ROOT`](#pulse-es256-reproduction-root) | Contributor and test-only configuration | Contributor/test-only proof reproduction control. |
29
+ | [`PULSE_ES256_REPRODUCTION_ARCHIVE`](#pulse-es256-reproduction-archive) | Contributor and test-only configuration | Contributor/test-only proof reproduction control. |
30
+ | [`PULSE_RUST_CARGO`](#pulse-rust-cargo) | Contributor and test-only configuration | Contributor/test-only proof reproduction control. |
31
+ | [`PULSE_RUSTC`](#pulse-rustc) | Contributor and test-only configuration | Contributor/test-only proof reproduction control. |
32
+
33
+ ## Supported tooling configuration
34
+
35
+ Documented environment inputs accepted by release tooling. These configure tools, not handler authority.
36
+
37
+ <a id="pulse-fastly-bin"></a>
38
+
39
+ ### `PULSE_FASTLY_BIN`
40
+
41
+ Selects the Fastly CLI binary used for external target inspection and local Compute execution.
42
+
43
+ | Property | Contract |
44
+ |---|---|
45
+ | Value | Absolute or relative executable path |
46
+ | Default | No explicit path; discover `fastly` on `PATH`. |
47
+ | Precedence | An explicit `binary` option wins, then `PULSE_FASTLY_BIN`, then `PATH` discovery. |
48
+ | Consumer | Fastly CLI inspection and the external Compute reality gate. |
49
+ | Secret safety | Not a secret. Do not point it at an untrusted executable. |
50
+ | Stability | Supported Beta tooling override. |
51
+ | Source owners | `packages/provider-fastly/src/testing/fastly-cli.js` |
52
+
53
+ <a id="pulse-viceroy-bin"></a>
54
+
55
+ ### `PULSE_VICEROY_BIN`
56
+
57
+ Selects an inspected Viceroy executable for direct local Compute execution when no explicit Fastly CLI launcher is selected.
58
+
59
+ | Property | Contract |
60
+ |---|---|
61
+ | Value | Absolute or relative executable path |
62
+ | Default | Unset; discover the Fastly CLI first, then Viceroy, on `PATH`. |
63
+ | Precedence | An explicit launcher choice wins. Without one, an explicit Fastly CLI path selects CLI ownership; otherwise an explicit `viceroyBinary` or `PULSE_VICEROY_BIN` selects direct Viceroy execution. |
64
+ | Consumer | External Fastly Compute reality gates, either as the direct local engine or as an explicit Fastly CLI engine override. |
65
+ | Secret safety | Not a secret. Do not point it at an untrusted executable. |
66
+ | Stability | Supported Beta tooling override. |
67
+ | Source owners | `packages/provider-fastly/src/testing/fastly-cli.js` |
68
+
69
+ <a id="pulse-profile"></a>
70
+
71
+ ### `PULSE_PROFILE`
72
+
73
+ Selects the flat Pulse project profile when no explicit `--profile` option is supplied.
74
+
75
+ | Property | Contract |
76
+ |---|---|
77
+ | Value | Pulse profile name |
78
+ | Default | Unset; use `pulse.defaultProfile` when declared. |
79
+ | Precedence | `--profile` wins, then `PULSE_PROFILE`, then `pulse.defaultProfile`. |
80
+ | Consumer | Project-aware Pulse CLI commands using the `.pulse/config.ts` convention. |
81
+ | Secret safety | Not a secret. It selects a committed profile and never carries resolved binding values. |
82
+ | Stability | Supported project-selection input. |
83
+ | Source owners | `wasm/packages/cli/src/project-config.js` |
84
+
85
+ ## Contributor and test-only configuration
86
+
87
+ Repository harness controls. They are intentionally outside the application compatibility contract.
88
+
89
+ <a id="pulse-release-ref"></a>
90
+
91
+ ### `PULSE_RELEASE_REF`
92
+
93
+ Carries the sealed candidate release ref into the protected publish process for an equality check against GitHub's native identity.
94
+
95
+ | Property | Contract |
96
+ |---|---|
97
+ | Value | Full Git ref (`refs/tags/v<version>`) |
98
+ | Default | Unset; the protected npm workflow derives it from the sealed candidate. |
99
+ | Precedence | When set by the workflow, it must exactly equal GitHub's native release-tag ref. |
100
+ | Consumer | Protected npm publication identity binding. |
101
+ | Secret safety | Not a secret. It is validated rather than trusted as independent authority. |
102
+ | Stability | Repository release-workflow internal; not an application setting. |
103
+ | Source owners | `scripts/release-publication.cjs` |
104
+
105
+ <a id="pulse-release-sha"></a>
106
+
107
+ ### `PULSE_RELEASE_SHA`
108
+
109
+ Carries the sealed candidate source commit into the protected publish process for an equality check against GitHub's native identity.
110
+
111
+ | Property | Contract |
112
+ |---|---|
113
+ | Value | Full lowercase 40-character Git commit SHA |
114
+ | Default | Unset; the protected npm workflow derives it from the sealed candidate. |
115
+ | Precedence | When set by the workflow, it must exactly equal GitHub's native release-tag commit. |
116
+ | Consumer | Protected npm publication identity binding. |
117
+ | Secret safety | Not a secret. It is validated rather than trusted as independent authority. |
118
+ | Stability | Repository release-workflow internal; not an application setting. |
119
+ | Source owners | `scripts/release-publication.cjs` |
120
+
121
+ <a id="pulsewasm-artifacts-dir"></a>
122
+
123
+ ### `PULSEWASM_ARTIFACTS_DIR`
124
+
125
+ Redirects generated build and test artifacts away from the default repository directory.
126
+
127
+ | Property | Contract |
128
+ |---|---|
129
+ | Value | Directory path |
130
+ | Default | `wasm/artifacts`. |
131
+ | Precedence | Overrides the repository artifact root for scripts that opt into it. |
132
+ | Consumer | Build and test isolation. |
133
+ | Secret safety | Not a secret. Use an isolated writable directory. |
134
+ | Stability | Contributor/test-only. |
135
+ | Source owners | `wasm/packages/build-support/src/artifacts-dir.js`, `wasm/scripts/build.cjs`, `wasm/scripts/run-wasm-tests.cjs` |
136
+
137
+ <a id="pulsewasm-test-tmp-root"></a>
138
+
139
+ ### `PULSEWASM_TEST_TMP_ROOT`
140
+
141
+ Pins test workspaces beneath a caller-managed temporary root.
142
+
143
+ | Property | Contract |
144
+ |---|---|
145
+ | Value | Directory path |
146
+ | Default | A suite-specific temporary directory. |
147
+ | Precedence | When set, tests create their working directories beneath this root. |
148
+ | Consumer | Documentation, CLI, provider, package-release, and clean-machine acceptance tests. |
149
+ | Secret safety | Not a secret. The directory may contain generated projects and test data. |
150
+ | Stability | Contributor/test-only; may change with test-runner updates. |
151
+ | Source owners | `wasm/test/docs/assert-executable-documentation.cjs`, `wasm/test/release/assert-release-packages.cjs` |
152
+
153
+ <a id="pulse-fastly-reality-evidence"></a>
154
+
155
+ ### `PULSE_FASTLY_REALITY_EVIDENCE`
156
+
157
+ Selects the output path for the real Fastly host evidence report.
158
+
159
+ | Property | Contract |
160
+ |---|---|
161
+ | Value | File path |
162
+ | Default | Unset; the reality gate prints its normal test result without retaining a proof file. |
163
+ | Precedence | When set, the real-host gate writes its redacted machine-readable proof to this path. |
164
+ | Consumer | Fastly CLI-managed or direct-Viceroy local Compute reality gate. |
165
+ | Secret safety | Not a secret. The proof intentionally excludes secret values and authorization plaintext. |
166
+ | Stability | Contributor/release tooling override. |
167
+ | Source owners | `wasm/test/provider/assert-fastly-compute-reality.cjs` |
168
+
169
+ <a id="pulse-four-mode-evidence"></a>
170
+
171
+ ### `PULSE_FOUR_MODE_EVIDENCE`
172
+
173
+ Selects the output path for the four-mode conformance evidence report.
174
+
175
+ | Property | Contract |
176
+ |---|---|
177
+ | Value | File path |
178
+ | Default | `wasm/.test-results/four-mode-conformance.json`. |
179
+ | Precedence | When set, the four-mode conformance suite writes its revision-bound proof to this path. |
180
+ | Consumer | Node/Fastly Native/JavaScript conformance evidence. |
181
+ | Secret safety | Not a secret. The proof records target identities, support hashes, and test outcomes without application secrets. |
182
+ | Stability | Contributor/release tooling override. |
183
+ | Source owners | `wasm/test/contracts/assert-four-mode-conformance.cjs` |
184
+
185
+ <a id="pulse-source-revision"></a>
186
+
187
+ ### `PULSE_SOURCE_REVISION`
188
+
189
+ Propagates one source identity through an aggregate release replay so independently written evidence cannot drift.
190
+
191
+ | Property | Contract |
192
+ |---|---|
193
+ | Value | 40-character lowercase source identity |
194
+ | Default | Current Git commit, or a deterministic archive-tree identity outside a Git checkout. |
195
+ | Precedence | When set by the release runner, every child evidence shard validates and reuses this exact identity. |
196
+ | Consumer | Release-seal task, four-mode, and offline deployment-candidate evidence binding. |
197
+ | Secret safety | Not a secret. It identifies source but grants no publication or deployment authority. |
198
+ | Stability | Repository release-evidence internal; not an application setting. |
199
+ | Source owners | `scripts/source-identity.cjs` |
200
+
201
+ <a id="pulse-source-identity-kind"></a>
202
+
203
+ ### `PULSE_SOURCE_IDENTITY_KIND`
204
+
205
+ Labels the provenance class of the propagated source identity.
206
+
207
+ | Property | Contract |
208
+ |---|---|
209
+ | Value | Source identity classification |
210
+ | Default | `git-commit` in a checkout or `archive-tree-sha256-160` for an extracted source tree. |
211
+ | Precedence | Meaningful only with `PULSE_SOURCE_REVISION`; the release runner supplies both together. |
212
+ | Consumer | Release-seal reports, test reports, four-mode evidence, and offline candidate manifests. |
213
+ | Secret safety | Not a secret. It prevents an archive digest from being represented as a Git commit. |
214
+ | Stability | Repository release-evidence internal; not an application setting. |
215
+ | Source owners | `scripts/source-identity.cjs` |
216
+
217
+ <a id="pulse-source-digest-sha256"></a>
218
+
219
+ ### `PULSE_SOURCE_DIGEST_SHA256`
220
+
221
+ Preserves the full archive-tree digest behind the compatibility-width source revision field.
222
+
223
+ | Property | Contract |
224
+ |---|---|
225
+ | Value | 64-character lowercase SHA-256 digest |
226
+ | Default | Unset for Git commits; the full archive-tree digest outside a Git checkout. |
227
+ | Precedence | The release runner supplies it with an archive-tree source identity. |
228
+ | Consumer | Release-seal reports, test reports, four-mode evidence, and offline candidate manifests. |
229
+ | Secret safety | Not a secret. It is integrity metadata and carries no release authority. |
230
+ | Stability | Repository release-evidence internal; not an application setting. |
231
+ | Source owners | `scripts/source-identity.cjs` |
232
+
233
+ <a id="pulse-source-file-count"></a>
234
+
235
+ ### `PULSE_SOURCE_FILE_COUNT`
236
+
237
+ Carries the source-file count associated with an archive-tree digest for audit clarity.
238
+
239
+ | Property | Contract |
240
+ |---|---|
241
+ | Value | Non-negative integer |
242
+ | Default | Unset for Git commits; the deterministic archive-tree inventory count otherwise. |
243
+ | Precedence | The release runner supplies it with an archive-tree source identity. |
244
+ | Consumer | Release-seal reports, test reports, four-mode evidence, and offline candidate manifests. |
245
+ | Secret safety | Not a secret. It records only the number of source files in the identity inventory. |
246
+ | Stability | Repository release-evidence internal; not an application setting. |
247
+ | Source owners | `scripts/source-identity.cjs` |
248
+
249
+ <a id="pulse-fake-fastly-capture"></a>
250
+
251
+ ### `PULSE_FAKE_FASTLY_CAPTURE`
252
+
253
+ Tells the fake Fastly CLI where to write its captured invocation.
254
+
255
+ | Property | Contract |
256
+ |---|---|
257
+ | Value | File path |
258
+ | Default | Unset. |
259
+ | Precedence | Used only by the fake Fastly CLI fixture when present. |
260
+ | Consumer | Fastly CLI surface test fixture. |
261
+ | Secret safety | Not a secret. The file records test arguments and paths. |
262
+ | Stability | Fixture-only; not a public tooling setting. |
263
+ | Source owners | `wasm/test/provider/assert-fastly-cli-gate-surface.cjs` |
264
+
265
+ <a id="pulse-fake-viceroy-capture"></a>
266
+
267
+ ### `PULSE_FAKE_VICEROY_CAPTURE`
268
+
269
+ Tells the fake Viceroy launcher where to write its captured invocation.
270
+
271
+ | Property | Contract |
272
+ |---|---|
273
+ | Value | File path |
274
+ | Default | Unset. |
275
+ | Precedence | Used only by the fake direct-Viceroy fixture when present. |
276
+ | Consumer | Fastly local-engine surface test fixture. |
277
+ | Secret safety | Not a secret. The file records test arguments and paths. |
278
+ | Stability | Fixture-only; not a public tooling setting. |
279
+ | Source owners | `wasm/test/provider/assert-fastly-cli-gate-surface.cjs` |
280
+
281
+ <a id="pulse-es256-reproduction-root"></a>
282
+
283
+ ### `PULSE_ES256_REPRODUCTION_ROOT`
284
+
285
+ Adds an independent source-identical raw guest artifact and Rust metadata comparison to G5.
286
+
287
+ | Property | Contract |
288
+ |---|---|
289
+ | Value | Directory path |
290
+ | Default | Unset; the G5 seal still performs its required local maintainer reconstruction. |
291
+ | Precedence | The `--reproduction-root` G5 option wins, then `PULSE_ES256_REPRODUCTION_ROOT`. |
292
+ | Consumer | Optional independent clean-container output comparison in the ES256 G5 seal. |
293
+ | Secret safety | Not a secret. The directory must contain only the public verifier source and build output. |
294
+ | Stability | Contributor/test-only proof reproduction control. |
295
+ | Source owners | `wasm/test/jwt/assert-jwt-es256-final-seal.cjs` |
296
+
297
+ <a id="pulse-es256-reproduction-archive"></a>
298
+
299
+ ### `PULSE_ES256_REPRODUCTION_ARCHIVE`
300
+
301
+ Records the byte size and hash of the independently supplied ES256 reproduction archive.
302
+
303
+ | Property | Contract |
304
+ |---|---|
305
+ | Value | File path |
306
+ | Default | Unset; no external archive identity is recorded. |
307
+ | Precedence | The `--reproduction-archive` G5 option wins, then `PULSE_ES256_REPRODUCTION_ARCHIVE`. |
308
+ | Consumer | Optional independent clean-container archive identity in the ES256 G5 seal. |
309
+ | Secret safety | Not a secret. The archive must contain only the public verifier source and build output. |
310
+ | Stability | Contributor/test-only proof reproduction control. |
311
+ | Source owners | `wasm/test/jwt/assert-jwt-es256-final-seal.cjs` |
312
+
313
+ <a id="pulse-rust-cargo"></a>
314
+
315
+ ### `PULSE_RUST_CARGO`
316
+
317
+ Selects the Cargo executable used to reproduce the sealed first-party Rust guest proof.
318
+
319
+ | Property | Contract |
320
+ |---|---|
321
+ | Value | Absolute or relative executable path |
322
+ | Default | No explicit path; discover `cargo` on `PATH`. |
323
+ | Precedence | `PULSE_RUST_CARGO` overrides `PATH` discovery in the guest-link proof harnesses. |
324
+ | Consumer | Phase A guest-link Rust fixture compilation and toolchain recording. |
325
+ | Secret safety | Not a secret. Do not point it at an untrusted executable. |
326
+ | Stability | Contributor/test-only proof reproduction control. |
327
+ | Source owners | `wasm/test/guest-link/assert-scalar-link-control.cjs`, `wasm/test/guest-link/assert-memory-matrix.cjs`, `wasm/test/guest-link/assert-final-artifact-reality.cjs` |
328
+
329
+ <a id="pulse-rustc"></a>
330
+
331
+ ### `PULSE_RUSTC`
332
+
333
+ Selects the Rust compiler used to reproduce the sealed first-party Rust guest proof.
334
+
335
+ | Property | Contract |
336
+ |---|---|
337
+ | Value | Absolute or relative executable path |
338
+ | Default | No explicit path; discover `rustc` on `PATH`. |
339
+ | Precedence | `PULSE_RUSTC` overrides `PATH` discovery in the guest-link proof harnesses. |
340
+ | Consumer | Phase A guest-link Rust fixture compilation and toolchain recording. |
341
+ | Secret safety | Not a secret. Do not point it at an untrusted executable. |
342
+ | Stability | Contributor/test-only proof reproduction control. |
343
+ | Source owners | `wasm/test/guest-link/assert-scalar-link-control.cjs`, `wasm/test/guest-link/assert-memory-matrix.cjs`, `wasm/test/guest-link/assert-final-artifact-reality.cjs` |
344
+
345
+ ## Standard process variables
346
+
347
+ Pulse also observes normal operating-system inputs such as `PATH` while locating external tools. Standard process variables are not renamed as Pulse configuration and are outside this catalog.
@@ -0,0 +1,264 @@
1
+ # Managed handler TypeScript and JavaScript
2
+
3
+ This is the canonical language reference for managed Pulse handlers. It defines
4
+ the shared TypeScript/JavaScript authoring shape, the subset that can lower to
5
+ Native, and the extensions available only under an explicitly selected
6
+ JavaScript target.
7
+
8
+ The authoritative four-mode support table is
9
+ [Provider and target compatibility](./compatibility-matrix.md). Target
10
+ selection never silently rewrites the application or falls back to another
11
+ target.
12
+
13
+ ## One source model
14
+
15
+ Pulse accepts `.ts`, `.mts`, `.js`, and `.mjs` project modules through the
16
+ reachable project graph. TypeScript annotations, interfaces, type-only imports,
17
+ generic arguments, and `as const`-style authoring metadata do not become
18
+ runtime capabilities. JavaScript and TypeScript use the same managed handler,
19
+ Router, context, effect, and result contract.
20
+
21
+ Portable handler code should stay inside the subset the Native plan can encode:
22
+
23
+ - scalar, array, and object literals, including supported literal spreads;
24
+ - simple local declarations and assignments;
25
+ - property and element reads;
26
+ - template strings;
27
+ - arithmetic, comparison, equality, boolean, bitwise, and nullish operators;
28
+ - prefix unary operators, updates, and conditional expressions;
29
+ - `if`/`else`, blocks, expression statements, and explicit returns;
30
+ - static calls to the documented `ctx`, Router, and supported package-root
31
+ surfaces.
32
+
33
+ The compiler, not the file extension, decides Native eligibility. A `.js` file
34
+ can be Native-eligible, and a `.ts` file can cross the Native boundary.
35
+
36
+ ## Native language boundary
37
+
38
+ Native lowering requires source that resolves to the bounded canonical plan.
39
+ The current Native subset rejects or records a boundary for:
40
+
41
+ - `for`, `for...of`, `for...in`, `while`, and `do...while` loops;
42
+ - `switch`, `try`/`catch`/`finally`, and authored `throw`;
43
+ - classes, constructors, `new`, `this`, generators, and optional chaining;
44
+ - nested function or closure execution in a managed handler;
45
+ - general destructuring declarations, except the recognized static result
46
+ binding produced by `await ctx.parallel({ ... })`;
47
+ - dynamic imports, CommonJS `require`, runtime module discovery, and dynamic
48
+ calls the compiler cannot resolve;
49
+ - recursion, top-level mutable runtime state, or capture of module-evaluation
50
+ values;
51
+ - arbitrary Promise construction or library awaits;
52
+ - ambient authority such as global `fetch`, timers, process/environment,
53
+ filesystem, sockets, randomness, or provider SDKs.
54
+
55
+ An explicitly selected JavaScript application may keep ordinary
56
+ provider-compatible JavaScript packages, Promise construction, and library
57
+ awaits. Those forms are recorded as Native eligibility boundaries. They do not
58
+ permit ambient host authority, do not become Pulse effects, and cannot be used
59
+ inside `ctx.parallel`.
60
+
61
+ ## Why handlers are async-shaped
62
+
63
+ Every managed handler returns a promise-shaped result in TypeScript:
64
+
65
+ ```ts
66
+ type Handler = (
67
+ ctx: PulseContext
68
+ ) => Promise<PulseResult | PulseFetchResponse>
69
+ ```
70
+
71
+ JavaScript targets execute that shape through a provider-owned request
72
+ lifecycle. Native targets treat the wrapper as authoring notation. The compiler
73
+ turns trusted host operations into explicit effects and the following code into
74
+ continuations, then removes `async` and `await` from generated Native code.
75
+
76
+ This gives one familiar source shape without pretending that Native contains a
77
+ general JavaScript Promise runtime.
78
+
79
+ Static event handlers use the same managed notation with a non-HTTP context and
80
+ void completion:
81
+
82
+ ```ts
83
+ app.on('device.reading', { schema: 'events.DeviceReading' }, async (ctx) => {
84
+ const mode = await ctx.config.get('MODE')
85
+ ctx.state.set('mode', mode)
86
+ void ctx.event.payload
87
+ })
88
+ ```
89
+
90
+ `ctx.event.type` is the exact registered type and `ctx.event.payload` is the
91
+ immutable schema-validated payload, or `null` for a no-payload registration.
92
+ Event handlers cannot access request metadata, route parameters, response
93
+ builders, Router transfer, middleware, or a response result. Eligible handlers
94
+ lower through the conditional provider-neutral Native event entry and reuse the
95
+ existing effect/continuation state machine. This does not activate a provider
96
+ event transport or target-support claim.
97
+
98
+ See [Static events and outbound emission](../guides/events.md) for the complete
99
+ frame, queue, harness, target, Native-extension, and explicit no-call contract.
100
+
101
+ ## Trusted awaits
102
+
103
+ The portable awaited forms are Pulse-owned operations:
104
+
105
+ - `ctx.req.text()` and `ctx.req.json(schemaId?)`;
106
+ - `ctx.fetch(url, init)` and its `.text()` or `.json(schemaId?)` projections;
107
+ - `ctx.config.get(name)` and `ctx.secret.get(name)`;
108
+ - `ctx.kv(namespace).get(key)` and `.put(key, value)`;
109
+ - `ctx.parallel({ ... })`;
110
+ - request-bound effects from supported package roots, such as
111
+ `grip.broadcast(ctx, message)`.
112
+
113
+ Response construction, request metadata, route parameters, `ctx.state`, and
114
+ `ctx.log` are synchronous. Awaiting a proven synchronous value is redundant and
115
+ may produce a warning.
116
+
117
+ The canonical synchronous context forms include `ctx.req.method`,
118
+ `ctx.req.url`, `ctx.req.path`, immutable `ctx.req.headers`, the
119
+ case-insensitive `ctx.req.header(name)` helper, `ctx.param(name)` inside matched
120
+ route handlers, `ctx.state.get` / `ctx.state.set`, response builders, and fixed
121
+ `ctx.log` methods. The [context API map](../../API.md#context-at-a-glance)
122
+ separates HTTP-only, route-only, event-only, and shared execution authority.
123
+
124
+ Arbitrary library awaits and Promise construction are JavaScript-only. They are
125
+ not Pulse effects, do not enter `ctx.parallel`, and make the same source
126
+ ineligible for Native compilation.
127
+
128
+ `ctx.emit(type, { schema, payload? })` is a recognized Pulse effect for direct
129
+ JavaScript execution and Native lowering. It requires literal event/schema
130
+ identities and direct await, or placement as a fresh member of an awaited
131
+ `ctx.parallel` group. Native emits the same canonical effect descriptor and
132
+ resumes its ordinary continuation after host acceptance; no Promise runtime,
133
+ JavaScript import, Asyncify transform, or fallback is added. Node has a bounded
134
+ reference ingress/acceptance realization for direct parity evidence. It is not
135
+ a public bus or a delivery guarantee, and other provider eligibility remains
136
+ separate.
137
+
138
+ ## `ctx.parallel` is an explicit portable group
139
+
140
+ Use `ctx.parallel` when operations must begin together across all four modes:
141
+
142
+ ```ts
143
+ const { profile, flags } = await ctx.parallel({
144
+ profile: ctx.fetch(profileUrl).json<Profile>(),
145
+ flags: ctx.fetch(flagsUrl).json<Flags>(),
146
+ })
147
+ ```
148
+
149
+ The accepted shape is deliberately narrow:
150
+
151
+ - one nonempty inline object literal;
152
+ - fixed, unique, non-index string keys;
153
+ - no spreads, computed keys, getters, methods, arrays, or dynamic records;
154
+ - one fresh execution-owned `PulseParallelEffect` per value;
155
+ - no arbitrary promises, reused roots, cross-request effects, or nested groups.
156
+
157
+ Property order owns effect identity, trace order, deterministic primary-failure
158
+ selection, and keyed result reconstruction. Every member settles before the
159
+ continuation resumes.
160
+
161
+ Separate awaits retain normal sequential behavior on JavaScript. Native may
162
+ also group adjacent independent trusted effects internally, but that
163
+ optimization is not a portable concurrency promise. Use `ctx.parallel` when
164
+ concurrency is application behavior.
165
+
166
+ ## Static application boundaries
167
+
168
+ Beyond the expression and statement subset above, Native eligibility requires
169
+ an application graph the compiler can prove:
170
+
171
+ - a statically reachable project entry and module graph;
172
+ - async-shaped managed handlers with a simple `ctx` identifier;
173
+ - static Router construction, route methods, paths, mounts, and handler
174
+ references;
175
+ - root-only static `Pulse.on` registrations with literal event/schema identities,
176
+ one exact owner per event type, and void event-handler completion;
177
+ - literal schema and response-case identities;
178
+ - supported `ctx` call shapes and bounded object options;
179
+ - supported package-root imports with the package's documented static
180
+ arguments;
181
+ - no dynamic import, generator handler, nested async handler, provider SDK, or
182
+ ambient authority.
183
+
184
+ JavaScript targets preserve a broader ordinary package and async surface, but
185
+ the provider's runtime and packaging environment still decide whether a
186
+ dependency is compatible. A Node-only dependency does not become Fastly
187
+ compatible merely because both targets are JavaScript.
188
+
189
+ ## Router topology and terminal transfer
190
+
191
+ `Router` is a compile-time authoring marker. The v2 surface supports static
192
+ `get`, `head`, and `post` routes; exact, named-parameter, and trailing-wildcard
193
+ paths; global and path-scoped middleware; acyclic mounts; fallthrough; and
194
+ error middleware.
195
+
196
+ `next()` is terminal:
197
+
198
+ ```ts
199
+ app.use(async (ctx, next) => {
200
+ if (!authorized(ctx)) return ctx.text('unauthorized', { status: 401 })
201
+ return next()
202
+ })
203
+ ```
204
+
205
+ The current handler never resumes after `return next()` or
206
+ `return next(error)`. Assigning, awaiting, or calling `next()` without returning
207
+ it is rejected. Pulse does not provide onion-style post-`next()` work.
208
+
209
+ ## JSON and body ownership
210
+
211
+ With the default `pulse.strict: true`, request, fetch, and response JSON
212
+ boundaries use static schema or response-case IDs declared by the project.
213
+ Setting `pulse.strict: false` deliberately enables bounded generic JSON and
214
+ records that parser requirement in the plan.
215
+
216
+ Structured bodies may be read as bounded text or JSON. Opaque bodies remain
217
+ host-owned. Return an opaque fetch or package result directly; do not inspect
218
+ its bytes, iterate chunks, transform it, or retain it beyond the request.
219
+
220
+ ## Supported imports and extension boundaries
221
+
222
+ Canonical source may import:
223
+
224
+ - `@pulse-compute/pulse` and `@pulse-compute/runtime`;
225
+ - supported package roots such as `@pulse-compute/assets` and
226
+ `@pulse-compute/grip`;
227
+ - ordinary JavaScript dependencies when the explicitly selected JavaScript
228
+ target can package and execute them.
229
+
230
+ Native lowering recognizes only the core contract and synchronized trusted
231
+ package-root lowerers. Compatibility `/pulsewasm` subpaths are not the preferred
232
+ authoring surface. Arbitrary third-party lowerer loading and provider SDK
233
+ imports are unsupported.
234
+
235
+ See [Pulse-aware package authoring](../contributing/pulse-aware-packages.md),
236
+ [Compatibility imports and migration](../guides/compatibility-imports.md), and
237
+ the target cells in the [compatibility matrix](./compatibility-matrix.md).
238
+
239
+ ## How Native ineligibility is reported
240
+
241
+ For a Native-selected profile, `doctor`, `inspect`, `compile`, and `build`
242
+ report source-located eligibility diagnostics and stop before target
243
+ realization. Common classes include unsupported awaits, ambient authority,
244
+ dynamic topology, unresolved package ownership, and unsupported package call
245
+ shapes.
246
+
247
+ For an explicitly selected JavaScript profile, inspection records Native
248
+ eligibility separately from JavaScript target support. A JavaScript build may
249
+ proceed when its own project, package, capability, and provider requirements
250
+ are eligible. A Native failure never triggers automatic JavaScript fallback,
251
+ and Pulse does not choose Native after an explicit JavaScript selection.
252
+
253
+ Use:
254
+
255
+ ```bash
256
+ pulse doctor --json
257
+ pulse inspect --json
258
+ ```
259
+
260
+ Then follow the stable diagnostic and its source location. See
261
+ [Troubleshooting](../guides/troubleshooting.md), [Diagnostics and
262
+ remediation](./diagnostics.md), [Static Router authoring](../guides/routing.md),
263
+ [Effects and continuations](../concepts/effects-and-continuations.md), and
264
+ [Structured and opaque bodies](../concepts/bodies.md).