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

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 (76) hide show
  1. package/API.md +37 -4
  2. package/CHANGELOG.md +30 -0
  3. package/README.md +4 -3
  4. package/cli-spec.json +1 -1
  5. package/docs/README.md +1 -1
  6. package/docs/architecture/current-contracts.md +108 -7
  7. package/docs/concepts/compilation-and-lowering.md +1 -1
  8. package/docs/concepts/contracts-and-providers.md +2 -2
  9. package/docs/concepts/effects-and-continuations.md +57 -0
  10. package/docs/concepts/package-owned-lowering.md +1 -1
  11. package/docs/concepts/targets-and-hosts.md +10 -2
  12. package/docs/contributing/adding-core-provider.md +1 -1
  13. package/docs/contributing/adding-first-party-lowerer.md +1 -1
  14. package/docs/contributing/package-lowerer-contract.md +2 -2
  15. package/docs/guides/migrating-from-express.md +3 -3
  16. package/docs/guides/routing.md +19 -1
  17. package/docs/maintainers/documentation-deployment.md +4 -4
  18. package/docs/maintainers/documentation-versioning.md +1 -1
  19. package/docs/maintainers/maintainer-charter.md +17 -1
  20. package/docs/maintainers/maintenance-policy.json +34 -3
  21. package/docs/maintainers/maintenance-policy.md +3 -3
  22. package/docs/maintainers/npm-publishing.md +34 -6
  23. package/docs/maintainers/plugin-readiness.json +1 -1
  24. package/docs/maintainers/plugin-readiness.md +1 -1
  25. package/docs/maintainers/release-acceptance.md +51 -8
  26. package/docs/maintainers/release-manifest.md +23 -22
  27. package/docs/maintainers/scope-policy.md +13 -1
  28. package/docs/maintainers/testing.md +47 -1
  29. package/docs/packages/README.md +25 -24
  30. package/docs/packages/assets.md +1 -1
  31. package/docs/packages/crypto.md +8 -1
  32. package/docs/packages/entities.md +1 -1
  33. package/docs/packages/grip.md +1 -1
  34. package/docs/packages/implementation-packages.md +10 -1
  35. package/docs/packages/jwt.md +1 -1
  36. package/docs/packages/provider-fastly.md +29 -3
  37. package/docs/packages/pulse.md +1 -1
  38. package/docs/packages/runtime.md +10 -1
  39. package/docs/packages/s3.md +101 -0
  40. package/docs/preview-scope.md +2 -2
  41. package/docs/reference/cli-spec.json +1 -1
  42. package/docs/reference/cli.md +1 -1
  43. package/docs/reference/compatibility-matrix.md +2 -2
  44. package/docs/reference/diagnostics.md +5 -5
  45. package/docs/reference/documentation-versions.json +19 -3
  46. package/docs/reference/handler-authoring.md +1 -1
  47. package/docs/reference/project-config.md +33 -5
  48. package/docs/reference/project-config.schema.json +70 -7
  49. package/docs/reference/release-manifest.json +37 -23
  50. package/documentation-site.json +8 -1
  51. package/documentation-versions.json +19 -3
  52. package/examples/01-hello-json/README.md +1 -1
  53. package/examples/01-hello-json/package.json +2 -2
  54. package/examples/02-request-schema/README.md +1 -1
  55. package/examples/02-request-schema/package.json +2 -2
  56. package/examples/03-fetch-composition/README.md +1 -1
  57. package/examples/03-fetch-composition/package.json +2 -2
  58. package/examples/05-fastly-capabilities/README.md +2 -2
  59. package/examples/05-fastly-capabilities/package.json +4 -4
  60. package/examples/07-opaque-proxy/README.md +2 -2
  61. package/examples/07-opaque-proxy/package.json +3 -3
  62. package/examples/09-router-lowering/README.md +1 -1
  63. package/examples/09-router-lowering/package.json +3 -3
  64. package/examples/10-entities-tools/package.json +3 -3
  65. package/examples/11-events/README.md +1 -1
  66. package/examples/11-events/package.json +2 -2
  67. package/examples/12-mcp-proxy/README.md +1 -1
  68. package/examples/12-mcp-proxy/package.json +2 -2
  69. package/examples/13-jwt-es256/README.md +1 -1
  70. package/examples/13-jwt-es256/package.json +3 -3
  71. package/package.json +7 -7
  72. package/project-config.schema.json +70 -7
  73. package/release-manifest.json +37 -23
  74. package/src/documentation.js +1 -1
  75. package/src/project-config-schema.js +3 -3
  76. package/src/project-execution.js +64 -30
package/API.md CHANGED
@@ -30,7 +30,7 @@ process, provider SDK, or global network surface behind it.
30
30
  | [`ctx.emit`](#ctxemit) | HTTP and event handlers | One-way, schema-bound event acceptance effect. |
31
31
  | [`ctx.log`](#ctxlog) | HTTP and event handlers | Synchronous thresholded logging. |
32
32
  | [`ctx.config`, `ctx.secret`](#config-and-secrets) | HTTP and event handlers | Explicit configured binding reads. |
33
- | [`ctx.kv(name)`](#kv) | HTTP and event handlers | Bound `get` and `put` storage effects. |
33
+ | [`ctx.kv(name)`](#kv) | HTTP and event handlers | Bound reads, writes, and conditional KV effects (Node reference). |
34
34
  | [`ctx.json`, `ctx.text`, `ctx.response`](#response-builders) | HTTP handlers and middleware | Synchronous response construction. |
35
35
  | `ctx.event` | Event handlers only | Exact event type and immutable validated payload. |
36
36
 
@@ -83,7 +83,7 @@ app.mount('/api', api)
83
83
  export default app
84
84
  ```
85
85
 
86
- `Router` is a compile-time marker. Canonical v2 supports `get`, `head`, `post`, exact paths, named parameters, a trailing wildcard, static mounts, global/path-scoped/mounted middleware, route fallthrough, and error middleware. `ctx.param(name)` returns the matched named parameter inside route handlers.
86
+ `Router` is a compile-time marker. Canonical v2 supports `get`, `head`, `post`, `put`, `patch`, `delete`, exact paths, named parameters, a trailing wildcard, static mounts, global/path-scoped/mounted middleware, route fallthrough, and error middleware. `Pulse` inherits these registrations. `ctx.param(name)` returns the matched named parameter inside route handlers.
87
87
 
88
88
  `next()` is a terminal control transfer. `return next()` advances the normal Router cursor and permanently ends the current handler scope. `return next(error)` enters or advances the error lane. There is no onion-style downstream return or post-`next()` resume. Normal and error exhaustion produce compiler-owned 404 and 500 responses respectively.
89
89
 
@@ -400,7 +400,7 @@ const value = await sessions.get('current')
400
400
  if (value !== undefined) await sessions.put('last', value)
401
401
  ```
402
402
 
403
- The Beta supports `get` and `put`. Store names and keys are
403
+ The existing `get` and `put` operations remain available. Store names and keys are
404
404
  provider-neutral logical bindings. Values are bounded, detached, deeply frozen
405
405
  JSON-compatible trees; accessors, symbols, sparse arrays, repeated references,
406
406
  cycles, class instances, nonfinite numbers, and nested `undefined` are rejected.
@@ -408,6 +408,39 @@ cycles, class instances, nonfinite numbers, and nested `undefined` are rejected.
408
408
  and cross-request lifetime remain provider capabilities rather than properties
409
409
  of the common API.
410
410
 
411
+ The Node reference on JavaScript and Native, and the Fastly Native adapter,
412
+ realize these operations through direct await or keyed `ctx.parallel`:
413
+
414
+ | Method | Result |
415
+ | --- | --- |
416
+ | `getVersioned(key)` | `found` with one observed `value` and opaque `generation`, `not-found`, or `failed` with a reason. |
417
+ | `insertIfAbsent(key, value)` | Atomically creates an absent key. |
418
+ | `compareAndSwap(key, generation, value)` | Atomically replaces the value only when its current generation matches. |
419
+
420
+ Conditional writes return `stored`, `conflict`, `not-stored` with a reason, or
421
+ `unknown` with a reason. `unknown` may have committed; Pulse never automatically
422
+ retries or rebases. A write acknowledgement carries no new generation. An absent
423
+ CAS conflicts. A read may be stale, but its value and token describe the same
424
+ observation. Tokens are bounded opaque strings, never JavaScript numbers or
425
+ application revision counters.
426
+
427
+ Namespaces must be literal bindings; keys, generations, and candidates are runtime
428
+ data. Candidates are snapshotted at admission. Keys are exact Unicode scalar
429
+ strings of 1–1,024 UTF-8 bytes without C0/C1 controls; tokens are 1–256 visible
430
+ ASCII bytes. Values retain the 65,536-byte JSON, depth-64 and 10,000-entry bounds.
431
+ The host owns the ten-second operation deadline, shortened by a request deadline.
432
+ Timeouts before dispatch are `not-stored`; unconfirmed writes after dispatch are
433
+ `unknown`. Request cancellation follows the existing managed lifecycle and
434
+ never implies rollback.
435
+
436
+ The Node realization is an explicit in-memory reference instance, not a durable
437
+ storage guarantee. Fastly Native uses lossless 64-bit generation metadata and
438
+ conditional host operations with bounded readiness and body acquisition. Deployed
439
+ cross-location acceptance remains a separate gate. The Fastly JavaScript SDK is
440
+ incomplete capability mapping and does not define or block
441
+ Pulse's contract. Conditional wire values use the strict
442
+ `{"__pulseKv":1,"value":...}` envelope; legacy raw JSON requires explicit migration.
443
+
411
444
  ## Explicit JSON schemas
412
445
 
413
446
  <!-- pulse-doc-source: examples/02-request-schema/.pulse/config.ts -->
@@ -454,7 +487,7 @@ Older `/pulsewasm` imports are compatibility-only and are isolated in the
454
487
 
455
488
  ## Entities API
456
489
 
457
- `@pulse-compute/entities` is part of the synchronized `1.0.0-beta.1` package
490
+ `@pulse-compute/entities` is part of the synchronized `1.0.0-beta.3` package
458
491
  set. The application surface has two runtime values:
459
492
 
460
493
  ```ts
package/CHANGELOG.md CHANGED
@@ -2,6 +2,36 @@
2
2
 
3
3
  Pulse follows semantic versioning for public releases. The repository begins its public history with the `1.0.0-beta.1` prerelease.
4
4
 
5
+ ## 1.0.0-beta.3 — Beta (2026-09-14)
6
+
7
+ - Fix CLI storage execution on Node Native, Node JavaScript and the Fastly Native local fixture host, including S3 response streams, bindings and conditional KV.
8
+ - Keep the last working Native application available when a development reload fails.
9
+ - Allow bounded npm registry propagation time and publish future releases directly under the `latest` npm tag while retaining the Beta release label.
10
+
11
+ ## 1.0.0-beta.2 — Beta (2026-09-13)
12
+
13
+ This candidate synchronizes the 19-package release catalog and prepares the
14
+ next npm `beta` release:
15
+
16
+ - adds bounded S3-compatible object storage in `@pulse-compute/s3`, backed by
17
+ the Crypto hashing and signing primitives; the Assets contract stays intact;
18
+ - adds conditional KV operations and opaque generation tokens, with explicit
19
+ conflict handling and no non-atomic emulation;
20
+ - propagates explicit JavaScript targets through project analysis, retaining
21
+ resolved static third-party imports and ordinary awaited calls while
22
+ checking Native eligibility independently;
23
+ - clarifies maintainer ownership, target boundaries, evidence requirements,
24
+ and human release authority;
25
+ - links public and internal package listings to npm and preserves the exact
26
+ published beta.1 documentation snapshot alongside the beta.2 documentation.
27
+
28
+ Conditional KV acceptance remains gated separately from the aggregate seal:
29
+ Viceroy 0.21.0 creates a missing key for an existing-generation CAS, contrary to
30
+ the required conflict behavior, and deployed Pulse cross-location acceptance
31
+ is still pending. The standalone live Fastly probe confirms missing-key
32
+ rejection but does not satisfy those Pulse acceptance gates. See
33
+ [`wasm/test/kv/K4.md`](https://github.com/pulse-compute/pulse/blob/16444cc5e116498e1fdf5f1e4815b4b8c3c74349/wasm/test/kv/K4.md) for the evidence and release boundary.
34
+
5
35
  ## 1.0.0-beta.1 — Beta (2026-08-01)
6
36
 
7
37
  The first public Beta establishes a native-first Pulse application contract
package/README.md CHANGED
@@ -6,13 +6,14 @@
6
6
  > **Install directly:** Yes. Install the package globally or as a project development dependency.<br>
7
7
  > **Supported entry points:** `pulse binary`, `@pulse-compute/cli`, `@pulse-compute/cli/workflow`, `@pulse-compute/cli/project-config`, `@pulse-compute/cli/project-execution`, `@pulse-compute/cli/project-config-schema`, `@pulse-compute/cli/diagnostics`, `@pulse-compute/cli/project-config.schema.json`, `@pulse-compute/cli/cli-spec.json`, `@pulse-compute/cli/release-manifest.json`, `@pulse-compute/cli/documentation-versions.json`, `@pulse-compute/cli/documentation-site.json`<br>
8
8
  > **Stability:** Supported Beta workflow and project-configuration contract.<br>
9
- > **Canonical documentation:** [Package guide](https://pulsecompute.io/v1.0.0-beta.1/packages/cli/)
9
+ > **npm:** [`@pulse-compute/cli`](https://www.npmjs.com/package/@pulse-compute/cli)<br>
10
+ > **Canonical documentation:** [Package guide](https://pulsecompute.io/v1.0.0-beta.3/packages/cli/)
10
11
  >
11
- > This release-status block is generated from the synchronized `Pulse 1.0.0-beta.1` package policy.
12
+ > This release-status block is generated from the synchronized `Pulse 1.0.0-beta.3` package policy.
12
13
  <!-- pulse-package-status:end -->
13
14
 
14
15
  The public CLI and conventional `@pulse-compute/pulse` application root are
15
- both part of the synchronized `1.0.0-beta.1` release set. Validate the generated
16
+ both part of the synchronized `1.0.0-beta.3` release set. Validate the generated
16
17
  workflow from the repository or the exact packed acceptance set:
17
18
 
18
19
  ```bash
package/cli-spec.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": "pulse.cli-command-spec.v5",
3
- "cliVersion": "1.0.0-beta.1",
3
+ "cliVersion": "1.0.0-beta.3",
4
4
  "completionShells": [
5
5
  "bash",
6
6
  "zsh",
package/docs/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Pulse documentation
2
2
 
3
- Pulse documentation is organized in layers so you can stop when you have enough detail. The `1.0.0-beta.1` candidate uses async-shaped managed handlers, trusted Pulse effects, a conventional `.pulse/config.ts` workspace, and the `pulse` CLI. The synchronized 18-package release catalog remains the authority for npm availability and support tiers.
3
+ Pulse documentation is organized in layers so you can stop when you have enough detail. The `1.0.0-beta.3` candidate uses async-shaped managed handlers, trusted Pulse effects, a conventional `.pulse/config.ts` workspace, and the `pulse` CLI. The synchronized 18-package release catalog remains the authority for npm availability and support tiers.
4
4
 
5
5
  ## 1. Start and ship a first project
6
6
 
@@ -52,6 +52,14 @@ their own topology while normalizing handler bodies into the same canonical IR.
52
52
  Provider realization begins only after the complete reachable program and its
53
53
  capability requirements are known.
54
54
 
55
+ HTTP Router authoring supports static `get`, `head`, `post`, `put`, `patch`,
56
+ and `delete` registrations, inherited by `Pulse`. The owned Router API registry
57
+ defines compiler admission; topology and lifecycle method catalogs derive from
58
+ that registry. Each verb uses the existing route entry, exact-method dispatch,
59
+ terminal transfer and 404/500 exhaustion contracts. This expands ingress
60
+ registration without changing outgoing fetch methods or the effect/continuation
61
+ ABI.
62
+
55
63
  The compiler also recognizes root-only `Pulse.on(type, { schema }, handler)`
56
64
  declarations as a separate static event topology. Event types and schema IDs
57
65
  must be literal, schema IDs must resolve through the project registry, each
@@ -115,10 +123,10 @@ See [Compilation and lowering](../concepts/compilation-and-lowering.md) and the
115
123
 
116
124
  ## Execution ownership
117
125
 
118
- Host authority is explicit. Fetch, config, secrets, KV, GRIP, assets, and future
119
- host operations enter the program as canonical capabilities or package
120
- operations. Provider SDK objects, ambient process state, and hidden host
121
- namespaces do not enter handler scope.
126
+ Pulse-provided host authority is explicit. Fetch, config, secrets, KV, GRIP,
127
+ assets, and future host operations enter the program as canonical capabilities
128
+ or package operations. Pulse does not expose provider SDK objects, ambient
129
+ process state, or hidden host namespaces through the handler context.
122
130
 
123
131
  Native execution erases managed async notation into explicit effects and
124
132
  single-use continuations. JavaScript targets execute the same application
@@ -133,6 +141,19 @@ authority but do
133
141
  not expose a Request, Response, route parameters, Router transfer, middleware,
134
142
  or response builders.
135
143
 
144
+ Conditional KV is owned by the portable runtime authoring/host contract.
145
+ `kv.getVersioned`, `kv.insertIfAbsent`, and `kv.compareAndSwap` lower through the
146
+ ordinary effect and continuation machinery, including Native value handles.
147
+ The Node reference supplies one explicit local key authority; provider
148
+ preparation and the send boundary remain distinct so unconfirmed writes preserve
149
+ `unknown`. The Native host imports the existing workspace runtime owner rather
150
+ than duplicating its validation, snapshots, limits, or outcome normalization.
151
+ The Fastly Native provider realizes conditional KV directly through its host ABI,
152
+ with lossless generations, conditional options, bounded metadata/body reads and
153
+ readiness deadlines. Its AssemblyScript limits come from the runtime owner; the
154
+ shared corpus checks its wire and outcome semantics. Fastly JavaScript remains
155
+ incomplete capability mapping. Deployed acceptance remains a separate gate. See [conditional KV](../concepts/effects-and-continuations.md#conditional-kv).
156
+
136
157
  `ctx.parallel({ ... })` is the explicit cross-target concurrency form. Router
137
158
  `next()` and `next(error)` are terminal cursor transfers, not onion-style calls:
138
159
  no application code resumes after the transfer. Normal exhaustion produces
@@ -161,6 +182,25 @@ A generally available target can reject an ineligible project. A passing local
161
182
  runtime does not claim that an external deployment, binding, service, or
162
183
  provider control plane is healthy.
163
184
 
185
+ The selected target reaches project linking and handler validation explicitly.
186
+ For `javascript`, resolved static package imports and project-relative helper
187
+ imports remain source-runtime boundaries; they do not acquire Native lowerer
188
+ authority. Canonical application topology, schemas, effect-await rules, graph
189
+ containment and entry lifecycle checks still apply. An ordinary imported async
190
+ call may be awaited in a JavaScript handler. Native compilation continues to
191
+ reject unsupported imports and awaits, including when graph eligibility is
192
+ requested in record-only mode.
193
+
194
+ JavaScript compilation returns canonical inspection metadata without an
195
+ executable normalized generator. The provider's graph-backed loader and source
196
+ packager execute the original module closure with its JavaScript async semantics.
197
+ Inspection describes recognized Pulse effects; it does not infer effects inside
198
+ ordinary dependency implementations or certify their isolation. An ordinary
199
+ JavaScript import gains no compiler/lowerer authority or Native guest sandbox
200
+ guarantee. Native inspection compiles the source
201
+ independently under Native rules. Its failure is advisory for a selected
202
+ JavaScript target; `pulse compile` still requires a real Native compilation.
203
+
164
204
  Provider packages own descriptors, configuration normalization, local
165
205
  execution, target generation, source packaging, deployment bindings, and target
166
206
  support policy. The compiler owns the neutral bootstrap, contract validation,
@@ -198,6 +238,18 @@ guest-link packaging authorization have already been checked. It does not
198
238
  contain a TypeScript AST/service, compiler cache, builder, mutable manifest,
199
239
  compiled-program object, raw target option bag, or alternate target.
200
240
 
241
+ CLI Native test/dev execution that needs guest crypto or conditional KV uses
242
+ an optional provider-owned `prepareNativeExecution` driver hook. It receives the
243
+ same immutable, validated invocation with action `execute-native` and returns a
244
+ local request executor. The CLI never substitutes another provider's host.
245
+ Node executes the compiled neutral Wasm with its provider adapter. Fastly
246
+ realizes its own Native artifact and runs the existing fixture ABI, including
247
+ the conditional-KV authority. Its result identifies the artifact hash and fixture
248
+ kind; unavailable effect telemetry is reported as such. This does not establish
249
+ Viceroy or deployed Fastly acceptance. S3 fixtures preserve raw response streams
250
+ inside the provider transport while ordinary fetch retains its opaque response
251
+ contract. Dev retains a last-good Native executor if recompilation fails.
252
+
201
253
  Native realization and JavaScript source packaging are normalized into
202
254
  versioned, data-only results before the CLI consumes them. Provider packaging
203
255
  must report the same artifact identity authorized by the final guest audit.
@@ -295,7 +347,7 @@ without moving package semantics into the compiler or widening the trust model.
295
347
 
296
348
  ## JWT verification
297
349
 
298
- The synchronized `1.0.0-beta.1` JWT/crypto packages compose
350
+ The synchronized `1.0.0-beta.3` JWT/crypto packages compose
299
351
  `@pulse-compute/jwt` over the lower-level, provider-neutral verification
300
352
  contract owned by `@pulse-compute/crypto`. The executable algorithm set is
301
353
  HS256 and ES256. Crypto verifies a MAC or signature over caller-supplied bytes
@@ -312,7 +364,7 @@ objects do not merge. An empty declaration enables no algorithms. An unknown,
312
364
  missing, unavailable, or failed realization stops with a normalized diagnostic
313
365
  and never authorizes fallback.
314
366
 
315
- JavaScript targets select `runtime-builtin` and use Web Crypto with explicit
367
+ For JWT verification, JavaScript targets select `runtime-builtin` and use Web Crypto with explicit
316
368
  HMAC/SHA-256 or ECDSA/P-256/SHA-256 parameters. The crypto boundary receives a
317
369
  normalized 64-byte P-256 point; its JavaScript adapter validates that point and
318
370
  constructs the runtime-private JWK used for import. Native HS256 selects
@@ -321,6 +373,41 @@ primary module, while Native ES256 selects the audited
321
373
  `guest-linked:pulse-es256-rustcrypto-p256` unit. Neither algorithm retries a
322
374
  different realization.
323
375
 
376
+ S3 operations require exact `SHA-256` and `HMAC-SHA256` selection. Native
377
+ composes the same Crypto-owned source once; Node JavaScript explicitly selects
378
+ Crypto's `runtime-builtin` Web Crypto byte realization through the trusted
379
+ `@pulse-compute/crypto/provider` export. Both return 32-byte results, cap data
380
+ at 32 KiB and HMAC keys at 8 KiB, and snapshot and wipe staging inputs. Native
381
+ also checks guest memory ranges. JWT verification retains its separate limits.
382
+ No target probes or falls back to a different realization.
383
+
384
+ The supported-extension `@pulse-compute/s3` package owns `head`, `getText` and `putText`,
385
+ literal binding/options authority, runtime key/text lowering, SigV4 composition
386
+ and bounded results. Node and Fastly own fixed endpoint/bucket/region mappings,
387
+ credential lookup, deadlines and transport. Fastly requires a static backend.
388
+ Reads and writes bypass cache, disable decompression and redirects, preserve
389
+ exact bytes and do not retry. PUT distinguishes pre-dispatch failure and
390
+ complete rejection (`not-stored`) from unconfirmed dispatched writes (`unknown`).
391
+ Only a complete 200 acknowledgement with a bounded empty body yields `stored`;
392
+ its digest describes sent bytes, not durability. Request cancellation retains
393
+ existing lifecycle behavior and does not fabricate a typed S3 outcome. Fastly
394
+ pending requests lack a cancel ABI; invocation termination owns their release.
395
+
396
+ One canonical consumer exercises Node Native, Node JavaScript and Fastly Native
397
+ PUT/HEAD/GET, integrity, bounded acknowledgements and cancellation. Fastly Native
398
+ runs compiled Wasm against a host ABI fixture. This is local evidence, not live
399
+ Object Storage proof. Fastly JavaScript remains ineligible: its SDK projects raw
400
+ response headers, losing multiplicity and aggregate-size evidence required by
401
+ O1. The provider-specific limitation is documented in `wasm/test/s3/O3.md` and
402
+ does not gate supported targets. O4 adds S3 to the synchronized release package
403
+ set and repeats the three-target read/write corpus against isolated exact
404
+ tarballs, including package-owned lowering. These are local candidate checks;
405
+ live origin acceptance follows T2. Assets alignment remains separate.
406
+
407
+ Package redaction declarations survive Handler IR projection into the Native
408
+ plan. Native host effect traces omit declared private payloads and results;
409
+ applications still control their own response and logging use of returned data.
410
+
324
411
  All four target classes—Node JavaScript, Fastly JavaScript, Node Native, and
325
412
  Fastly Native—execute the same HS256 semantics. ES256 adds exact default and
326
413
  size-oriented Native artifact cells, producing a six-cell 38-case matrix:
@@ -341,7 +428,7 @@ publish, promote, deploy, or activate the release.
341
428
 
342
429
  ## Support, release, and authority
343
430
 
344
- Pulse `1.0.0-beta.1` is a Beta intended for the `beta` channel.
431
+ Pulse `1.0.0-beta.3` is a Beta intended for the `beta` channel.
345
432
  Documented, evidence-backed behavior is intentional, but public surfaces may
346
433
  change deliberately before a compatibility-bearing release. Unsupported
347
434
  behavior fails explicitly, historical and implementation subpaths gain no
@@ -361,6 +448,20 @@ architecture, merge, repository-setting, and release authority. Codex may
361
448
  analyze, review, reproduce, and prepare bounded patches; deterministic checks
362
449
  remain authoritative even when Codex is unavailable.
363
450
 
451
+ A protected-path match requires a boundary declaration and review; it does not
452
+ establish that the patch changes that boundary's semantics. Human direction
453
+ already supplied for a bounded task covers its necessary implementation, tests,
454
+ canonical documentation, regeneration and PR preparation. The PR records that
455
+ direction and any remaining decision. A new semantic or authority change beyond
456
+ the authorized scope requires new direction. Implementation approval does not
457
+ transfer merge, publication, deployment or self-approval authority.
458
+
459
+ Validation claims distinguish injected hosts, local Compute engines, standalone
460
+ live probes and deployed Pulse artifacts. SDK capability mappings and observed
461
+ provider discrepancies do not redefine Pulse's contract. Required acceptance
462
+ gates remain separate from the aggregate release command; their status and any
463
+ human-directed policy changes must be explicit before claiming release readiness.
464
+
364
465
  See the [maintainer charter](../maintainers/maintainer-charter.md),
365
466
  [release acceptance](../maintainers/release-acceptance.md),
366
467
  [npm publishing](../maintainers/npm-publishing.md), and
@@ -408,7 +408,7 @@ generic loader handles reachable-graph discovery and trusted invocation. Older
408
408
  `/pulsewasm` imports are isolated in the
409
409
  [compatibility migration guide](../guides/compatibility-imports.md).
410
410
 
411
- In Pulse `1.0.0-beta.1`, package-owned builders must declare `compiler.trust: 'first-party'` and ship in the synchronized release set. This is an internal contributor mechanism, not a general third-party plugin API. See [Add a first-party package-owned lowerer](../contributing/adding-first-party-lowerer.md).
411
+ In Pulse `1.0.0-beta.3`, package-owned builders must declare `compiler.trust: 'first-party'` and ship in the synchronized release set. This is an internal contributor mechanism, not a general third-party plugin API. See [Add a first-party package-owned lowerer](../contributing/adding-first-party-lowerer.md).
412
412
 
413
413
  ## Provider lowering is a second contract
414
414
 
@@ -38,7 +38,7 @@ GRIP uses the same split. `isWebSocket`, `subscribe`, and `handoff` are pure HTT
38
38
 
39
39
  ## Provider selection
40
40
 
41
- Pulse `1.0.0-beta.1` has three provider driver identifiers:
41
+ Pulse `1.0.0-beta.3` has three provider driver identifiers:
42
42
 
43
43
  | Provider | Local execution | Deployable build | Purpose |
44
44
  |---|---:|---:|---|
@@ -96,7 +96,7 @@ For Fastly, `pulse build` additionally emits a real Compute target. The explicit
96
96
 
97
97
  ## Current extension boundary
98
98
 
99
- There is no automatic provider plugin registry in `1.0.0-beta.1`. Configuration
99
+ There is no automatic provider plugin registry in `1.0.0-beta.3`. Configuration
100
100
  selects a bare host ID, internal `none`, or an exact scoped project-installed
101
101
  package name. Bare IDs resolve by the `@pulse-compute/provider-<id>` convention.
102
102
  A package is loadable only when selected and when it exports the versioned
@@ -241,3 +241,60 @@ pulse test ./my-app --json
241
241
  - [Fetching and composing data](../guides/fetching-and-composition.md)
242
242
  - [Project configuration](../reference/project-config.md)
243
243
  - [Troubleshooting](../guides/troubleshooting.md)
244
+
245
+ ## Conditional KV
246
+
247
+ `ctx.kv<T>('name')` exposes `getVersioned(key)`, `insertIfAbsent(key, value)`, and
248
+ `compareAndSwap(key, generation, value)` as direct awaited or keyed parallel
249
+ effects. The Node reference implements the contract for JavaScript and compiled
250
+ Native control flow. Fastly Native implements it through direct KV hostcalls;
251
+ Fastly JavaScript conditional KV remains explicitly incomplete.
252
+
253
+ The condition and mutation are atomic at one key's authority. A versioned read
254
+ returns a value and an opaque generation from the same observation, which may be
255
+ stale. Generations are strings, not numbers, hashes or application versions.
256
+ Create conflicts when present; CAS conflicts when absent or when its token is
257
+ stale. Equal-byte replacement is still a write and changes its generation.
258
+ Existing unconditional `get` and `put` remain available.
259
+
260
+ A write returns `stored`, `conflict`, `not-stored` with a bounded reason, or
261
+ `unknown` with a bounded reason. Unknown may have committed. A complete explicit
262
+ provider rejection establishes no write; an exception from a send primitive
263
+ does not. Pulse does not retry, reread-and-rebase, or invent a generation from a
264
+ write acknowledgement. A subsequent missing or stale read cannot resolve an
265
+ ambiguous write by itself.
266
+
267
+ Admission detaches and freezes the candidate before provider preparation. The
268
+ host's monotonic ten-second deadline starts at admission and is shortened by an
269
+ owning request deadline. Preparation may resolve bindings and stage data but
270
+ cannot send. Entry into the returned provider primitive marks dispatch even if
271
+ it throws synchronously. Timeout before that boundary is `not-stored`; timeout
272
+ or transport loss after it is `unknown`. Cancellation suppresses delivery to an
273
+ inactive execution and records whether dispatch occurred; it promises no rollback.
274
+
275
+ Exact keys are bounded Unicode scalar strings; generations are bounded visible
276
+ ASCII strings. Values retain the portable KV JSON limits. Conditional storage
277
+ uses a strict UTF-8 JSON envelope with exactly `__pulseKv: 1` and `value`, rejecting
278
+ duplicate members, invalid values, and oversized bodies. The wrapper is not
279
+ recursively unwrapped. Legacy raw JSON requires explicit migration. Keys, tokens,
280
+ and values are omitted or redacted from runtime evidence and managed errors;
281
+ application responses are not silently rewritten.
282
+
283
+ Node reference instances retain nonreused generation identities for their own
284
+ lifetime. Host code can explicitly reuse one reference across requests and target
285
+ runners; independent instances isolate their state. Deterministic identities,
286
+ clocks, and failure hooks belong to host evidence, not handler authority. This
287
+ local model does not establish durability, global visibility, cross-key
288
+ transactions, or a portable physical-delete/recreate guarantee. Fastly SDK
289
+ limitations cannot redefine this contract or gate other targets.
290
+
291
+ Fastly Native preserves all 64 generation bits in an opaque string. ADD and
292
+ generation-conditioned overwrite remain distinct operations, including an explicit
293
+ condition for zero bits. The adapter stages the complete envelope before dispatch,
294
+ uses monotonic deadlines and readiness selection before pending waits and body
295
+ reads, and closes acquired bodies. It accepts up to 65,560 wire bytes, including
296
+ wrapper overhead. Provider key restrictions return `invalid-key` without changing
297
+ the key. Pending KV operations have no cancellation hostcall; an expired operation
298
+ is abandoned to invocation teardown and may still commit. Host termination never
299
+ resumes an inactive handler. Local Wasm evidence is separate from K4's deployed
300
+ cross-location acceptance.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Package-owned lowering lets a synchronized Pulse package extend the canonical compiler with narrow, statically recognized operations while keeping domain rules out of compiler core.
4
4
 
5
- The synchronized `1.0.0-beta.1` release uses this pattern for Assets, GRIP,
5
+ The synchronized `1.0.0-beta.3` release uses this pattern for Assets, GRIP,
6
6
  JWT, and Entities.
7
7
  It is a **trusted first-party synchronization mechanism**, not a public
8
8
  registry that executes arbitrary npm compiler plugins.
@@ -6,9 +6,17 @@ branches on. The release distinguishes current execution proof from forward
6
6
  host work so architectural direction does not become an accidental support
7
7
  claim.
8
8
 
9
+ An explicit JavaScript profile can retain resolved static package imports and
10
+ project-relative helpers, including awaited calls into ordinary JavaScript
11
+ dependencies. Pulse checks the canonical application surface and packages its
12
+ original source graph. Native eligibility is reported separately and does not
13
+ block JavaScript execution. Unsupported dynamic module boundaries and missing
14
+ `await` on Pulse effects still fail validation. `pulse compile` continues to
15
+ require Native-compatible source; use `pulse build` for a JavaScript package.
16
+
9
17
  ## Current Beta targets
10
18
 
11
- `1.0.0-beta.1` exercises four explicit modes through one conformance corpus:
19
+ `1.0.0-beta.3` exercises four explicit modes through one conformance corpus:
12
20
 
13
21
  | Host | Target | Current release status | Build shape |
14
22
  |---|---|---|---|
@@ -37,7 +45,7 @@ adapter, lifecycle, conformance evidence, and package claim.
37
45
  The [ESP32 reference host](https://github.com/pulsecompute/pulse-esp32-host)
38
46
  tests whether the event/effect/continuation model remains useful without a
39
47
  JavaScript fallback, abundant memory, or an HTTP-centered lifecycle. It is a
40
- boundary witness, not a `1.0.0-beta.1` provider or compatibility promise. The
48
+ boundary witness, not a `1.0.0-beta.3` provider or compatibility promise. The
41
49
  [architecture vision](../architecture/vision.md#esp32-as-a-boundary-witness)
42
50
  describes the intended host-owned interrupt queue and non-reentrant Wasm entry.
43
51
 
@@ -75,7 +75,7 @@ Descriptors are normalized by the shared provider contract. A conceptual descrip
75
75
  ```js
76
76
  const EXAMPLE_PROVIDER_DESCRIPTOR = createProviderDescriptor({
77
77
  id: 'example',
78
- providerVersion: '1.0.0-beta.1',
78
+ providerVersion: '1.0.0-beta.3',
79
79
  package: '@pulse-compute/provider-example',
80
80
  runtime: 'pulse.canonical-example-runtime.v1',
81
81
  buildTarget: 'example-edge',
@@ -11,7 +11,7 @@ Start with [Pulse-aware package authoring](./pulse-aware-packages.md) to decide
11
11
  whether the package needs Native lowering at all. Ordinary target-compatible
12
12
  JavaScript packages do not require a compiler builder.
13
13
 
14
- > **Scope and trust boundary:** Pulse `1.0.0-beta.1` executes package-owned compiler builders only when their manifest declares `compiler.trust: 'first-party'` and the package is part of the synchronized release set. This is a core-repository contributor workflow, **not an external plugin** interface or a supported third-party plugin API. An external package cannot self-register arbitrary compiler code.
14
+ > **Scope and trust boundary:** Pulse `1.0.0-beta.3` executes package-owned compiler builders only when their manifest declares `compiler.trust: 'first-party'` and the package is part of the synchronized release set. This is a core-repository contributor workflow, **not an external plugin** interface or a supported third-party plugin API. An external package cannot self-register arbitrary compiler code.
15
15
 
16
16
  A package-owned lowerer lets one release package define a narrow TypeScript facade and keep its domain-specific static validation outside compiler core. GRIP is the clearest current example; assets is the second implementation proving that the generic loader is not GRIP-specific.
17
17
 
@@ -8,7 +8,7 @@ pulse-doc-meta:end -->
8
8
  # Package lowerer contract reference
9
9
 
10
10
  This reference describes the internal first-party lowerer protocol used by the
11
- synchronized `1.0.0-beta.1` release. It documents current repository
11
+ synchronized `1.0.0-beta.3` release. It documents current repository
12
12
  interfaces; it is not a third-party plugin compatibility promise. Package
13
13
  availability remains owned by the release catalog.
14
14
 
@@ -370,7 +370,7 @@ Package lowerer code must not choose `node.*`, `fastly.*`, backend names, store
370
370
 
371
371
  ## Compatibility status
372
372
 
373
- This protocol is synchronized inside the `1.0.0-beta.1` release set. It can change with compiler implementation needs. Only explicitly documented application facades carry the package support promise.
373
+ This protocol is synchronized inside the `1.0.0-beta.3` release set. It can change with compiler implementation needs. Only explicitly documented application facades carry the package support promise.
374
374
 
375
375
  A public external lowerer API would require a new contract that addresses trust, sandboxing, provenance, protocol negotiation, resource limits, lifecycle support, and semver compatibility.
376
376
 
@@ -117,12 +117,12 @@ normal lane ends as `404 Not Found`; an unhandled error lane ends as
117
117
 
118
118
  The Beta Router supports:
119
119
 
120
- - `use`, `get`, `head`, `post`, `mount`, and `error`;
120
+ - `use`, `get`, `head`, `post`, `put`, `patch`, `delete`, `mount`, and `error`;
121
121
  - exact paths, named `:parameters`, and a trailing `*` wildcard;
122
122
  - statically declared, acyclic mounted routers;
123
123
  - first-match order and explicit route fallthrough.
124
124
 
125
- It does not support `put`, `patch`, `delete`, regular-expression routes,
125
+ It does not support `options`, `trace`, `connect`, regular-expression routes,
126
126
  runtime route registration, Express Router plugins, or hidden server lifecycle
127
127
  hooks. Keep an unsupported endpoint on its existing service or redesign it
128
128
  before moving that endpoint into Pulse; selecting a JavaScript target does not
@@ -165,7 +165,7 @@ Pulse never changes targets or falls back automatically.
165
165
 
166
166
  1. Inventory routes, methods, middleware order, error paths, body parsing, and
167
167
  ambient host dependencies.
168
- 2. Move one supported `GET`, `HEAD`, or `POST` route to a statically declared
168
+ 2. Move one supported `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, or `DELETE` route to a statically declared
169
169
  `Pulse` application.
170
170
  3. Replace response mutation with returned `ctx.json`, `ctx.text`, or
171
171
  `ctx.response` results.
@@ -76,7 +76,7 @@ export default app
76
76
 
77
77
  - `new Router()` with a default-exported root router;
78
78
  - `use(handler)` and `use(path, handler)` middleware;
79
- - `get`, `head`, and `post` registrations;
79
+ - `get`, `head`, `post`, `put`, `patch`, and `delete` registrations;
80
80
  - exact paths, named `:parameters`, and a trailing `*` wildcard;
81
81
  - static acyclic `mount` composition;
82
82
  - named or inline async-shaped route handlers using `(ctx)` or `(ctx, next)`;
@@ -87,6 +87,24 @@ export default app
87
87
 
88
88
  Every Router handler uses the normal canonical context. Fetches, schemas, config, secrets, KV, opaque responses, and trusted package effects lower into the same native execution plan as single-handler authoring.
89
89
 
90
+ `Pulse` inherits the same route registration methods. Each registration matches
91
+ its exact HTTP method; a method mismatch advances the route cursor and normal
92
+ exhaustion remains `404`. There is no automatic `OPTIONS` or `405` response.
93
+ Ingress route methods do not widen the separate outbound `ctx.fetch` contract.
94
+
95
+ The `catalog-router-parity` conformance task exercises the original Catalog
96
+ consumer probe and all 14 of its PUT/PATCH/DELETE operations with their existing
97
+ methods and paths. Its shared cases check mounted parameters, request text,
98
+ middleware state, exact method misses, registration order, terminal fallthrough,
99
+ 404 exhaustion and handled errors on Node/Fastly JavaScript and Native. Native
100
+ lanes execute compiled Wasm; Fastly evidence uses local provider emulation and
101
+ the target ABI mock host, not a deployed service. The fixtures establish routing
102
+ acceptance only; they do not implement Catalog persistence or authorization.
103
+
104
+ ```sh
105
+ node wasm/scripts/run-wasm-tests.cjs --task catalog-router-parity --no-report
106
+ ```
107
+
90
108
  ## `next()` is a terminal transfer
91
109
 
92
110
  `next()` is not an onion-style callback. It is a compiler-visible control transfer:
@@ -31,7 +31,7 @@ GitHub Pages deployment is no longer part of the repository workflow. The releas
31
31
 
32
32
  ## Object classes
33
33
 
34
- The `1.0.0-beta.1` layout is:
34
+ The `1.0.0-beta.3` layout is:
35
35
 
36
36
  ```text
37
37
  <bucket>/pulse/
@@ -41,8 +41,8 @@ The `1.0.0-beta.1` layout is:
41
41
  versions.json mutable
42
42
  site-manifest.json mutable
43
43
  public-site-manifest.json mutable
44
- v1.0.0-beta.1/** immutable
45
- deployments/v1.0.0-beta.1.json immutable receipt
44
+ v1.0.0-beta.3/** immutable
45
+ deployments/v1.0.0-beta.3.json immutable receipt
46
46
  ```
47
47
 
48
48
  The exact-version tree is the archival release. Root and `latest` are convenience surfaces promoted only after exact-version verification and matching npm package verification.
@@ -72,7 +72,7 @@ npm run docs:deployment:prepare
72
72
  npm run docs:deployment:verify
73
73
  ```
74
74
 
75
- `.pulse-documentation-deployment/documentation-deployment-manifest.json` records every object key, local source, byte length, SHA-256, content type, cache class, mutability, source commit, public documentation route, and independent storage prefix. Its deterministic deployment receipt records the complete generated-site digest and the exact-version object inventory and tree digest for `deployments/v1.0.0-beta.1.json`. Candidate verification rejects any root or site file outside that sealed inventory.
75
+ `.pulse-documentation-deployment/documentation-deployment-manifest.json` records every object key, local source, byte length, SHA-256, content type, cache class, mutability, source commit, public documentation route, and independent storage prefix. Its deterministic deployment receipt records the complete generated-site digest and the exact-version object inventory and tree digest for `deployments/v1.0.0-beta.3.json`. Candidate verification rejects any root or site file outside that sealed inventory.
76
76
 
77
77
  A local adapter exercised by `npm run publication:check` proves:
78
78
 
@@ -26,7 +26,7 @@ The homepage and exact current documentation load the same assets under `/v<vers
26
26
  The canonical URL for this release begins with:
27
27
 
28
28
  ```text
29
- https://pulsecompute.io/v1.0.0-beta.1/
29
+ https://pulsecompute.io/v1.0.0-beta.3/
30
30
  ```
31
31
 
32
32
  Diagnostics, package status blocks, and package metadata use exact-version URLs. This prevents a diagnostic emitted by an older CLI from silently opening instructions for a newer contract.