redweb 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/CHANGELOG.md +166 -9
  2. package/README.md +177 -523
  3. package/bin/redweb.js +11 -20
  4. package/client.d.ts +7 -2
  5. package/config/tsconfig.json +14 -14
  6. package/contract.d.ts +45 -0
  7. package/contract.js +5 -0
  8. package/docs/ACTION_INPUT_VERIFICATION.md +96 -0
  9. package/docs/ADMISSION_TIMEOUT_VERIFICATION.md +69 -0
  10. package/docs/AGENT_ACCESS.md +35 -0
  11. package/docs/AGENT_EVALUATION.md +58 -0
  12. package/docs/AGENT_READY_ACCEPTANCE.md +763 -0
  13. package/docs/APPLICATION_RECORDER_VERIFICATION.md +50 -0
  14. package/docs/BENCHMARK_VERIFICATION.md +307 -0
  15. package/docs/BROWSER_OWNER_VERIFICATION.md +191 -0
  16. package/docs/CLI.md +116 -0
  17. package/docs/CLIENT_DEVELOPMENT.md +152 -0
  18. package/docs/CLIENT_POLISH_VERIFICATION.md +282 -0
  19. package/docs/COVERAGE_COUNTER_VALIDATION.md +109 -0
  20. package/docs/COVERAGE_SCOPE_AUDIT.md +1183 -0
  21. package/docs/DEVELOPMENT.md +79 -0
  22. package/docs/DIAGNOSTIC_COMPATIBILITY.md +76 -0
  23. package/docs/DOCUMENTATION.md +37 -0
  24. package/docs/FEEDBACK_COMMAND_VERIFICATION.md +228 -0
  25. package/docs/GETTING_STARTED.md +58 -0
  26. package/docs/JSX_PERFORMANCE_VERIFICATION.md +59 -0
  27. package/docs/LIVE_HTML.md +169 -21
  28. package/docs/LIVE_HTML_LOAD_VERIFICATION.md +98 -0
  29. package/docs/MIGRATION.md +28 -0
  30. package/docs/MULTIPLAYER_OPERATIONS.md +26 -4
  31. package/docs/ORIGINAL_RECOVERY_VERIFICATION.md +100 -0
  32. package/docs/PACKAGED_EXAMPLE_VERIFICATION.md +126 -0
  33. package/docs/POLISH_RELEASE_CHECKPOINT.md +91 -0
  34. package/docs/PROCESS_CLEANUP_OBSERVATION.md +61 -0
  35. package/docs/PROCESS_REAPING_VERIFICATION.md +30 -0
  36. package/docs/PRODUCTION_READINESS.md +11 -2
  37. package/docs/RECOVERY_CLIENT_HEAP.md +201 -0
  38. package/docs/RECOVERY_CODE_ATTRIBUTION.md +174 -0
  39. package/docs/RECOVERY_CODE_CENSUS.md +158 -0
  40. package/docs/RECOVERY_COMPARISON.md +103 -0
  41. package/docs/RECOVERY_DEOPTIMIZATION.md +169 -0
  42. package/docs/RECOVERY_FOLLOWUP_SPIKE.md +147 -0
  43. package/docs/RECOVERY_INVESTIGATION.md +229 -0
  44. package/docs/RECOVERY_RUNTIME_CONTROLS.md +181 -0
  45. package/docs/RELEASE_TRUST.md +58 -0
  46. package/docs/ROOM_AUTHORIZATION.md +49 -0
  47. package/docs/RUNTIME_DIAGNOSTICS.md +78 -0
  48. package/docs/SERVER_RECOVERY_CANDIDATE.md +185 -0
  49. package/docs/SOAK_ROTATION_OBSERVATION.md +160 -0
  50. package/docs/SOAK_VERIFICATION.md +154 -0
  51. package/docs/SOCKET_CONTRACTS.md +39 -0
  52. package/docs/SPLIT_RECOVERY_COVERAGE.md +83 -0
  53. package/docs/SPLIT_RECOVERY_ERROR_HANDLING.md +67 -0
  54. package/docs/STARTER_COORDINATOR_VERIFICATION.md +112 -0
  55. package/docs/STARTER_LIFECYCLE_VERIFICATION.md +75 -0
  56. package/docs/STARTER_REPORT_RETENTION.md +73 -0
  57. package/docs/VERIFICATION_EVIDENCE.md +2 -0
  58. package/docs/generated.json +2154 -0
  59. package/docs/guides/chatroom.md +27 -0
  60. package/docs/guides/http-websocket.md +28 -0
  61. package/docs/guides/jsx-without-react.md +26 -0
  62. package/docs/guides/realtime-dashboard.md +29 -0
  63. package/docs/guides/typed-websockets.md +26 -0
  64. package/docs/reference.json +1207 -0
  65. package/docs/snippets/room-access.tsx +51 -0
  66. package/docs/topics.json +21 -0
  67. package/examples/live-html/chatroom.js +207 -268
  68. package/examples/live-html/chatroom.tsx +167 -0
  69. package/examples/live-html/jsx-page.js +1 -1
  70. package/examples/live-html/jsx-page.tsx +1 -1
  71. package/examples/live-html/tsconfig.json +8 -7
  72. package/index.d.ts +170 -45
  73. package/index.js +2 -0
  74. package/jsx-dev-runtime.js +2 -2
  75. package/jsx-runtime.d.ts +7 -2
  76. package/package.json +88 -7
  77. package/recipes/add/artifact.test.cjs +57 -0
  78. package/recipes/add/live.tsx +18 -0
  79. package/recipes/add/socket-route.ts +24 -0
  80. package/recipes/chat/README.md +22 -0
  81. package/recipes/chat/app.test.cjs +105 -0
  82. package/recipes/chat/app.tsx +9 -0
  83. package/recipes/dashboard/README.md +43 -0
  84. package/recipes/dashboard/admin.ts +21 -0
  85. package/recipes/dashboard/app.css +16 -0
  86. package/recipes/dashboard/app.test.cjs +450 -0
  87. package/recipes/dashboard/app.tsx +86 -0
  88. package/recipes/dashboard/auth.ts +80 -0
  89. package/recipes/dashboard/cards.tsx +102 -0
  90. package/recipes/dashboard/rate-window.test.cjs +17 -0
  91. package/recipes/dashboard/store.ts +120 -0
  92. package/recipes/http-ws/README.md +11 -0
  93. package/recipes/http-ws/app.test.cjs +92 -0
  94. package/recipes/http-ws/app.tsx +36 -0
  95. package/recipes/realtime/README.md +8 -0
  96. package/recipes/realtime/app.test.cjs +15 -0
  97. package/recipes/realtime/app.tsx +28 -0
  98. package/recipes/shared/README.md +40 -0
  99. package/recipes/shared/app.css +8 -0
  100. package/recipes/shared/copy-assets.cjs +8 -0
  101. package/recipes/shared/network.cjs +59 -0
  102. package/recipes/shared/run-app.test.cjs +158 -0
  103. package/recipes/shared/run-app.ts +50 -0
  104. package/recipes/site/README.md +4 -0
  105. package/recipes/site/app.test.cjs +19 -0
  106. package/recipes/site/app.tsx +25 -0
  107. package/recipes/socket/README.md +39 -0
  108. package/recipes/socket/app.test.cjs +85 -0
  109. package/recipes/socket/app.tsx +30 -0
  110. package/recipes/socket/contract.ts +12 -0
  111. package/recipes/socket/handlers.ts +40 -0
  112. package/src/OwnedServerLifecycle.js +66 -0
  113. package/src/access/AccessPolicy.js +37 -0
  114. package/src/access/AuthenticationFailure.js +13 -0
  115. package/src/access/RequestFailure.js +33 -0
  116. package/src/access/failure-codes.json +25 -0
  117. package/src/async/BoundedOperation.js +62 -0
  118. package/src/cli/ActionReferences.js +193 -0
  119. package/src/cli/AdditionLayout.js +140 -0
  120. package/src/cli/FilePlan.js +94 -0
  121. package/src/cli/ProjectAddition.js +60 -0
  122. package/src/cli/ProjectConfig.js +26 -0
  123. package/src/cli/ProjectDoctor.js +112 -0
  124. package/src/cli/ProjectInitializer.js +20 -30
  125. package/src/cli/SourceInspector.js +207 -0
  126. package/src/cli/StaticSource.js +192 -0
  127. package/src/cli/arguments.js +62 -0
  128. package/src/cli/formatCommand.js +10 -0
  129. package/src/cli/run.js +57 -0
  130. package/src/cli/templates.js +86 -87
  131. package/src/context/RequestSnapshot.js +41 -0
  132. package/src/dataProperty.js +11 -0
  133. package/src/development/DevelopmentPageManager.js +48 -0
  134. package/src/development/Inspection.js +104 -0
  135. package/src/development/ObservedRenderer.js +42 -0
  136. package/src/development/description.js +35 -0
  137. package/src/development/loopbackRequest.js +27 -0
  138. package/src/development/refreshBrowser.js +96 -0
  139. package/src/development/refreshStyles.js +9 -0
  140. package/src/development/settings.js +17 -0
  141. package/src/docs/Documentation.js +182 -0
  142. package/src/htmx/ActionDefinition.js +44 -0
  143. package/src/htmx/Jsx.js +24 -8
  144. package/src/htmx/LiveHtmlServer.js +41 -19
  145. package/src/htmx/LivePage.js +63 -13
  146. package/src/htmx/PageIdentity.js +32 -0
  147. package/src/htmx/PageLifetime.js +37 -0
  148. package/src/htmx/PageManager.js +203 -74
  149. package/src/htmx/ReactiveRenderer.js +241 -0
  150. package/src/htmx/StaticExporter.js +1 -1
  151. package/src/htmx/TemplateRenderer.js +13 -7
  152. package/src/htmx/browserRuntime.js +2 -93
  153. package/src/htmx/metadata.js +19 -7
  154. package/src/validation/ActionInputError.js +12 -0
  155. package/src/validation/SchemaValidator.js +38 -0
  156. package/src/ws/AdmissionPolicy.js +24 -23
  157. package/src/ws/BaseSocketServer.js +53 -38
  158. package/src/ws/ContractValidationError.js +12 -0
  159. package/src/ws/HeartbeatMonitor.js +19 -7
  160. package/src/ws/ProtocolPolicy.js +1 -1
  161. package/src/ws/RoomAccess.js +82 -0
  162. package/src/ws/RoomRegistry.js +56 -6
  163. package/src/ws/RouteRuntime.js +56 -10
  164. package/src/ws/SocketContract.js +112 -0
  165. package/src/ws/SocketRoute.js +18 -0
  166. package/src/ws/protocol-schema.json +6 -1
  167. package/examples/live-html/chatroom.ts +0 -217
@@ -0,0 +1,147 @@
1
+ # Deferred runtime-recovery investigation
2
+
3
+ Status: deferred research, not a resolved defect or a recovery waiver.
4
+
5
+ The maintainer subsequently authorized development, review and adoption of the
6
+ server-focused check documented in `docs/SERVER_RECOVERY_CANDIDATE.md`. It now
7
+ blocks CI; the original command remains unchanged as a visible non-blocking
8
+ diagnostic. This changes the acceptance contract, not the historical results or
9
+ the unresolved runtime explanation. No historical bounded comparison is repeated.
10
+
11
+ The one-original/one-split Ubuntu comparison is now complete. See
12
+ [its results and contrary ordinary-CI evidence](RECOVERY_COMPARISON.md).
13
+ The stopping rule remains in effect: no repeat research measurement is needed.
14
+
15
+ The maintainer prioritized finishing Redweb's release work over further open-ended
16
+ runtime investigation. Exact V8 code-lifetime attribution is therefore a separate
17
+ follow-up spike. It is no longer a prerequisite to finish the implementation.
18
+ This does not by itself authorize shipping with a failed acceptance check.
19
+
20
+ ## What is parked
21
+
22
+ - Explaining whether the attached Code objects in the private client snapshots
23
+ remain executable or are marked for invalidation.
24
+ - Accounting for every hidden/runtime byte and the remaining unclassified parser.
25
+ - Matching invalidated versions from the separate code-log run to snapshot objects.
26
+ - Producing a minimal upstream V8/ws reproduction if the evidence warrants one.
27
+
28
+ No more heap captures, compiler tracing, GC experiments or new diagnostic tooling
29
+ are planned on the release path solely to answer these questions. Do not repeat
30
+ the existing research or treat its partial explanations as a production fix.
31
+
32
+ ## Evidence already available
33
+
34
+ [Offline attribution](RECOVERY_CODE_ATTRIBUTION.md) found 261 final
35
+ deoptimization-bearing Code objects attached to preexisting functions/closures,
36
+ one unchanged double-version group, and three unchanged standard-stream/prototype
37
+ Socket objects. The [JIT control](RECOVERY_RUNTIME_CONTROLS.md) strongly supports
38
+ a compilation-dependent contribution in the separate load-generator process.
39
+
40
+ These findings do not establish the entire cause of the original shared-process
41
+ Ubuntu/Node 22.23.2 failure. Its fourth storm reached 110.218742% against the 110%
42
+ limit. One separately traced server also reached 110.080951%; server isolation is
43
+ not assumed to guarantee a pass. Original failures and private evidence remain
44
+ preserved. The snapshots must not be uploaded or embedded in a public issue.
45
+
46
+ ## Bounded release decision
47
+
48
+ The next recovery-specific release step is a predeclared comparison using the
49
+ existing original and split-process tools on Ubuntu/Node 22.23.2, with the matching
50
+ client dependency identified. Record exact revisions, environments and every
51
+ phase; keep connection counts, fixed warm baseline, delivery/cleanup checks and
52
+ the 110% bound. No snapshots, tracing, JIT disabling, coverage instrumentation or
53
+ other tests may run inside or alongside the measured processes.
54
+
55
+ Use one original run and one baseline split run, sequentially, not retries until
56
+ green. A failed setup is not a workload result. This is a bounded decision input,
57
+ not enough by itself to establish repeatability or replace cross-runtime release
58
+ checks. Separate processes change scheduling/GC and are not equivalent to the
59
+ original shared-process measurement.
60
+
61
+ Before execution, pin Node 22.23.2, record the Ubuntu 24.04 image/patch/kernel and
62
+ any differences from the historical runner, and record source/lockfile/client
63
+ hashes. Clear inherited diagnostic, coverage and workload overrides. Commands,
64
+ in this order, with the second result collected even if the first fails, but only
65
+ after confirming that the first process and all its children have terminated.
66
+ If cleanup is uncertain, record the second run as blocked; do not launch it beside
67
+ potential residual load:
68
+
69
+ ```text
70
+ node --expose-gc scripts/verify-recovery.js
71
+ node scripts/diagnostics/recovery-split.cjs baseline
72
+ ```
73
+
74
+ After these two runs, stop, record both outcomes, and request the acceptance-contract
75
+ decision. Do not automatically launch follow-up tracing or repeat either run.
76
+
77
+ - If the isolated server satisfies its own budget and delivery/cleanup checks,
78
+ review whether an explicitly versioned server-focused acceptance protocol is
79
+ appropriate. Track client-generator health separately. Adoption is a separate
80
+ reviewed decision, not automatic promotion of this diagnostic or erasure of
81
+ historical failures.
82
+ - If the server fails its budget, delivery, registry cleanup or process shutdown,
83
+ report the concrete failure and the required release decision. Do not start
84
+ another unbounded runtime-research cycle automatically.
85
+ - A failed diagnostic, incomplete output or uncertain cleanup is not a pass.
86
+ The diagnostic's successful exit proves its stated delivery/cleanup conditions,
87
+ not that its reported heap ratios satisfy a release budget.
88
+
89
+ Existing CI remains unchanged until a replacement protocol is explicitly approved.
90
+ No threshold increase, selective rerun, code-byte subtraction or blanket
91
+ `continue-on-error` follows from this deferral.
92
+
93
+ ### Temporary collection host
94
+
95
+ The local Windows machine has no running Docker Linux engine or Ubuntu WSL
96
+ distribution. A temporary, push-only `recovery-comparison.yml` workflow therefore
97
+ collects the declared pair on a separate Ubuntu 24.04 hosted VM, pinned to Node
98
+ 22.23.2. It only triggers when that workflow file changes on `codex/agent-ready`,
99
+ rejects repeated run attempts, and is removed after collection. It does not replace
100
+ or modify `ci.yml`, and its completion does not adopt a new acceptance protocol.
101
+
102
+ The historical failed runner reported Ubuntu 24.04.4, image `20260823.283.1`
103
+ and runner agent 2.336.0 (run `33322376349`, job `99286494853`). The new run records
104
+ its actual OS/image/kernel and Node/V8, revision, source/lockfile and client hashes.
105
+ The historical log did not independently record its kernel. Matching the image
106
+ label is not a claim of identical hardware or kernel.
107
+
108
+ Each measured command runs in a transient systemd service with a minimal
109
+ environment and `ExitType=cgroup`, so detached diagnostic worker groups remain
110
+ owned. The 180-second outer cap and five-second termination bound do not change
111
+ the scripts' existing internal deadlines. No resource quota or memory subtraction
112
+ is added. Before either workload, two trivial real Node services exit 0 and 7
113
+ through the same wrapper to verify status propagation and cleanup; these are setup
114
+ probes, not recovery measurements. A failed command remains failed; an empty/removed cgroup must establish
115
+ descendant termination before the split run starts. Systemd containment and clean
116
+ environment differ from the historical direct-shell execution and are disclosed
117
+ in the evidence. Other CI jobs use separate VMs, not necessarily exclusive physical
118
+ hardware. Only explicit safe logs/reports/hashes are retained, never snapshots.
119
+
120
+ The orchestration follows [systemd's transient-service semantics](https://raw.githubusercontent.com/systemd/systemd/v255/man/systemd-run.xml)
121
+ and the kernel's [recursive cgroup population definition](https://docs.kernel.org/admin-guide/cgroup-v2.html#un-populated-notification).
122
+ Its syntax/review and actual hosted execution are verification evidence, not a
123
+ claim of unit coverage for shell orchestration. Both outcomes and the split server's
124
+ actual warm/storm ratios still require review before the acceptance decision.
125
+
126
+ ## What remains release-critical
127
+
128
+ - Actual message delivery, reconnect behavior, bounded queues and empty owned
129
+ registries after cleanup.
130
+ - Successful shutdown checks; a reproduced timeout must be resolved or explicitly
131
+ dispositioned, not hidden by a longer deadline. The historical timeout remains
132
+ unexplained even when current regression tests pass.
133
+ - Matching packed Redweb/client compatibility, required coverage and ordinary
134
+ test/load/memory/package checks. Existing gaps are not waived by this spike.
135
+ - Honest documentation of the tested runtime, limits and remaining uncertainty.
136
+
137
+ The full acceptance checklist remains in [AGENT_READY_ACCEPTANCE.md](AGENT_READY_ACCEPTANCE.md).
138
+ This spike adds no new release feature, performance guarantee or certification.
139
+
140
+ ## Reopening the spike
141
+
142
+ Resume only as deliberately scheduled work, or when a server-specific regression,
143
+ continued growth under an approved protocol, or a real deployment incident makes
144
+ these questions actionable. Start from the existing evidence and a single
145
+ falsifiable question. Set the experiment count and stopping rule before executing;
146
+ end with a reproducible cause/fix or a documented evidence boundary, not an
147
+ indefinite sequence of deeper snapshots.
@@ -0,0 +1,229 @@
1
+ # Recovery investigation — 2026-08-30
2
+
3
+ Status: unresolved. This investigation does not waive the fixed recovery gate.
4
+
5
+ ## Question and controls
6
+
7
+ The existing five-cycle `steady-v2` gate intermittently exceeds its 110% retained
8
+ heap limit despite empty connection, room and session registries. The retained
9
+ earlier snapshots showed a temporary compiled-code increase, but did not prove a
10
+ complete attribution or establish an application-owned leak.
11
+
12
+ This investigation used Windows and Node 22.21.0, starting at Redweb `2410e60`.
13
+ The workload remained 1,200 preconditioning connections, 200 warm connections,
14
+ five rounds of 1,200 connections, batches of 50, and the existing 400 ms settling
15
+ period and two explicit collections. No warm-up, threshold, dependency, V8
16
+ acceptance flag or workload change was made. The local npm links were preserved.
17
+
18
+ ## Observations
19
+
20
+ One separate `--trace-opt --trace-deopt` run showed repeated weak-object
21
+ invalidation of compiled code in Node transport functions and Redweb's
22
+ `requestSnapshot`, `decorate`, `prepareContext`, `ensureContext`, `handleConnection`
23
+ and session paths. The captured console output was truncated, so it cannot support
24
+ complete event counts or attribution. This trace is diagnostic only, even though
25
+ the verifier's `diagnosticOnly` field does not detect Node trace flags. No raw heap
26
+ snapshots were created. It does not prove that socket-property transitions caused
27
+ the peak, nor that application retention is absent.
28
+
29
+ Source review found avoidable per-connection allocations: a finite-capacity route
30
+ without authentication or protocol policy still allocated an admission abort
31
+ controller, pending-map record and promise chain. A capacity-only synchronous
32
+ path was tested using the existing reservation and rejection logic without that extra
33
+ admission lifecycle. Custom authorization and native `verifyClient` hooks remain
34
+ on the existing asynchronous path. The route's connection-lifetime controller,
35
+ when needed, was unchanged. No connection or exemplar object was kept alive to
36
+ inflate the baseline or preserve V8 shapes.
37
+
38
+ **That candidate was discarded.** Its eligibility check accessed an overridable
39
+ authorization getter outside the protected promise path. It could also mistake a
40
+ replacement on `SocketRoute.prototype` for the default implementation. Two added
41
+ regressions failed on the candidate: the first threw synchronously instead of
42
+ rejecting safely; the second bypassed a denial. Both pass on the restored original
43
+ runtime. The initial reviewer approval was explicitly withdrawn after these
44
+ findings. With no demonstrated recovery or throughput benefit, additional
45
+ compatibility machinery would not justify keeping this optimization.
46
+
47
+ ## Unchanged acceptance measurements
48
+
49
+ One ordinary run was taken before the change and one after it. These are individual
50
+ measurements, not a repeated statistical comparison or a throughput claim.
51
+
52
+ | Phase | Before: heap bytes | After: heap bytes |
53
+ | --- | ---: | ---: |
54
+ | Warm | 10,583,768 | 10,575,480 |
55
+ | Storm 1 | 11,043,608 | 11,004,912 |
56
+ | Storm 2 | 11,512,000 | 11,498,392 |
57
+ | Storm 3 | 11,577,120 | 11,560,912 |
58
+ | Storm 4 | 11,583,512 | 11,668,656 |
59
+ | Storm 5 | 10,544,464 | 10,448,840 |
60
+
61
+ The before run passed at a maximum 109.44601204410375%. The after run **failed**
62
+ at 110.33689250984354%. All measured registries were zero in both runs. Final
63
+ decline to 98.80251298286224% after the change does not waive the intermediate
64
+ failure. No retry was used to replace that result. The allocation reduction is
65
+ therefore **not a recovery fix**, and the previous CI failure remains relevant.
66
+
67
+ ## Functional verification
68
+
69
+ The new real-listener regression failed before the change: a capacity-only
70
+ connection still had a pending admission record. Afterward, the same regression
71
+ verifies an active capacity reservation during connection, no asynchronous
72
+ admission record, rejection at capacity, release on disconnect and successful
73
+ reconnection. Separate real connections exercise custom authorization denial and
74
+ asynchronous native verification. Unit cases exercise drain, destroyed transports,
75
+ upgrade exceptions and reservation cleanup. These tests do not inject mocked
76
+ transports into the integration cases.
77
+
78
+ Before these extra compatibility cases were added, the discarded candidate
79
+ passed 759 tests in 74 suites and all four instrumented-library coverage metrics
80
+ at 100% (392.665 seconds), plus pretest/types. That broad pass did not detect the
81
+ two subsequently demonstrated compatibility defects, and is not final-tree
82
+ verification. The restored runtime with the two retained regression cases passes
83
+ 143 unit/real-network tests in ten suites, with all-four 100% coverage over
84
+ `src/ws/BaseSocketServer.js`. Earlier narrower selections lacked unrelated
85
+ constructor/inspection coverage and correctly failed their 100% coverage checks;
86
+ their behavior tests passed. No threshold was changed.
87
+
88
+ ## Native WebSocket control
89
+
90
+ After the full suite completed, one separate native-`ws` control acknowledged all
91
+ 7,400 messages using the same connection counts, batch size, settling delay and
92
+ collection sequence. It loaded no Redweb server/runtime, but reused the existing
93
+ native client open/close helpers. It omitted Redweb's rooms, sessions, authorization
94
+ and application dispatch, so it is not a feature-equivalent benchmark or acceptance
95
+ substitute. Its wire-response assertions and helper waits also differ from the
96
+ acceptance driver. It measured zero native server clients after every phase.
97
+
98
+ Warm heap was 6,919,096 bytes. Successive cycle heaps were 7,279,776 / 7,672,840 /
99
+ 7,755,872 / 7,819,640 / 7,829,720 bytes, ending at **113.16102565999951%** of warm.
100
+ The control's exit 0 means its delivery/cleanup assertions passed, not that it
101
+ passed a 110% memory gate; it deliberately reports measurements without enforcing
102
+ Redweb's acceptance threshold. Its local source is retained at
103
+ `coverage/recovery-native-control.cjs` (SHA-256
104
+ `70484c74a59071fc8b9c73691c4e01dc6240abe65e15ea1a9e15536da03772e1`).
105
+
106
+ This demonstrates that exceeding a 10% total-heap ratio is possible in this host's
107
+ underlying network workload without Redweb. Together with the trace, it supports
108
+ further investigation of runtime/compiled-code lifetime. It does **not** establish
109
+ complete attribution of Redweb's failure or prove the absence of a Redweb leak.
110
+
111
+ ## Remaining investigation boundary
112
+
113
+ The next recovery investigation must distinguish normal compiled-code lifetime
114
+ from a concrete application retainer using a narrowly targeted observation. Do
115
+ not subtract code bytes, retain artificial baseline objects, weaken the 110%
116
+ limit, increase warm-up, or treat a later isolated pass as resolution. Publication,
117
+ full original-client/application coverage and final cross-platform checks remain
118
+ separate requirements.
119
+
120
+ ## Split-process milestone
121
+
122
+ The original verifier measures Redweb, native client sockets and its load driver
123
+ inside one Node heap. To distinguish those owners, the separate diagnostic
124
+ `node scripts/diagnostics/recovery-split.cjs` starts a server worker and a native
125
+ client worker. Only the coordinator retains earlier measurements. The acceptance
126
+ verifier is unchanged; this diagnostic cannot pass or waive its heap gate.
127
+
128
+ Both workers use Node's existing `--expose-gc` flag, without inherited Node options
129
+ or coverage instrumentation. The server retains the original route, handler,
130
+ room/session limits and timing. Work remains 1,200 preconditioning connections,
131
+ 200 warm connections, five 1,200-connection storms and batches of 50. Each batch
132
+ waits for server connection cleanup. Each phase waits 400 ms, collects twice with
133
+ one intervening immediate, and requires all measured registries to be empty.
134
+
135
+ Differences are deliberate and material: there are separate runtimes, IPC and a
136
+ coordinator between batches; replies are parsed and checked against their exact
137
+ IDs; client operations use settled-result arrays and explicit ownership through
138
+ failure cleanup. V8 statistics are read after the phase's heap measurement. These
139
+ extra allocations and the changed scheduling mean ratios cannot be substituted
140
+ for, added to, or directly compared as equivalents of the original shared heap.
141
+ V8 spaces, code statistics, external memory and array buffers are overlapping views,
142
+ not additive explanations of heap growth. No code-byte subtraction is allowed.
143
+
144
+ Evidence is written to a new exclusive directory under `coverage/recovery-split-*`:
145
+ complete per-phase JSON lines, a final JSON report, source fingerprints, versions,
146
+ process identities, actual delivery counts, registry sizes and all memory views.
147
+ Source fingerprints are checked again after completion. Output beyond 1 MiB is
148
+ explicitly marked truncated. Each request and process cleanup is bounded; failed
149
+ channels cannot be reused, and uncertain cleanup retains the PID and nested
150
+ failures rather than claiming success. No raw heap snapshots are taken.
151
+
152
+ ### Single split run: observations
153
+
154
+ Run once after the full suite finished, from 19:05:35.658 to 19:05:48.448 UTC on
155
+ 2026-08-30, Windows/Node 22.21.0, V8 `12.4.254.21-node.33`, native `ws` 8.21.3.
156
+ The server PID was 22040; the load-generator PID was 34932. Both workers exited.
157
+ All 7,400 request IDs were acknowledged exactly, and every phase had zero server
158
+ connections/rooms/sessions and zero tracked client connections. Fingerprints were
159
+ unchanged at completion. Neither worker emitted output; no output was truncated.
160
+
161
+ | Phase | Server heap bytes | Client heap bytes |
162
+ | --- | ---: | ---: |
163
+ | Preconditioning | 10,181,120 | 6,579,816 |
164
+ | Warm | 10,187,232 | 6,540,872 |
165
+ | Storm 1 | 10,466,240 | 6,782,104 |
166
+ | Storm 2 | 10,874,320 | 7,205,968 |
167
+ | Storm 3 | 10,989,184 | 7,312,720 |
168
+ | Storm 4 | 11,037,936 | 7,374,504 |
169
+ | Storm 5 | 9,718,488 | 7,410,304 |
170
+
171
+ The server peaked at **108.35068839111547%** of its own warm heap and ended at
172
+ **95.39871085688438%**. The client crossed 110% at storm 2 and ended at
173
+ **113.29229497229116%**, its highest measured value. This attributes the sustained
174
+ above-110% ratio **in this split diagnostic** to the native load-generator process,
175
+ which does not load Redweb's runtime or `redweb-client`. It does not establish the
176
+ cause or relative contributions inside the original shared-process CI failure.
177
+
178
+ The client's warm-to-final heap increase was 869,432 bytes. Its code-and-metadata
179
+ statistic increased 521,972 bytes, while bytecode-and-metadata stayed at 755,952.
180
+ Its old/code/trusted spaces increased 394,608 / 321,216 / 152,360 bytes respectively;
181
+ external memory and array buffers remained unchanged after warm-up. These are
182
+ overlapping views sampled sequentially, not an exact object-retention accounting.
183
+ The data supports investigating client/runtime code and metadata lifetime, but
184
+ does not establish that all growth is compiled code or exclude retained objects.
185
+
186
+ On the server, bytecode-and-metadata fell from 908,240 bytes at storm 4 to 204,960
187
+ at storm 5 while heap fell by 1,319,448 bytes. This is a correlated observation,
188
+ not proof of a particular garbage-collector or bytecode-flushing cause. Server
189
+ code-and-metadata remained 416,038 bytes above warm at the final measurement.
190
+
191
+ Complete local evidence: `coverage/recovery-split-RQytod/report.json`, SHA-256
192
+ `fa8b0a070dfb833a8449e4c658190a64778f9e425fed42c93251dda57ed35db7`, alongside
193
+ `samples.ndjson`. The report includes all source fingerprints and memory views;
194
+ the table above preserves every phase's heap measurement in version control.
195
+
196
+ ### Verification and next boundary
197
+
198
+ The full suite passed **770 tests / 76 suites**, pretest/type checks, and all-four
199
+ 100% instrumented-library coverage in 427.392 seconds. Sixteen focused tests cover
200
+ the diagnostic's fixed phase plan, fingerprints, nested errors, real HTTP-upgrade
201
+ and WebSocket delivery, malformed replies, refused connections, timeout/exit,
202
+ graceful and forced cleanup, and command validation. OS-cleanup uncertainty is
203
+ tested separately with mocked units, not presented as real-process integration.
204
+
205
+ The diagnostic scripts are **not at 100% coverage**. Native child-aware coverage
206
+ reports 74.83% statements/lines, 95.12% branches and 80% functions across both
207
+ scripts. Worker statements/lines are 97.36%; orchestration/CLI and failure paths
208
+ remain uncovered. The earlier Jest-only report did not instrument child code and
209
+ reported 36.72% statements; that was not a behavioral failure. Both coverage gates
210
+ correctly exited nonzero without weakened thresholds; all sixteen behavior tests
211
+ passed. Coverage instrumentation is explicit in behavioral tests and disabled in
212
+ the actual measured workers. Library coverage does not certify diagnostic coverage.
213
+
214
+ Final pretest/type/generated-documentation checks and 20 focused documentation/
215
+ diagnostic tests also passed after the evidence update. The senior critic approved
216
+ the milestone after independently checking report/source hashes, phase counts,
217
+ registries and calculations; earlier cleanup/evidence findings were addressed.
218
+ The next causal step is client-only retaining-path/code-lifetime
219
+ inspection at warm and late storms, with complete bounded evidence, followed by a
220
+ one-variable control. A speculative Redweb runtime optimization is not justified
221
+ by this result. The original recovery failure, client/application coverage gaps
222
+ and release requirements remain open. No original acceptance gate was rerun or
223
+ waived, and no production code, dependency, threshold, publication or deployment
224
+ changed in this milestone.
225
+
226
+ Research-led follow-up: [runtime/JIT controls](RECOVERY_RUNTIME_CONTROLS.md) records
227
+ the subsequent same-source baseline, complete trace and client-only JIT-disabled
228
+ control. It narrows the client growth to a JIT-dependent effect without waiving
229
+ the original recovery failure.
@@ -0,0 +1,181 @@
1
+ # Recovery runtime controls — 2026-08-30
2
+
3
+ Status: a strong JIT-dependent effect was identified in the split load generator.
4
+ The original shared-process recovery failure is **not resolved or waived**.
5
+ This continues [the split-process investigation](RECOVERY_INVESTIGATION.md).
6
+
7
+ ## Research and predeclared tests
8
+
9
+ The V8 source bundled with Node 22.21.0 enables bytecode flushing with an aging
10
+ threshold of six eligible collections. Forced and heap-profiler collections keep
11
+ ages unchanged; the exposed `gc()` function requests a forced collection. Thus two
12
+ explicit collections do not guarantee that unused code has aged enough to flush.
13
+ These are implementation details of this exact runtime, not portable API promises.
14
+ Sources: [flags](https://github.com/nodejs/node/blob/v22.21.0/deps/v8/src/flags/flag-definitions.h),
15
+ [age handling](https://github.com/nodejs/node/blob/v22.21.0/deps/v8/src/heap/heap.h),
16
+ [GC extension](https://github.com/nodejs/node/blob/v22.21.0/deps/v8/src/extensions/gc-extension.cc),
17
+ [V8 bytecode-flushing explanation](https://v8.dev/blog/v8-lite).
18
+
19
+ Three runs were declared before measurement, executed once each, sequentially:
20
+
21
+ 1. `node scripts/diagnostics/recovery-split.cjs baseline` — a fresh same-source control.
22
+ 2. `node scripts/diagnostics/recovery-split.cjs trace` — both workers use
23
+ `--trace-gc --trace-flush-code`, with additional sample markers.
24
+ 3. `node scripts/diagnostics/recovery-split.cjs client-jitless` — only the load
25
+ generator additionally uses `--jitless`; the server retains normal compilation.
26
+
27
+ All use `--expose-gc`. No inherited Node options or coverage instrumentation enter
28
+ the measured workers. Windows, Node 22.21.0, V8 12.4.254.21-node.33 and ws 8.21.3
29
+ are unchanged. All three reports contain identical source fingerprints, also
30
+ checked at each run's completion. No test suite ran alongside the measurements.
31
+ The diagnostic changes no original acceptance script, workload, warm-up or budget.
32
+
33
+ The fixed workload remains 1,200 preconditioning connections, 200 warm connections,
34
+ five rounds of 1,200, batches of 50, connection-cleanup barriers and 400 ms settling
35
+ with two explicit collections. Every run verified all 7,400 exact reply IDs and
36
+ empty measured registries at every phase. Both workers exited in every run.
37
+
38
+ ## Measurements
39
+
40
+ Heap bytes, captured before allocating each sample's subsequent V8 statistics:
41
+
42
+ | Phase | Baseline server | Baseline client | Traced server | Traced client | JIT-control server | JIT-disabled client |
43
+ | --- | ---: | ---: | ---: | ---: | ---: | ---: |
44
+ | Preconditioning | 10,171,000 | 6,568,792 | 10,174,984 | 6,571,376 | 10,186,408 | 5,566,904 |
45
+ | Warm | 10,190,632 | 6,539,864 | 10,182,928 | 6,504,752 | 10,190,344 | 5,570,608 |
46
+ | Storm 1 | 10,472,704 | 6,767,512 | 10,453,688 | 6,773,968 | 10,455,296 | 5,573,200 |
47
+ | Storm 2 | 10,866,832 | 7,235,712 | 10,777,240 | 7,198,296 | 10,774,848 | 5,573,320 |
48
+ | Storm 3 | 10,888,784 | 7,339,704 | 11,079,576 | 7,321,224 | 11,000,000 | 5,575,240 |
49
+ | Storm 4 | 11,067,616 | 7,365,128 | 10,882,944 | 7,362,680 | 11,112,632 | 5,575,752 |
50
+ | Storm 5 | 9,911,296 | 7,388,792 | 11,209,464 | 7,343,488 | 11,109,832 | 5,575,752 |
51
+
52
+ The like-for-like comparison is baseline versus client-JIT control, **not** trace
53
+ versus JIT control. Baseline client growth after warm-up was **848,928 bytes**
54
+ (112.98082039626512% of warm); the JIT-disabled client grew **5,144 bytes**
55
+ (100.09234180541873%). Baseline client code-and-metadata grew 504,608 bytes;
56
+ the JIT-disabled client's corresponding value stayed exactly 2,058,560 bytes.
57
+ Client bytecode-and-metadata, external memory and array buffers remained unchanged
58
+ after warm-up in both runs.
59
+
60
+ This is strong evidence of **JIT-dependent growth in this split workload**. It is
61
+ not exact accounting of every retained byte: code/space statistics overlap, and
62
+ disabling JIT also changes execution speed, allocation and collection behavior.
63
+ The control additionally reports `Warning: disabling flag --expose_wasm due to
64
+ conflicting flags`; that warning is preserved, not suppressed. The workload does
65
+ not exercise WebAssembly. This is neither a throughput result nor a recommendation
66
+ to disable JIT in production. See [V8's description of JIT-less execution](https://v8.dev/blog/jitless).
67
+
68
+ The baseline server peaked at 108.60578617695154% and finished at
69
+ 97.25889424718703% of its warm heap. Its bytecode-and-metadata again fell late,
70
+ from 908,584 to 205,248 bytes. That event **did not recur in the traced run**:
71
+ server bytecode remained 908,584 and final heap reached 110.08095117632178%.
72
+ The normal-JIT server paired with the JIT-disabled client peaked at
73
+ 109.05060712376344% and finished at 109.0231301318189%, also without the late
74
+ bytecode drop. Retain all three observations; do not select the smallest result.
75
+
76
+ ## Complete trace and its framing limitation
77
+
78
+ The traced server's stdout contains 12,979 bytes and the client's 12,257 bytes;
79
+ both stderr files are empty. All file lengths and SHA-256 values were independently
80
+ rechecked. Natural successful shutdown now drains output before exit; abrupt
81
+ coordinator loss retains orphan protection and the coordinator retains bounded
82
+ forced cleanup. Output is limited to 16 MiB per stream: overflow or a write failure
83
+ invalidates the run instead of silently truncating successful evidence.
84
+
85
+ V8's buffered native output and JavaScript sample markers interleave, occasionally
86
+ inside a native line. **Raw marker adjacency is not a trustworthy timeline.**
87
+ The original byte logs are preserved unchanged. For the counts below, remove only
88
+ the fourteen exact `[rw-phase ...]` marker records (including their line endings)
89
+ per worker from an in-memory copy. The reconstructed native records all have the
90
+ expected process prefix and monotonically increasing V8 millisecond timestamps.
91
+ No original bytes/files are overwritten, and no marker-based phase timing claim
92
+ is made.
93
+
94
+ | Reconstructed native records | Server | Client |
95
+ | --- | ---: | ---: |
96
+ | Scavenges | 37 | 41 |
97
+ | Mark-Compacts | 19 | 16 |
98
+ | Mark-Compacts labeled `testing` | 14 | 14 |
99
+ | Mark-Compacts labeled `finalize incremental marking via task` | 5 | 2 |
100
+ | Flushing summary records | 19 | 16 |
101
+ | Total flushed SharedFunctionInfos reported | 0 | 0 |
102
+
103
+ Server natural-major timestamps: 454 / 6,299 / 8,275 / 10,259 / 12,244 ms.
104
+ Client natural-major timestamps: 1,323 / 4,201 ms. The fourteen testing collections
105
+ per worker agree with two explicit calls for each of seven phases. The zero
106
+ flushing totals and stable bytecode measurements are consistent with the V8 aging
107
+ mechanism, but do not prove what caused the earlier untraced bytecode drop.
108
+ No retry was made to obtain the desired flushing event.
109
+
110
+ ## Evidence locations
111
+
112
+ Each directory contains `report.json`, `samples.ndjson`, and separate server/client
113
+ stdout/stderr logs. Reports include flags, versions, identities, source hashes,
114
+ per-phase memory views, delivery counts and output-file hashes. Times are UTC.
115
+
116
+ | Mode | Local directory under `coverage/` | Start–end on 2026-08-30 |
117
+ | --- | --- | --- |
118
+ | Baseline | `recovery-split-RqlKQM` | 19:20:24.892–19:20:37.704 |
119
+ | Trace | `recovery-split-bg0hV9` | 19:20:42.205–19:20:54.990 |
120
+ | Client JIT-disabled | `recovery-split-z9JA5J` | 19:20:59.831–19:21:13.483 |
121
+
122
+ Report SHA-256 values, respectively:
123
+
124
+ - `212f24669b0240eff1680cb9aa91cef4690465f3203b6b81e6f8da50981d9a08`
125
+ - `88fa6323feded06fea25f78169c88f79d7f4dcead997730d078203f8ee132f02`
126
+ - `21b6c73bac8789c4f234363416df9fd740c0c7208b977e821f83c9377ccd7521`
127
+
128
+ Trace stdout SHA-256 values:
129
+
130
+ - Server: `29be4f852458b55af3ce6b77a9fd4b9b8213430c38e7c827c66231f2ae67d38c`
131
+ - Client: `e006731ada264a63220e4dcafa6da080c049699e59c3f7caaabd2572cf14b4a2`
132
+
133
+ ## Verification and remaining work
134
+
135
+ Twenty-four focused tests pass, combining unit tests with real child processes
136
+ and real HTTP-upgrade/WebSocket traffic. New cases verify exact mode flags,
137
+ complete output/hashes, cap failures, exclusive evidence creation and an 8 MiB
138
+ queued-output shutdown fixture. That last test also passed before the drain fix
139
+ on Windows; it must not be described as a reproduced POSIX truncation bug.
140
+
141
+ Native child-aware diagnostic coverage remains below its unchanged 100% gate:
142
+ 76.03% statements/lines, 95.57% branches and 91.66% functions. The worker is at
143
+ 100% statements/lines/functions and 97.82% branches; its connection-barrier timeout
144
+ branch remains uncovered. Coordinator/CLI and failure paths also remain uncovered.
145
+ All behavior tests pass; the separate coverage command correctly exits nonzero.
146
+ No exclusions or relaxed thresholds were introduced.
147
+
148
+ Full-suite verification failed: **777 tests passed and one failed** across
149
+ 76 suites (75 passed, one failed), in 415.09 seconds. The failing case is
150
+ `owned-http-shutdown.integration.test.js`: successful page cleanup with `live=true`
151
+ timed out waiting 500 ms for the client's WebSocket close event, after application
152
+ shutdown and incomplete-HTTP-peer closure had completed. Its cause remains
153
+ unestablished; it is not dismissed as a timing flake or attributed to these
154
+ diagnostics. No retry was used to replace this result. Pretest/generated-document
155
+ and TypeScript gates passed. Instrumented-library coverage was 100% for statements,
156
+ branches, functions and lines, but that does not override the behavioral failure
157
+ or the separate diagnostic-tool coverage gaps above.
158
+
159
+ Read-only critic inspection confirmed that the client close listener was installed
160
+ before connection readiness, so no obvious missed-listener race explains the
161
+ failure. Server shutdown bounds termination attempts but does not await the remote
162
+ client's close notification. Endpoint state and error timing were not captured at
163
+ the deadline; those observations are needed before attributing this failure.
164
+ Final documentation generation/TypeScript checks passed, followed by 28 focused
165
+ documentation and diagnostic tests across three suites. That scoped pass does not
166
+ replace the failed full-suite result.
167
+
168
+ The senior critic independently checked mode isolation, cleanup, report/log hashes,
169
+ delivery/registry counts, reconstructed trace counts and the inference boundaries.
170
+ There was no actionable evidence-integrity finding after the drain fix.
171
+
172
+ The next causal investigation, if continued, should identify which compiled
173
+ functions, feedback structures and retaining paths account for the client growth
174
+ under normal JIT. The paired result does not establish an exact object-level cause
175
+ or resolve the original shared-process CI failure. No further repeated benchmark
176
+ is justified merely to obtain a smaller number or a flushing event. Original
177
+ acceptance limits, runtime/library sources, dependencies, npm links, publication
178
+ and deployment remain unchanged. No raw heap snapshots were taken.
179
+
180
+ Follow-up: [client code-creation census](RECOVERY_CODE_CENSUS.md) identifies
181
+ concrete normal-JIT compilation candidates without claiming retained-size proof.
@@ -0,0 +1,58 @@
1
+ # Choose and verify a Redweb release
2
+
3
+ Redweb is a Node.js HTTP/WebSocket library with server-rendered TSX, not a hosted service. Evaluate the exact package, runtime, application and deployment you intend to use. A passing test suite, a registry signature and a provenance statement answer different questions; none certifies an application as secure.
4
+
5
+ ## Runtime and compiler compatibility
6
+
7
+ | Area | Contract and verification boundary |
8
+ | --- | --- |
9
+ | Core runtime | The package declares Node `>=18`. This is an installation/compatibility floor, not a recommendation to deploy an end-of-life runtime. |
10
+ | Production Node | Use a currently maintained LTS release with current security patches. As checked on 2026-08-30, Node 22 and 24 are LTS; Node 18 and 20 are end-of-life. Recheck the official schedule when deploying. |
11
+ | CI coverage | The repository matrix targets Node 18, 20, 22 and 24 on Linux. The 18/20 jobs are legacy-compatibility checks, not security-support claims. A configured job is not a passing result; inspect checks for your exact commit. |
12
+ | TypeScript/TSX | The starter uses the package's tested TypeScript dependency and `redweb/tsconfig.json`. Standard decorators and legacy `experimentalDecorators` consumers have separate compile tests. Node's native TypeScript execution is not a replacement for compiling TSX/decorators with this configuration. |
13
+ | Persistent dashboard | This application recipe requires Node 22.13+ and native `node:sqlite`; it is not part of the core runtime requirement. Its database and account/session design are single-process. |
14
+ | Browser | The real-browser gates exercise Chromium. They are not a Firefox/Safari compatibility certification. Test the browsers you support, including reconnect and forms, before release. |
15
+ | Runtime platforms | This branch has local Windows evidence and Linux CI configuration. Neither proves every OS, architecture, proxy, container platform or serverless host works. Live pages require a long-lived Node listener with WebSocket upgrades. Static export is a separate deployment mode. |
16
+
17
+ Use the [official Node release schedule](https://nodejs.org/en/about/previous-releases) for maintained releases, the [TypeScript decorator documentation](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html#decorators) for the distinction between decorator modes, and [Node's TypeScript limitations](https://nodejs.org/api/typescript.html) for native execution constraints. Current per-commit test evidence and uncompleted checks are recorded in the [release checklist](AGENT_READY_ACCEPTANCE.md), not inferred from this table.
18
+
19
+ ## Pin the package and the documentation together
20
+
21
+ For a published application, select an exact release, commit its lockfile, and use `npm ci` in CI/deployment. The following is an intentionally pinned example, not an instruction to treat `0.12.0` as permanently current:
22
+
23
+ ```sh
24
+ npm view redweb@0.12.0 version engines dist.integrity dist.signatures dist.attestations gitHead --json
25
+ npm install --save-exact redweb@0.12.0
26
+ npm audit signatures
27
+ npm audit --omit=dev
28
+ ```
29
+
30
+ The signature command must run in the installed application directory. Keep TLS verification enabled and use a current npm CLI; a certificate/trust-store failure is not a reason to disable verification. A lockfile's integrity value detects changed package bytes; registry signatures authenticate registry metadata; provenance, when present and verified, links an artifact to a build/source identity. Vulnerability audit is a separate check against known advisories, not an application penetration test.
31
+
32
+ For this branch's **unreleased** features, follow the matching tarball instructions in the [complete starter recipes](GETTING_STARTED.md#start-with-a-complete-recipe). The checkout has package metadata `0.13.0`, reserved for this unreleased candidate; the published `redweb@0.12.0` does not contain these changes. Installing `latest` does not install the unmerged branch. Do not mix a local-candidate guide with an older registry release and assume the APIs exist. Changing the package version does not publish it or satisfy outstanding release checks.
33
+
34
+ Redweb is pre-1.0. Consult the changelog and versioned guide before upgrading, run your own real HTTP/WebSocket/browser tests, and keep a rollback artifact. Patch/minor numbers and a compatible TypeScript build alone do not prove wire compatibility, preserved sessions, database compatibility or application authorization. HTTP-created live-page sessions are process-owned; a restart or rolling replacement does not migrate them automatically. Raw socket protocol versions are negotiated only when the route opts in, and application payload compatibility remains your contract.
35
+
36
+ ## What was verified for the published package
37
+
38
+ Read-only registry inspection on **2026-08-30** reported `latest: 0.12.0`, with:
39
+
40
+ - `gitHead`: `6c95093c5e3b357772841f40c5371359dab0bf03`.
41
+ - SHA-512 integrity: `sha512-74AOoEmREkoPElYB9nalsN8nLfiPzw1Ap3WYEwxERJqoSGcfYAQhyfpAK2dOyLQtc+A+sAl9fFv0HMuIXWDjEg==`.
42
+ - Registry signatures present; **no `dist.attestations` field was returned**. Build provenance is therefore not claimed for this release.
43
+
44
+ An independently created temporary application installed that exact package with lifecycle scripts disabled and ran `npm audit signatures --json` using Node 22.21.0/npm 11.6.2 and the Windows system trust store. It exited successfully with `invalid: []` and `missing: []`. That checks the installed registry dependency tree's signatures/available attestations; an empty failure list does **not** mean every package has build provenance. This historical observation is not a verification of a future release or of the current unreleased source.
45
+
46
+ The commands above let you repeat the check. See npm's [signature and attestation verification](https://docs.npmjs.com/cli/v11/commands/npm-audit/) and [viewing provenance](https://docs.npmjs.com/viewing-package-provenance/) documentation for current verification behavior.
47
+
48
+ ## Publishing provenance is a maintainer action
49
+
50
+ No publishing workflow or npm account setting is enabled by this guide. To add provenance to a future release, the maintainer must choose an authorized supported build/publish workflow, configure the correct repository identity and npm permissions, publish the exact tested artifact, and verify the resulting registry attestation afterward. A local `npm pack`, `gitHead`, checksum, badge or successful CI run is not a substitute for a verified attestation. Do not label older releases retroactively as provenance-verified.
51
+
52
+ npm describes the supported providers and identity requirements in [generating provenance](https://docs.npmjs.com/generating-provenance-statements/) and [trusted publishing](https://docs.npmjs.com/trusted-publishers/). Provenance provides origin/build evidence, not proof that source code is safe.
53
+
54
+ ## Support and reporting boundaries
55
+
56
+ For ordinary bugs, provide a minimal reproducible project, exact Redweb/Node/npm/TypeScript versions, operating system, decorator mode, sanitized logs, and the failing HTTP/WebSocket sequence in the [issue tracker](https://github.com/lakam99/redweb/issues). Never include tokens, cookies, passwords, private database contents or customer traffic.
57
+
58
+ There is no paid support contract, response-time SLA or long-term backport policy established by these files. No private vulnerability contact is invented here. The repository inspection on 2026-08-30 reported no published security policy; the maintainer still needs to establish a private reporting channel and its handling policy before the project claims one. Do not disclose a suspected vulnerability or working exploit in a public bug report merely because that is the only linked tracker.