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,50 @@
1
+ # Application coverage-recorder verification
2
+
3
+ The recorder source is unchanged. This increment adds direct measurement of the
4
+ small exit hook that writes authored application coverage from actual child
5
+ processes. It closes a private-tool measurement gap, not a production-runtime bug.
6
+
7
+ `npm run verify:recorder:coverage` passes six selected tests across two suites:
8
+ five isolated recorder units and the existing actual instrumented-script pipeline
9
+ integration test. Eight unrelated integration cases are intentionally filtered,
10
+ not counted as passing. The source-level Istanbul map covers six statements, two
11
+ branches, **one function** and six lines, all 100%.
12
+
13
+ One unit observes the hook registered with the real process, invokes it with absent
14
+ and present coverage data, checks real files, then restores its listener/global/
15
+ environment changes. Four native subprocess cases verify no invented report,
16
+ exact payload and unique child filenames, visible missing-directory failure and
17
+ visible serialization failure. The existing pipeline integration compiles and
18
+ executes original-source-instrumented scripts and validates their actual report
19
+ inventory. These checks do not replace HTTP, filesystem or process APIs.
20
+
21
+ ## Why the native percentage alone was insufficient
22
+
23
+ The first c8 run passed five tests but reported zero measured functions. Inspection
24
+ of its nine relevant raw V8 reports found the authored anonymous callback at offsets
25
+ 232–496 with execution count one. Installed `v8-to-istanbul@9.2.0` only creates
26
+ function entries for truthy function names; both the wrapper and arrow callback
27
+ have empty names. This is a conversion limitation, not evidence that the callback
28
+ did not execute. The critic independently verified the raw ranges and converter.
29
+
30
+ The older native map remains diagnostic evidence under
31
+ `coverage/application-recorder/coverage-final.json`, SHA-256
32
+ `0ae6fdd8f6cab04610a688f7e395695f8489d4a7eac377ef35789c802af11ac4`.
33
+ Its 13 line-based statements, three branches and zero-function denominator are
34
+ not presented as complete authored function coverage. Do not rerun a native-only
35
+ collector with the Jest-transformed callback test mixed into the same source map.
36
+
37
+ The maintained gate instead uses the nonvacuous original-source Istanbul map
38
+ alongside native behavioral evidence. CI allows five minutes and retains its
39
+ authored report for 30 days on success or failure. The critic approved this scope,
40
+ restoration behavior and supervision; no source rename or converter patch was
41
+ needed merely to change a percentage.
42
+
43
+ Source `scripts/lib/record-application-coverage.cjs` SHA-256:
44
+ `265b87f95d71b44bb59a9b50b1eda0d831188283a5c2f9b85bb3dfa0a8cc4df3`.
45
+ Authored report `coverage/application-recorder-authored/coverage-final.json` SHA-256:
46
+ `d487e66d02da76915f452b451d972aed9cb44bcbf06bd6658a74af30b98642e5`.
47
+ The first authored run passed in 1.517 seconds; the maintained command then passed
48
+ in 1.325 seconds with the same report hash. Its five new unit tests were added
49
+ after the preceding full regression selected its inventory; they are not
50
+ retroactively included in that full-run count. Broader release gates remain open.
@@ -0,0 +1,307 @@
1
+ # Disabled-feature benchmark verification
2
+
3
+ This is unreleased verification-tool and candidate evidence. The bounded
4
+ `18b1dfd` qualification below passes the current local regression rule; it is not
5
+ a production-capacity or statistical-performance guarantee. Production
6
+ socket/rendering code is unchanged by the evidence increment.
7
+
8
+ ## Contract and corrections
9
+
10
+ Run `npm run verify:overhead -- <baseline-directory> [candidate-directory]` with
11
+ both implementations already prepared. Defaults remain 20,000 measured messages,
12
+ 128 outstanding requests, 2,000 warm-up messages and five alternating paired
13
+ trials. The original upper-median calculation and maximum 3% throughput / 5% p99
14
+ regressions remain unchanged. Overrides must be safe integers with valid ranges.
15
+
16
+ Previously, an explicitly unit-stubbed subprocess result containing null p99
17
+ produced a successful exit and null regression. The coordinator now validates the
18
+ entire JSON response, finite positive measurements, requested workload, exact
19
+ delivery, and stable identity before calculating a result. A unit reproduction
20
+ is not described as native integration evidence.
21
+
22
+ Each phase tracks only its bounded outstanding requests and rejects unknown,
23
+ duplicate, malformed or late warm-up replies. Measured IDs continue after warm-up
24
+ rather than reusing its IDs. This is a **new harness revision**, not a byte-for-byte
25
+ repeat of historical traffic: accounting overhead and numeric payload IDs differ.
26
+ The same revision measures both sides. Timing still ends inside the final reply
27
+ callback; JSON parsing precedes the latency completion timestamp.
28
+
29
+ Each response phase has a 30-second deadline; each worker has a 120-second
30
+ deadline. Client and server cleanup are independently attempted, combined errors
31
+ remain visible, and successful output follows cleanup. The shared subprocess
32
+ owner rejects truncated output even when a child exits unsuccessfully. A real
33
+ child emitting an oversized prefix followed by valid JSON and exit 1 reproduced
34
+ the old acceptance hole; it is now rejected with the original failure retained.
35
+
36
+ Worker identity records the canonical entry/manifest hashes, module version,
37
+ Node version, NODE_PATH and client/server-root WebSocket resolution paths. These
38
+ are **not** a whole-library fingerprint or proof of the server's actual loaded
39
+ WebSocket implementation. Entry/manifest hashes are checked before loading and
40
+ after cleanup; changes between trials also fail validation.
41
+
42
+ ## Test boundaries
43
+
44
+ `npm run verify:overhead:coverage` measures these six modules explicitly:
45
+
46
+ ```text
47
+ scripts/benchmark-worker.js
48
+ scripts/verify-disabled-overhead.js
49
+ scripts/lib/BenchmarkBatch.js
50
+ scripts/lib/BenchmarkComparison.js
51
+ scripts/lib/BenchmarkWorkload.js
52
+ scripts/lib/measureBenchmarkBatch.js
53
+ ```
54
+
55
+ The focused suite has 52 tests across five suites: 204 statements, 111 branches,
56
+ 30 functions and 174 lines, all 100%. Native tests use actual HTTP/WebSockets,
57
+ worker processes, real 30-second silent peers and owned files. They cover both
58
+ phases, malformed frames, disconnects, duplicate/unknown replies, late warm-up
59
+ IDs, module-file mutation and actual paired worker execution. Explicit unit
60
+ boundary stubs cover otherwise difficult command and cleanup failures; they are
61
+ not labelled mock-free integration. Small fixtures are correctness tests, not
62
+ substitutes for default performance measurements. CI retains scoped reports on
63
+ success and failure.
64
+
65
+ Latest focused run: 65.463 seconds on Windows / Node 22.21.0. Report
66
+ `coverage/benchmark-tools/coverage-final.json` SHA-256:
67
+ `f81715b57b84ead6af52e96ac3d7c1e19a6dc5da4618d4be23506752aaca2ff6`.
68
+
69
+ | Measured source | SHA-256 |
70
+ | --- | --- |
71
+ | `benchmark-worker.js` | `07b79d6a32a274c4d5bec93060ca470f34ed50871b45592a20683090cfa56c97` |
72
+ | `verify-disabled-overhead.js` | `b09b6278fff001359998b113d6d0d04563658751b58f1bae93fd29cef39aec01` |
73
+ | `lib/BenchmarkBatch.js` | `8c387bbe0334cf781836ccc2012910a44c9b030114339304818bd0cf50b7042d` |
74
+ | `lib/BenchmarkComparison.js` | `e2b7f8fd4d5ee2b036408cd02b5ace1f33abfad104e48b6d9eefb9baec2f9605` |
75
+ | `lib/BenchmarkWorkload.js` | `7b52b5f4695bcff3568b7c0f4fd7aedf66a853edd694bd7ef6756427108759ad` |
76
+ | `lib/measureBenchmarkBatch.js` | `09e32385c3918c6e9707471b131c22a11eed80bb100a0e10bbffd1443ec62e0c` |
77
+
78
+ The shared owner's separately rerun memory-tool scope passes 71 tests with two
79
+ POSIX-only skips on Windows: 164 statements, 95 branches, 30 functions and 139
80
+ lines, all 100%. Owner source SHA-256:
81
+ `805df80e0f1877049d6bdf6847eab4f35187c38f3ca17aa8ef51fcac7a75bacb`.
82
+ Report `coverage/memory-tools/coverage-final.json` SHA-256:
83
+ `bc1a2faa8e6cb0b4f5248297d04c4e01212803386dd5adebc3f59c1005d3182d`.
84
+ Earlier owner maps describe earlier source, not this revision.
85
+
86
+ ## Current bounded qualification
87
+
88
+ After independent review and the complete local regression exited, one fresh
89
+ exact `redweb@0.12.0` installation was reused for exactly two preregistered
90
+ comparisons against immutable `18b1dfd`. Each comparison ran five alternating
91
+ pairs with20,000 measured messages,2,000 warm-up messages and concurrency128.
92
+ All20 workers completed exact warm-up and measured delivery, stable entry/manifest
93
+ identities, normal cleanup and empty stderr. No third or replacement comparison
94
+ ran; no workload, profiling or coverage override was present.
95
+
96
+ | Comparison | Baseline messages/s | Candidate messages/s | Throughput regression | p99 regression | Result |
97
+ | --- | ---: | ---: | ---: | ---: | --- |
98
+ | 1 | 37,525.121 | 37,663.117 | -0.3677% | -5.3204% | Pass |
99
+ | 2 | 37,521.080 | 38,192.750 | -1.7901% | -8.2032% | Pass |
100
+
101
+ Both are below the unchanged maximum3% throughput and5% p99 regressions, so the
102
+ predeclared decision is a **bounded PASS**. The desktop was not an isolated
103
+ benchmark host. This result does not explain, erase or relabel the historical
104
+ 4.78495% failure below. Raw report SHA-256 values are
105
+ `c2b9d26dd703a0f8ef121973331d0d91bf1bb6a8204dd322dc3c95a9f15647f3`
106
+ and `4979301a98f41cdbbb89f24e956c11dcf555719d04401652a9fe85cabbc77817`.
107
+
108
+ ## Retained default performance results
109
+
110
+ Windows / Node 22.21.0, published `redweb@0.12.0` installed into a newly owned
111
+ workspace for each comparison, then-current checkout as candidate. Both runs used the
112
+ same measured implementation entry hashes and unchanged benchmark limits. No
113
+ smaller workload or selective trial deletion was used.
114
+
115
+ | Run end (UTC, 2026-08-31) | Baseline messages/s | Candidate messages/s | Throughput regression | p99 regression | Result |
116
+ | --- | ---: | ---: | ---: | ---: | --- |
117
+ | 06:26:33 | 40,991.410 | 42,399.336 | -3.4347% | -14.3156% | Pass |
118
+ | 06:32:18 | 41,514.163 | 39,527.731 | 4.7850% | 1.2200% | **Fail** |
119
+
120
+ The second run fails the 3% throughput gate. The first pass does not cancel it;
121
+ the cause is under investigation. All trials reported exactly 2,000 warm-up and
122
+ 20,000 measured sends/replies. Raw trial identities and results remain in
123
+ `coverage/benchmark-registry-baseline.json` and
124
+ `coverage/benchmark-registry-baseline-final.json`. The latter follows the shared
125
+ strict-output fix; the timed worker implementation did not change between runs.
126
+ Report SHA-256 values, in the table's order:
127
+ `091f82fc80cd94806793c5a00748c2f5c7da125d80155292bf1e55432403bcef`,
128
+ `87e003a1719a45b6aae80379dbfdbde2beb8bd9500fb225413e1367056273143`.
129
+
130
+ Registry archive: `https://registry.npmjs.org/redweb/-/redweb-0.12.0.tgz`;
131
+ integrity `sha512-74AOoEmREkoPElYB9nalsN8nLfiPzw1Ap3WYEwxERJqoSGcfYAQhyfpAK2dOyLQtc+A+sAl9fFv0HMuIXWDjEg==`.
132
+ Fresh read-only source inspection confirms ws 8.21.3 and Express 4.22.2 on both
133
+ sides with matching entry hashes. Candidate client 0.2.0 differs from published
134
+ Redweb's client 0.1.0. Socket code also differs; version agreement alone cannot
135
+ rule out a regression. Candidate and harness resolve the same WebSocket path,
136
+ while the isolated baseline resolves its own copy. These observations identify
137
+ controls to investigate, not a proven explanation or permission to relax limits.
138
+
139
+ The website's Redweb dependency is a junction to the checkout, not an isolated
140
+ published baseline. No website, npm or PR release is performed by these tests.
141
+
142
+ ## Bounded controls, not acceptance retries
143
+
144
+ A predeclared three-control series retained the same five pairs, 20,000 messages,
145
+ 128-window workload and all trials. Owned workspaces were cleaned normally:
146
+
147
+ | Control | Throughput regression | p99 regression | Threshold outcome |
148
+ | --- | ---: | ---: | --- |
149
+ | Checkout versus itself, same path | -1.8540% | 4.4554% | Pass |
150
+ | Published package versus itself, same path | -1.7426% | 7.2279% | Fail (p99) |
151
+ | Baseline and candidate both independently installed | 4.2695% | -1.6602% | Fail (throughput) |
152
+
153
+ Report: `coverage/benchmark-controls.json`. The identical-package failure proves
154
+ this setup can cross the latency allowance without source differences. It does
155
+ not establish the cause of the separate throughput failures. Symmetric package
156
+ installation does not eliminate the observed throughput difference.
157
+
158
+ The critic recommended a more direct topology control: compare the checkout with
159
+ a byte-identical owned runtime copy containing a separate WebSocket dependency.
160
+ All 113 runtime, entrypoint and WebSocket files matched before/after; other
161
+ dependencies used the same checkout fallback. This single unchanged-workload A/A
162
+ comparison passed (throughput 0.7865%, p99 -7.3321%). Its full manifest and trials
163
+ are in `coverage/benchmark-topology-control.json`; cleanup completed normally.
164
+ The pass does not establish that dependency topology caused the A/B failures.
165
+ No controls are selectively substituted for the failed release comparison.
166
+
167
+ Independent review approved the strict-output correction, test time budgets and
168
+ documented coverage/source hashes. It confirmed arithmetic and noted measured
169
+ phases of approximately 463–534 ms; no retained evidence establishes scheduling,
170
+ GC or compilation as the cause. The historical result remains unresolved even
171
+ though the separately preregistered current qualification above passes.
172
+
173
+ ## Next diagnostic boundary
174
+
175
+ Use a bounded CPU-profile comparison to identify where time is spent before
176
+ changing the successful message path. Node 22 documents process-lifetime CPU
177
+ sampling and profile output on exit in its [CLI reference](https://nodejs.org/download/release/v22.21.0/docs/api/cli.html#--cpu-prof).
178
+ Any extended, instrumented workload is diagnostic only, not a replacement for
179
+ the default uninstrumented acceptance run.
180
+
181
+ This caution is consistent with [V8's real-world benchmarking discussion](https://v8.dev/blog/real-world-performance)
182
+ and [published VM warm-up research](https://arxiv.org/abs/1602.00602): a synthetic
183
+ score or presumed warm-up period does not alone establish representative stable
184
+ performance. These sources guide the investigation; they do not diagnose this
185
+ specific Redweb result.
186
+
187
+ The single bounded profile pair completed after the full local suite exited:
188
+ 500,000 measured messages, 128 outstanding, 2,000 warm-up, unchanged worker,
189
+ Node 22.21.0 CPU sampling. Both completed exact delivery and normal cleanup.
190
+ Sampled whole-process elapsed attribution was dominated by `writev` (baseline
191
+ 5.184s, candidate5.019s) and idle (3.578s,3.506s). Direct Redweb socket-frame self
192
+ samples were0.375s/0.278s and GC0.094s/0.081s. The critic independently found no
193
+ candidate-specific hotspot. About half the `writev` attribution came from client
194
+ requests, half from server replies; this is not pure CPU or syscall service time.
195
+
196
+ This workload is25 times the default and includes startup, warm-up, sorting and
197
+ cleanup without phase markers. It does not isolate the original short measured
198
+ window, prove the cause, or justify a runtime optimization. Do not repeat long
199
+ profiles or alter batching/GC based on this negative finding. A future targeted
200
+ investigation should observe the original20,000-message phase explicitly.
201
+ Raw profiles in `coverage/benchmark-cpu-diagnostic/` have SHA-256:
202
+
203
+ - `baseline.cpuprofile`: `34880286661985a48ea30e8c58cbfff861041b2b0baaa6243fc8736761d3b498`.
204
+ - `candidate.cpuprofile`: `2ef3e13fc9834ca707071cdf7e531fe1c8c7e586933c75a174d2a65938c90942`.
205
+
206
+ ## Original-phase diagnostic: one fixed ten-worker series
207
+
208
+ After the `bf01c2a` full regression exited successfully, one predeclared series
209
+ used the original 20,000 measured messages, 2,000 warm-up messages, 128-request
210
+ window and five alternating pairs. All ten workers completed exact delivery and
211
+ normal cleanup. No failed/default acceptance run was repeated or replaced.
212
+
213
+ The owned diagnostic worker preserves the original CommonJS resolution context.
214
+ Three exact-once insertions prepare the profiler before warm-up, wrap the existing
215
+ measured batch and close the profiler on completion/failure. Original and transformed
216
+ worker bytes are retained. The canonical worker, measurement/accounting helpers,
217
+ runtime entry/manifest/source tree and both resolved WebSocket packages are checked
218
+ before/after; each phase also records the hashes of actually loaded modules. No
219
+ application, socket or timer API is substituted. This is instrumentation, not an
220
+ uninstrumented acceptance measurement.
221
+
222
+ The implementation follows Node's documented
223
+ [CPU-profiler start/stop workflow](https://nodejs.org/download/release/v22.21.0/docs/api/inspector.html#cpu-profiler).
224
+ The window includes measured-batch construction, response handling, summarization
225
+ and completion microtasks; it excludes startup, warm-up and latency sorting.
226
+ Profiler setup perturbs execution. The requested interval is 1,000 microseconds,
227
+ but each roughly half-second profile contains only 305–316 samples on this Windows
228
+ host. About 18–20 ms is attributed to inspector control, and profile duration is
229
+ longer than the benchmark's own elapsed interval. Independent review verified
230
+ that the first sample is Inspector `post` in every trial and each trial's median
231
+ sampling delta is 1,546–1,549 microseconds. The 18.649–20.953 ms profile/batch
232
+ span difference is a boundary difference, not an estimate of profiling slowdown
233
+ inside the batch. Sampling weights are elapsed
234
+ attribution, not proof of pure CPU or syscall service time.
235
+
236
+ | Trial | Implementation | Measured ms | Profile ms | Samples | Direct Redweb socket-frame self ms |
237
+ | --- | --- | --- | --- | --- | --- |
238
+ | 1 | baseline | 490.6163 | 509.265 | 316 | 12.372 |
239
+ | 2 | candidate | 486.6625 | 507.615 | 315 | 4.637 |
240
+ | 3 | candidate | 477.3735 | 496.438 | 309 | 12.433 |
241
+ | 4 | baseline | 481.1249 | 500.439 | 309 | 12.485 |
242
+ | 5 | baseline | 479.5333 | 499.140 | 310 | 4.622 |
243
+ | 6 | candidate | 477.3278 | 497.395 | 309 | 13.904 |
244
+ | 7 | candidate | 482.7839 | 501.833 | 313 | 12.445 |
245
+ | 8 | baseline | 483.2845 | 503.428 | 312 | 12.416 |
246
+ | 9 | baseline | 473.8178 | 493.295 | 305 | 10.854 |
247
+ | 10 | candidate | 474.3387 | 494.325 | 307 | 3.098 |
248
+
249
+ Direct socket-frame attribution sums samples whose actual source URL is under
250
+ Redweb's `src/ws/`; it is not inclusive stack time. Per-trial raw frames and
251
+ weights remain available rather than relying only on pooled totals. `writev`
252
+ accounts for 196.556–246.052 ms and idle for 85.267–124.094 ms across the series;
253
+ both distributions overlap between implementations. These profiles do not
254
+ identify a consistent candidate-specific hotspot, prove why the original median
255
+ failed, justify speculative runtime changes or establish performance acceptance.
256
+ Direct Redweb attribution consists of only two to nine self samples per trial.
257
+ The critic independently verified all ten profile/phase hashes and worker outputs,
258
+ tooling identities and loaded-runtime comparisons, and approved this bounded
259
+ negative attribution result rather than a release-readiness claim.
260
+ The original 4.78495% throughput failure remains unresolved. No further profiling
261
+ series or automatic retry is implied by this result.
262
+
263
+ Retained directory: `coverage/benchmark-phase-diagnostic/`. Its `report.json`
264
+ SHA-256 is `151cb63390c18daf07ccd84ad4181b6b21e55a1ca245c108ebb770a46dc38ec6`.
265
+ Every profile and phase-record hash is recorded there, along with all ten original
266
+ worker outputs and the fixed order. Diagnostic driver SHA-256:
267
+ `ed135f76b5b7a3bbe43b294a8ea89986fc113756d23a4ce11db2aa796e3b3f8e`;
268
+ phase helper SHA-256:
269
+ `2381d7b28eec21ba6c9b9784426f75e877e7fcfc879058c52ea4282ea46bc851`.
270
+ The scripts are retained under ignored `coverage/`, not shipped or claimed as
271
+ fully covered production tooling. No acceptance threshold or frozen file changed.
272
+
273
+ ## Verified implementation checkpoint
274
+
275
+ At `43c6d73`, full pretest/type/regression passed1,098 tests/110 suites in614.552s,
276
+ with two POSIX-only skips and all-four100% of the unchanged91-file library scope
277
+ (5,449 statements,4,046 branches,978 functions,4,468 lines). Full coverage report
278
+ SHA-256: `ce878c849923384e0903a0e424a615dfb3be885046e0dd1bbf5131d1d3d7f681`.
279
+ The final source implementation was unchanged during verification; this report's
280
+ research/evidence-only additions followed the implementation commit.
281
+ Both [PR33365382012](https://github.com/lakam99/redweb/actions/runs/33365382012)
282
+ and [push33365378641](https://github.com/lakam99/redweb/actions/runs/33365378641)
283
+ passed all Node18/20/22/24 and lifecycle/package/browser jobs. The critic verified
284
+ all21 actual remote file blobs and approved this increment, not release readiness.
285
+
286
+ After the local suite and profile workers exited, sequential resource checks
287
+ passed: default load6,643.491 messages/s,6.781ms p99 and contained slow consumer;
288
+ default metadata1,881.648 bytes/connection; server recovery all7,400 replies,
289
+ peak108.6388% and final96.6147% of warm heap. Client112.8972% remains diagnostic.
290
+ HTML load passed200 expired renders/110 clients/8,329,896-byte heap delta; JSX
291
+ 10,000rows passed48.1ms/1.3MiB. The30s/16-client soak passed all eight trends with
292
+ 4,368 sent/4,365 received (99.9313%, three missing—not lossless), empty final
293
+ registries,100.2593% final warm heap and native handles1→2. This is not a new
294
+ 60-minute soak. Audit found zero vulnerabilities with TLS verification retained.
295
+
296
+ Report hashes:
297
+
298
+ - `coverage/43c6d73-resource-gates.json`: `20c94f067880295c5cae23beb2df57047f2f17792779af12afbf3f42fd5cc13a`.
299
+ - `coverage/43c6d73-short-soak.json`: `70f396696b05da057e7c0e258d96335fb89e1ba038c4bc7ee27645cc924dcddf`.
300
+ - `coverage/server-recovery-43c6d73/report.json`: `6f82e64382adf0e6c4eebaf17d70460d411dad0862e0ba1d0a093ea0a35334f5`.
301
+
302
+ Site `caa166f` synchronizes the43c6d73 catalogue locally:98pages/154assets,
303
+ real filesystem rollback/HTTP/link/download checks, six tests and100%
304
+ line/branch/function coverage across seven documentation modules. It used the
305
+ linked checkout while core tests ran, not an isolated published renderer or clean
306
+ performance environment. No publication, deployment or merge occurred. Default
307
+ throughput acceptance and remaining private-tool coverage remain open.
@@ -0,0 +1,191 @@
1
+ # Browser verification ownership and failure handling
2
+
3
+ Browser verification must fail honestly without skipping cleanup. Explicit fault
4
+ tests found that an exception from a debugging socket's `terminate()` could skip
5
+ browser and server shutdown. Exceptions from fallback `stderr.destroy()` or
6
+ `unref()` could do the same. A late tab's release error was not accounted for.
7
+ Five packed-verifier regressions failed before the correction. Separately, the
8
+ browser coverage coordinator used a raw, truthiness-based failure accumulator,
9
+ which could lose a falsy rejection.
10
+
11
+ These are demonstrated unit fault/control-flow defects, not evidence that a
12
+ native Chrome process leaked during a successful historical run.
13
+
14
+ ## Shared ownership, unchanged browser protocol
15
+
16
+ `BrowserPages` is a small shared owner used by the packed-browser verifier and
17
+ browser-coverage coordinator. It observes original page-opening promises before
18
+ the caller's timeout race, records returned tabs, closes tabs arriving during
19
+ cleanup, and boundedly accounts for outstanding openings. A still-unsettled
20
+ opening marks cleanup uncertain and retains the workspace, even if later browser
21
+ shutdown succeeds. Late release failures remain recorded on that owner. Closing
22
+ is idempotent; a closing owner refuses new pages.
23
+
24
+ Each tab release and subsequent browser/fallback/server/peer cleanup is attempted
25
+ independently. Errors use the existing `verificationError` normalizer, preserving
26
+ primary failures and secondary cleanup failures. No new browser protocol client,
27
+ runtime dependency or generic process manager was introduced. The frozen browser
28
+ and network helpers remain unchanged. Terminating a debugging socket is a release
29
+ request, not independent proof of every browser descendant's termination; the
30
+ existing browser exit checks and conservative workspace retention remain in force.
31
+
32
+ The isolated package harness copies the same owner alongside its other unchanged
33
+ verification inputs (24 files rather than 23). It still verifies copied bytes,
34
+ package immutability and isolated runtime dependency resolution.
35
+
36
+ ## Maintained tests and exact scope
37
+
38
+ `npm run verify:package:browser:coverage` passes 42 tests across four suites in
39
+ 6.063 seconds on Windows / Node 22.21.0 / Chrome 152.0.7977.64:
40
+
41
+ - 24 explicit packed-verifier boundary units cover success, acquisition,
42
+ assertions, late tabs, cleanup and fallback failures.
43
+ - Six explicit page-owner units cover idempotence, rejected/late/unsettled
44
+ openings, promise ownership and multiple release failures.
45
+ - Eleven targeted browser-coordinator units cover falsy failures and independent
46
+ tab/peer/browser/fallback cleanup. They do not claim whole-coordinator coverage.
47
+ - One native integration test runs the existing counter, chat delivery/escaping,
48
+ draft preservation, reconnect and disconnect checks through actual Chromium,
49
+ HTTP and WebSockets, with no API replacements.
50
+
51
+ That native test uses the checkout. It does not alone certify an independently
52
+ installed archive; the existing isolated-package gate supplies that separate
53
+ evidence. Eleven package-harness compatibility tests also pass. The native test's
54
+ ten-minute outer allowance covers the unchanged sequential 12-second operations,
55
+ bounded launch attempts and cleanup. CI allows 15 minutes for the scoped command
56
+ and retains its report for 30 days. These are failure supervision budgets, not
57
+ increased runtime or inner operation limits.
58
+
59
+ All-four 100% covers exactly two private files: 131 statements, 26 branches,
60
+ 20 functions and 103 lines. The VM maps are explicitly opt-in and do not enlarge
61
+ the normal library scope.
62
+
63
+ | Source | SHA-256 |
64
+ | --- | --- |
65
+ | `scripts/lib/BrowserPages.js` | `34a11cd3bebe213a082b2bb3d250f5f6e66b62533750c008e086a11d132b6c7c` |
66
+ | `scripts/lib/verify-packed-browser.js` | `6fb59772d165d32d08ab8670f3e4724f9ae8f02be9bda241f855e10dc03f8b93` |
67
+ | `scripts/verify-browser-coverage.js` (targeted units and native behavior, not full direct coverage) | `43a37063d17eb4f1f5211cd3c32456a269eb7560a929c5301ce1b81de70bba1a` |
68
+ | `scripts/lib/PackedBrowserHarness.js` | `e6ce226fafbb96bb1dcd16979008563f13872f7ca606dea73b73b3dddf867d80` |
69
+
70
+ `coverage/packed-browser-verifier/coverage-final.json` SHA-256:
71
+ `1d64027c49374a353a49f56272c39c6efda656979f075c2be1f81aac14d9a29b`.
72
+
73
+ ## Actual emitted-browser gates
74
+
75
+ The complete native runtime and development-refresh gates pass in ordinary and
76
+ instrumented modes with matched case inventories. Runtime remains all-four 100%
77
+ over 426 statements, 262 branches, 64 functions and 351 lines. Refresh remains
78
+ all-four 100% over 82 statements, 44 branches, 12 functions and 71 lines. Actual
79
+ history restoration, draft guards, malformed responses, outage/recovery, server
80
+ selection updates and feedback/morph/ownership cases are preserved.
81
+
82
+ | Report | Run | SHA-256 |
83
+ | --- | --- | --- |
84
+ | `coverage/browser-runtime/report.json` | `857b6627-5cc6-45ce-ae86-c7744089ec41` | `ca76701673c19cc4594f54ce98888847eca54337d46cc51bc9fcefe2abed061f` |
85
+ | `coverage/browser-refresh/report.json` | `fac8557c-a2b5-4d84-924a-3e9c69d1a208` | `efd8e608dc2fd9a188ee87f856337675e03860c38a531a75d5ffde659ea7af0d` |
86
+
87
+ ## Isolated package and regression boundary
88
+
89
+ The complete isolated-package gate passed with published `redweb-client@0.2.0`,
90
+ matching its committed registry identity and all four tested runtime bundle hashes.
91
+ It passed installed counter/chat/draft/reconnect/disconnect acceptance, all source-free
92
+ starters and executable documentation, compiled action/room consumers, static export,
93
+ and the copied acceptance/runtime/refresh harness. No runtime modules were replaced.
94
+
95
+ Tested Redweb archive SHA-256:
96
+ `0fb329edbf09e74a47a1ff8da565a3e155bc118bed5826b09560fd227f1097d8`.
97
+ That archive was packed before subsequent evidence-only README/documentation edits.
98
+ The retained browser phase report is
99
+ `coverage/packed-browser/45f01d8a-e1b5-42a5-a8b3-1521b195c775/report.json`, SHA-256:
100
+ `2ee3802bbb556a2811630c859b07e112a017ac294dc6a82570a4b38f9579878e`.
101
+ It records all three phases passing, 207 package files and 24 harness files, with
102
+ harness SHA-256 `f7066e63ead88c38d34d773df6e86114b223bec3ad9db39f3b02c9e0f0e54818`.
103
+
104
+ The senior critic approved the ownership/aggregation design, shared use, budgets,
105
+ documentation and exact source/report identities. Pretest/generated/type checks
106
+ and four documentation units pass. The completed root regression for `f96ba79`
107
+ passes 1,456 tests across 138 suites in 754.054 seconds, with two POSIX-only skips.
108
+ It includes the 42 browser-owner and 26 lifecycle cases absent from the preceding
109
+ 1,388-test inventory. Exactly 91 library files remain all-four 100%: 5,449
110
+ statements, 4,046 branches, 978 functions and 4,468 lines.
111
+
112
+ | Full regression evidence | SHA-256 |
113
+ | --- | --- |
114
+ | `coverage/browser-owner-full-results.json` | `6b446101550f58a23eef75af9cea6b8df2318c9812eba1e4f7595906a51d941b` |
115
+ | `coverage/coverage-final.json` | `b7ddd801caa759a33ebe5a5fb7a5175792eb97defb7c65ff33b6184b6425e6cd` |
116
+
117
+ The linked-client authored-source gate also passes: 77 tests in each ordinary and
118
+ instrumented mode, five worker reports, and matching native Chromium inventories
119
+ including 58 protocol and 43 client-network assertions per mode. Its exact scope
120
+ remains 791 statements, 521 branches, 125 functions and 659 lines, all 100%.
121
+ The source-built ordinary bundles match the linked production build. The separate
122
+ 26-test collector/preflight/report suite passes at its two-file 100% scope.
123
+
124
+ Run `efd9784b-b6d9-4f9e-affe-18080e6cb2cf` under `coverage/client-source/` retains:
125
+
126
+ | Client evidence | SHA-256 |
127
+ | --- | --- |
128
+ | `summary.json` | `b59f08ab081699532d5d17e2643113c2ebe9122167028d4d52bdbacc9eddbaa4` |
129
+ | `coverage.json` | `8673e236f675d741cb0f55d4f4bf630f2e2a50c2f2f76f856622558491ac8009` |
130
+
131
+ These runs use Windows / Node 22.21.0 / Chrome 152.0.7977.64. They do not relabel
132
+ the separate Node-only V8 diagnostic as passing. The existing npm links and the
133
+ user's client version edit are unchanged. Both hosted workflows for preceding
134
+ `377f029`, `1697f33` and `726b9a3` passed; `f96ba79` hosted results were still
135
+ running when this evidence was recorded and are not presumed passed.
136
+
137
+ No npm publication, deployment, benchmark waiver, new long soak or whole-repository
138
+ 100% claim is made. Remaining direct coordinator/browser-helper coverage and the
139
+ separate performance acceptance remain open.
140
+
141
+ ## Development-refresh launch cleanup follow-up
142
+
143
+ Independent audit found that the generated-app refresh coordinator acquired
144
+ Chromium before entering its cleanup block. If acquisition rejected, it did not
145
+ mark cleanup uncertain, so the workspace owner could remove the browser profile
146
+ without independently verified process termination. Its fallback pipe/reference
147
+ releases could also replace the original error or skip the next release.
148
+
149
+ Seven of thirteen initial explicit boundary units failed before correction.
150
+ These were injected launch/process/filesystem faults, not a claim that a native
151
+ Chromium leak or falsy shutdown rejection had been observed in a normal run.
152
+
153
+ The coordinator now acquires inside its existing guarded lifecycle. A launch
154
+ without a returned browser marks the workspace for retention; confirmed ordinary
155
+ or signal exit remains clean. Shutdown has a 15-second deadline. The existing
156
+ coercion-free error normalizer preserves falsy failures, and pipe/reference
157
+ releases are attempted independently while retaining every error. No new owner
158
+ class or public API was added; frozen helpers remain unchanged.
159
+
160
+ The expanded unit suite has 15 cases, including a pending shutdown using the real
161
+ 15-second deadline, an absent stderr pipe, both fallback failures, signal exit,
162
+ pre-acquisition failures and falsy errors. It passes in 15.828 seconds. Its
163
+ 45-second per-case allowance includes the shutdown deadline. The critic approved
164
+ the scope, ownership and test boundaries. These units do not establish complete
165
+ direct coverage of the coordinator; that file remains in the coverage audit.
166
+
167
+ The actual `npm run verify:development:browser` workflow separately exercises
168
+ generated realtime/site applications, real watchers and Chromium: TSX/CSS rebuilds,
169
+ failed-build recovery, draft/focus retention, explicit discard, state reset,
170
+ outage/reconnect, malformed/redirect/partial responses and delayed-script draft
171
+ guards under self-only CSP. The final-source run passed all of these checks on
172
+ Windows / Node 22.21.0 / Chrome 152.0.7977.64, including observed actual
173
+ back-forward-cache restoration. Pretest, generated docs, three type configurations
174
+ and four documentation units pass. It already runs in CI with a ten-minute outer limit.
175
+ The existing raw page/command acquisition and inner template/helper cleanup paths
176
+ remain a separate audit boundary; this correction does not claim they are all
177
+ bounded. Pipe/reference release is not proof of process termination.
178
+
179
+ Corrected coordinator SHA-256:
180
+ `7309fde16234bcdea8ae3cbe2870d181b1e5ad7a359f5c37dc0818b9c7cf5402`.
181
+ The complete regression at `bf01c2a` passed 1,486 tests/142 suites in 773.401
182
+ seconds, with two POSIX-only skips and all-four 100% of the 91-file library scope
183
+ (5,449 statements, 4,046 branches, 978 functions, 4,468 lines). This includes
184
+ the two native feedback-driver cases and all fifteen development-cleanup units.
185
+ Full result `coverage/development-refresh-full-results.json` SHA-256:
186
+ `f0a52e663b7f54d72a06e51890421b85e1fa89f8d5c7e0d587bf2452b3aff8a4`.
187
+ Corresponding `coverage/coverage-final.json` SHA-256:
188
+ `d9669b60e15270da98bce1a04f9e515fbe93fe9cbefa278326ef525af32c403a`.
189
+ Both `69dcbf8` and `9897924` hosted workflows passed completely; latest hosted
190
+ results remain separate. The critic approved all seven actual remote `bf01c2a`
191
+ blobs and their source/documentation identities.