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.
- package/CHANGELOG.md +166 -9
- package/README.md +177 -523
- package/bin/redweb.js +11 -20
- package/client.d.ts +7 -2
- package/config/tsconfig.json +14 -14
- package/contract.d.ts +45 -0
- package/contract.js +5 -0
- package/docs/ACTION_INPUT_VERIFICATION.md +96 -0
- package/docs/ADMISSION_TIMEOUT_VERIFICATION.md +69 -0
- package/docs/AGENT_ACCESS.md +35 -0
- package/docs/AGENT_EVALUATION.md +58 -0
- package/docs/AGENT_READY_ACCEPTANCE.md +763 -0
- package/docs/APPLICATION_RECORDER_VERIFICATION.md +50 -0
- package/docs/BENCHMARK_VERIFICATION.md +307 -0
- package/docs/BROWSER_OWNER_VERIFICATION.md +191 -0
- package/docs/CLI.md +116 -0
- package/docs/CLIENT_DEVELOPMENT.md +152 -0
- package/docs/CLIENT_POLISH_VERIFICATION.md +282 -0
- package/docs/COVERAGE_COUNTER_VALIDATION.md +109 -0
- package/docs/COVERAGE_SCOPE_AUDIT.md +1183 -0
- package/docs/DEVELOPMENT.md +79 -0
- package/docs/DIAGNOSTIC_COMPATIBILITY.md +76 -0
- package/docs/DOCUMENTATION.md +37 -0
- package/docs/FEEDBACK_COMMAND_VERIFICATION.md +228 -0
- package/docs/GETTING_STARTED.md +58 -0
- package/docs/JSX_PERFORMANCE_VERIFICATION.md +59 -0
- package/docs/LIVE_HTML.md +169 -21
- package/docs/LIVE_HTML_LOAD_VERIFICATION.md +98 -0
- package/docs/MIGRATION.md +28 -0
- package/docs/MULTIPLAYER_OPERATIONS.md +26 -4
- package/docs/ORIGINAL_RECOVERY_VERIFICATION.md +100 -0
- package/docs/PACKAGED_EXAMPLE_VERIFICATION.md +126 -0
- package/docs/POLISH_RELEASE_CHECKPOINT.md +91 -0
- package/docs/PROCESS_CLEANUP_OBSERVATION.md +61 -0
- package/docs/PROCESS_REAPING_VERIFICATION.md +30 -0
- package/docs/PRODUCTION_READINESS.md +11 -2
- package/docs/RECOVERY_CLIENT_HEAP.md +201 -0
- package/docs/RECOVERY_CODE_ATTRIBUTION.md +174 -0
- package/docs/RECOVERY_CODE_CENSUS.md +158 -0
- package/docs/RECOVERY_COMPARISON.md +103 -0
- package/docs/RECOVERY_DEOPTIMIZATION.md +169 -0
- package/docs/RECOVERY_FOLLOWUP_SPIKE.md +147 -0
- package/docs/RECOVERY_INVESTIGATION.md +229 -0
- package/docs/RECOVERY_RUNTIME_CONTROLS.md +181 -0
- package/docs/RELEASE_TRUST.md +58 -0
- package/docs/ROOM_AUTHORIZATION.md +49 -0
- package/docs/RUNTIME_DIAGNOSTICS.md +78 -0
- package/docs/SERVER_RECOVERY_CANDIDATE.md +185 -0
- package/docs/SOAK_ROTATION_OBSERVATION.md +160 -0
- package/docs/SOAK_VERIFICATION.md +154 -0
- package/docs/SOCKET_CONTRACTS.md +39 -0
- package/docs/SPLIT_RECOVERY_COVERAGE.md +83 -0
- package/docs/SPLIT_RECOVERY_ERROR_HANDLING.md +67 -0
- package/docs/STARTER_COORDINATOR_VERIFICATION.md +112 -0
- package/docs/STARTER_LIFECYCLE_VERIFICATION.md +75 -0
- package/docs/STARTER_REPORT_RETENTION.md +73 -0
- package/docs/VERIFICATION_EVIDENCE.md +2 -0
- package/docs/generated.json +2154 -0
- package/docs/guides/chatroom.md +27 -0
- package/docs/guides/http-websocket.md +28 -0
- package/docs/guides/jsx-without-react.md +26 -0
- package/docs/guides/realtime-dashboard.md +29 -0
- package/docs/guides/typed-websockets.md +26 -0
- package/docs/reference.json +1207 -0
- package/docs/snippets/room-access.tsx +51 -0
- package/docs/topics.json +21 -0
- package/examples/live-html/chatroom.js +207 -268
- package/examples/live-html/chatroom.tsx +167 -0
- package/examples/live-html/jsx-page.js +1 -1
- package/examples/live-html/jsx-page.tsx +1 -1
- package/examples/live-html/tsconfig.json +8 -7
- package/index.d.ts +170 -45
- package/index.js +2 -0
- package/jsx-dev-runtime.js +2 -2
- package/jsx-runtime.d.ts +7 -2
- package/package.json +88 -7
- package/recipes/add/artifact.test.cjs +57 -0
- package/recipes/add/live.tsx +18 -0
- package/recipes/add/socket-route.ts +24 -0
- package/recipes/chat/README.md +22 -0
- package/recipes/chat/app.test.cjs +105 -0
- package/recipes/chat/app.tsx +9 -0
- package/recipes/dashboard/README.md +43 -0
- package/recipes/dashboard/admin.ts +21 -0
- package/recipes/dashboard/app.css +16 -0
- package/recipes/dashboard/app.test.cjs +450 -0
- package/recipes/dashboard/app.tsx +86 -0
- package/recipes/dashboard/auth.ts +80 -0
- package/recipes/dashboard/cards.tsx +102 -0
- package/recipes/dashboard/rate-window.test.cjs +17 -0
- package/recipes/dashboard/store.ts +120 -0
- package/recipes/http-ws/README.md +11 -0
- package/recipes/http-ws/app.test.cjs +92 -0
- package/recipes/http-ws/app.tsx +36 -0
- package/recipes/realtime/README.md +8 -0
- package/recipes/realtime/app.test.cjs +15 -0
- package/recipes/realtime/app.tsx +28 -0
- package/recipes/shared/README.md +40 -0
- package/recipes/shared/app.css +8 -0
- package/recipes/shared/copy-assets.cjs +8 -0
- package/recipes/shared/network.cjs +59 -0
- package/recipes/shared/run-app.test.cjs +158 -0
- package/recipes/shared/run-app.ts +50 -0
- package/recipes/site/README.md +4 -0
- package/recipes/site/app.test.cjs +19 -0
- package/recipes/site/app.tsx +25 -0
- package/recipes/socket/README.md +39 -0
- package/recipes/socket/app.test.cjs +85 -0
- package/recipes/socket/app.tsx +30 -0
- package/recipes/socket/contract.ts +12 -0
- package/recipes/socket/handlers.ts +40 -0
- package/src/OwnedServerLifecycle.js +66 -0
- package/src/access/AccessPolicy.js +37 -0
- package/src/access/AuthenticationFailure.js +13 -0
- package/src/access/RequestFailure.js +33 -0
- package/src/access/failure-codes.json +25 -0
- package/src/async/BoundedOperation.js +62 -0
- package/src/cli/ActionReferences.js +193 -0
- package/src/cli/AdditionLayout.js +140 -0
- package/src/cli/FilePlan.js +94 -0
- package/src/cli/ProjectAddition.js +60 -0
- package/src/cli/ProjectConfig.js +26 -0
- package/src/cli/ProjectDoctor.js +112 -0
- package/src/cli/ProjectInitializer.js +20 -30
- package/src/cli/SourceInspector.js +207 -0
- package/src/cli/StaticSource.js +192 -0
- package/src/cli/arguments.js +62 -0
- package/src/cli/formatCommand.js +10 -0
- package/src/cli/run.js +57 -0
- package/src/cli/templates.js +86 -87
- package/src/context/RequestSnapshot.js +41 -0
- package/src/dataProperty.js +11 -0
- package/src/development/DevelopmentPageManager.js +48 -0
- package/src/development/Inspection.js +104 -0
- package/src/development/ObservedRenderer.js +42 -0
- package/src/development/description.js +35 -0
- package/src/development/loopbackRequest.js +27 -0
- package/src/development/refreshBrowser.js +96 -0
- package/src/development/refreshStyles.js +9 -0
- package/src/development/settings.js +17 -0
- package/src/docs/Documentation.js +182 -0
- package/src/htmx/ActionDefinition.js +44 -0
- package/src/htmx/Jsx.js +24 -8
- package/src/htmx/LiveHtmlServer.js +41 -19
- package/src/htmx/LivePage.js +63 -13
- package/src/htmx/PageIdentity.js +32 -0
- package/src/htmx/PageLifetime.js +37 -0
- package/src/htmx/PageManager.js +203 -74
- package/src/htmx/ReactiveRenderer.js +241 -0
- package/src/htmx/StaticExporter.js +1 -1
- package/src/htmx/TemplateRenderer.js +13 -7
- package/src/htmx/browserRuntime.js +2 -93
- package/src/htmx/metadata.js +19 -7
- package/src/validation/ActionInputError.js +12 -0
- package/src/validation/SchemaValidator.js +38 -0
- package/src/ws/AdmissionPolicy.js +24 -23
- package/src/ws/BaseSocketServer.js +53 -38
- package/src/ws/ContractValidationError.js +12 -0
- package/src/ws/HeartbeatMonitor.js +19 -7
- package/src/ws/ProtocolPolicy.js +1 -1
- package/src/ws/RoomAccess.js +82 -0
- package/src/ws/RoomRegistry.js +56 -6
- package/src/ws/RouteRuntime.js +56 -10
- package/src/ws/SocketContract.js +112 -0
- package/src/ws/SocketRoute.js +18 -0
- package/src/ws/protocol-schema.json +6 -1
- package/examples/live-html/chatroom.ts +0 -217
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Packaged-example verification
|
|
2
|
+
|
|
3
|
+
The installed-example probe now bounds listening, upgrade and action waits,
|
|
4
|
+
owns its socket immediately, and attempts socket closure and application shutdown
|
|
5
|
+
independently. Malformed responses, premature closes, send errors and timeouts
|
|
6
|
+
fail the action with their cause preserved. All action listeners and its timer
|
|
7
|
+
are removed on settlement. Success is printed only after confirmed cleanup.
|
|
8
|
+
The counter's development-route 404 body is consumed as well.
|
|
9
|
+
|
|
10
|
+
This changes verification tooling, not Redweb's public API or application runtime.
|
|
11
|
+
The original acceptance assertions remain: a production-only counter without
|
|
12
|
+
TypeScript or Zod; chat after explicit application Zod installation; actual chat
|
|
13
|
+
join, sanitized inspection, development revision/JS/CSS resources; exact emitted
|
|
14
|
+
client bytes; and generated page/component/socket-route compilation and tests.
|
|
15
|
+
|
|
16
|
+
## Isolation and ownership
|
|
17
|
+
|
|
18
|
+
The verifier copies the existing realtime harness, error normalizer and frozen
|
|
19
|
+
network helper unchanged, alongside the guarded action helper, into a child
|
|
20
|
+
support directory. Its WebSocket dependency is resolved from the installed
|
|
21
|
+
Redweb package and linked only after checking its real path stays inside this
|
|
22
|
+
consumer. The probe additionally checks transport identity. No repository
|
|
23
|
+
dependency is substituted into the package, and the support directory is not
|
|
24
|
+
an ancestor of the probe: it cannot satisfy the probe's absent-TypeScript/Zod
|
|
25
|
+
checks. Each install refreshes the owned transport link; a replaced regular
|
|
26
|
+
file is rejected, not deleted. Client identity is checked before and after
|
|
27
|
+
the complete consumer flow.
|
|
28
|
+
|
|
29
|
+
Commands reject truncated output. Each probe has a 90-second parent deadline;
|
|
30
|
+
other install/compiler/generated-test commands retain 120 seconds. The existing
|
|
31
|
+
workspace owner supervises processes and removes only its disposable consumer.
|
|
32
|
+
|
|
33
|
+
## Evidence
|
|
34
|
+
|
|
35
|
+
`npm run verify:package:examples:coverage` passed **40 tests / five suites** in
|
|
36
|
+
25.259 seconds on Windows / Node 22.21.0. The three-script original-source scope
|
|
37
|
+
is 100%: 178 statements, 44 branches, 20 functions and 150 lines.
|
|
38
|
+
|
|
39
|
+
Explicit unit fault boundaries cover action protocol/timing, coordinator cleanup,
|
|
40
|
+
preflight and installed dependency resolution/link tampering. The copied entrypoint
|
|
41
|
+
is evaluated unchanged with original-source Istanbul instrumentation. Its private
|
|
42
|
+
VM map joins the report only when that file is explicitly selected by the maintained
|
|
43
|
+
coverage command; it does not enlarge the ordinary library denominator.
|
|
44
|
+
|
|
45
|
+
No-mock integration uses actual WebSocket peers for success, unrelated frames,
|
|
46
|
+
malformed data, incorrect results, close and silent timeout. A separate installed
|
|
47
|
+
consumer packs the current source, runs real npm installs, HTTP/WebSockets and
|
|
48
|
+
development resources, then compiles and executes all three generated additions.
|
|
49
|
+
The first local installation timed out after certificate-chain verification failed;
|
|
50
|
+
it cleaned up and was not counted as passing. Using Node's supported
|
|
51
|
+
`--use-system-ca` option succeeded without disabling TLS verification.
|
|
52
|
+
|
|
53
|
+
The senior critic identified two test defects: cleanup could skip server closure,
|
|
54
|
+
and VM coverage could pollute the library denominator. Both were corrected before
|
|
55
|
+
the maintained successful run. CI retains the scoped report for 30 days and
|
|
56
|
+
allows 30 minutes for all bounded install/verification phases.
|
|
57
|
+
|
|
58
|
+
Source SHA-256 identities:
|
|
59
|
+
|
|
60
|
+
- `scripts/lib/example-dependency-probe.cjs`: `3a2b575129544e5497f44fd5e0f0ab574bc4da13ed560219b0f8f1d830b49547`
|
|
61
|
+
- `scripts/lib/performProbeAction.js`: `21dbbe345657b528b62464bb6e4ffef0f4ac8fe7be46a0fa3e7805c5ee67fd98`
|
|
62
|
+
- `scripts/lib/verify-example-dependencies.js`: `fd99d93475fcfbf228564b49bf8fd771e76f9f71bc0faa2f26d2b19d8c6fbbab`
|
|
63
|
+
|
|
64
|
+
Report `coverage/example-dependency-tools/coverage-final.json` SHA-256:
|
|
65
|
+
`51729c6f8604ad0a0b1f4e5c3d71688b75f833d3cb6b78155c7dc769cdc14c17`.
|
|
66
|
+
|
|
67
|
+
This is not whole-repository 100%, a new one-hour soak, a benchmark waiver or a
|
|
68
|
+
release approval. The full package/regression/hosted outcomes are recorded
|
|
69
|
+
separately as they complete. No publication, deployment or merge is implied.
|
|
70
|
+
|
|
71
|
+
The full `verify:live-html:package` gate also passed: isolated registry client
|
|
72
|
+
0.2.0, actual counter/chat/reconnect/disconnect browser acceptance, all-four 100%
|
|
73
|
+
emitted runtime and refresh browser coverage, every packaged starter, compiled
|
|
74
|
+
documentation/action/room examples, generated additions and static/JSX export.
|
|
75
|
+
The checked archive SHA-256 was
|
|
76
|
+
`739567465bb18a3bf3df9771c84b57f56f503769527ed9c90d96c59a76cd97c1`;
|
|
77
|
+
its retained browser report is
|
|
78
|
+
`coverage/packed-browser/f91d60fd-dffd-4c6e-806f-c8615ecc687c/`.
|
|
79
|
+
That archive preceded this explanatory document; it is runtime/tool behavior
|
|
80
|
+
evidence, not a byte identity claim about a later documentation-bearing tarball.
|
|
81
|
+
|
|
82
|
+
## Complete increment checkpoint
|
|
83
|
+
|
|
84
|
+
The complete local regression of the source set committed in `449a369` and
|
|
85
|
+
`551a905` passed **1,292 tests / 126 suites** in 690.807 seconds, with two
|
|
86
|
+
POSIX-only skips. Generated documentation, example/protocol snapshots and all
|
|
87
|
+
three TypeScript configurations passed. The ordinary coverage map contains
|
|
88
|
+
exactly the unchanged 91 library files: 5,449 statements, 4,046 branches,
|
|
89
|
+
978 functions and 4,468 lines, all 100%. Private probe instrumentation did not
|
|
90
|
+
enter that denominator.
|
|
91
|
+
|
|
92
|
+
Full map `coverage/coverage-final.json` SHA-256:
|
|
93
|
+
`c21b602f7d66b6105fa53a7ba0a5eb879d4b75e7ee560c8869beebdbee20f051`.
|
|
94
|
+
Inventory `coverage/example-dependency-full-results.json` SHA-256:
|
|
95
|
+
`8e2612d78a30ee3ce3bf28201e222bbfff9da21d599c1bff2556a904fa304a24`.
|
|
96
|
+
|
|
97
|
+
Sequential clean checks after regression passed on Windows / Node 22.21.0:
|
|
98
|
+
|
|
99
|
+
- Default socket load: 32 clients, 3,200 messages, 6,486.03 messages/second,
|
|
100
|
+
p99 7.2315 ms, slow consumer contained.
|
|
101
|
+
- Memory: 500 connections, three trials, 1,881.744 bytes of measured framework
|
|
102
|
+
metadata per connection against the unchanged 2,048-byte limit.
|
|
103
|
+
- HTML load: 200 expired renders, 110 live clients, 7,501,568-byte heap delta.
|
|
104
|
+
- JSX: 10,000 component rows, 52.5 ms, 0.6 MiB retained.
|
|
105
|
+
- Server-focused recovery: `server-steady-v1`, all 7,400 replies exact,
|
|
106
|
+
all server phases passing (highest 108.4196% of warm). The retained client
|
|
107
|
+
diagnostic exceeded 110% in later phases; this is not a client-memory fix.
|
|
108
|
+
- Thirty-second / 16-client soak: 4,368 sent, 4,363 received, five missing,
|
|
109
|
+
99.88553114% delivery, seven samples, all eight trends passing, final registries
|
|
110
|
+
zero, final heap 99.909556% of warm, handles 1→2. Not lossless or an hour soak.
|
|
111
|
+
- Production dependency audit: zero reported vulnerabilities, with certificate
|
|
112
|
+
validation retained through the Windows trusted certificate store.
|
|
113
|
+
|
|
114
|
+
Recovery report `coverage/server-recovery-package-final-20260831/report.json`
|
|
115
|
+
SHA-256: `071e98324524586cd8c8c50b35b68d5623f2f179e1e436076da62d7031055465`.
|
|
116
|
+
Soak report `coverage/soak-package-final-20260831.json` SHA-256:
|
|
117
|
+
`4bd8bd5e95054da8c27f1236ca42335663fde6e303c3a850db3e4a684079b371`.
|
|
118
|
+
|
|
119
|
+
The senior critic approved all 18 actual changed remote blobs at `551a905`, with
|
|
120
|
+
no remaining scoped finding. Both [PR CI](https://github.com/lakam99/redweb/actions/runs/33373452034)
|
|
121
|
+
and [push CI](https://github.com/lakam99/redweb/actions/runs/33373448945) passed
|
|
122
|
+
every Node 18/20/22/24 and lifecycle/package/browser job at that head. These are
|
|
123
|
+
implementation-head outcomes, not claims about a later evidence-only commit.
|
|
124
|
+
The npm links and frozen files remain unchanged. The historical room-phase
|
|
125
|
+
failure, unresolved throughput benchmark, remaining private-tool coverage and
|
|
126
|
+
publication/site alignment remain separately recorded release work.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Release-polish checkpoint
|
|
2
|
+
|
|
3
|
+
This document preserves the historical `3166468` checkpoint, including its failed
|
|
4
|
+
CI result. It is not the current release decision: the server-focused recovery
|
|
5
|
+
gate was subsequently adopted, while the original measurement remains a visible
|
|
6
|
+
non-blocking diagnostic. See [the reviewed recovery policy](SERVER_RECOVERY_CANDIDATE.md)
|
|
7
|
+
and [the current acceptance checklist](AGENT_READY_ACCEPTANCE.md) for later work
|
|
8
|
+
and remaining gates. The historical failure below is not relabelled as resolved.
|
|
9
|
+
|
|
10
|
+
These are verified checkpoints, not release approval. Redweb's runtime at
|
|
11
|
+
`3166468` was tested with published `redweb-client@0.2.0` on Windows,
|
|
12
|
+
Node 22.21.0 and Chrome 152.0.7977.64. Later candidate-verifier development changes
|
|
13
|
+
private tooling only; it is not claimed covered by these earlier checks.
|
|
14
|
+
|
|
15
|
+
## Current package and resources
|
|
16
|
+
|
|
17
|
+
The full clean registry package gate passed: actual counter/chat/dashboard browser
|
|
18
|
+
acceptance, reconnect/disconnect, six starters, executable recipes and source-free
|
|
19
|
+
consumers. It used no client override or consumer link. All 192 original package
|
|
20
|
+
files, 23 harness files and four explicitly external development tools passed
|
|
21
|
+
identity checks.
|
|
22
|
+
|
|
23
|
+
- Redweb archive SHA-256:
|
|
24
|
+
`f9bb0230becb7d1ab29e36a24ab9c35362d70e790bff3a9f3b064f9cb9b49439`.
|
|
25
|
+
- Report: `coverage/packed-browser/a03b7840-905c-4718-8f52-701d5fbd955c/report.json`.
|
|
26
|
+
- Report SHA-256:
|
|
27
|
+
`8c4c051b034998a9ad537c1240600e9b434402a296fd7cdabc69244071a9b0e4`.
|
|
28
|
+
- Frontend run `b71d6f8a-fc4a-4b7f-b61d-207274883b12`: all-four 100% over
|
|
29
|
+
426 statements, 262 branches, 64 functions and 351 lines.
|
|
30
|
+
- Refresh run `ac9073e4-c2a2-4baa-b6f1-4552a38c526f`: all-four 100% over
|
|
31
|
+
82 statements, 44 branches, 12 functions and 71 lines; actual bfcache restoration.
|
|
32
|
+
|
|
33
|
+
After package and site tests terminated, the unchanged resource gates ran
|
|
34
|
+
sequentially without inherited workload or instrumentation overrides:
|
|
35
|
+
|
|
36
|
+
| Gate | Observed result |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| Socket load | 32 clients, 3,200 messages; 6,686.50 messages/s, p99 7.233 ms; slow consumer contained |
|
|
39
|
+
| Metadata overhead | Three 500-client trials; 1,880.752 bytes/connection against 2,048 limit |
|
|
40
|
+
| Live HTML load | 200 expired renders, 110 clients; 8,080,280-byte heap delta |
|
|
41
|
+
| JSX rendering | 10,000 component rows in 49.2 ms; 1.3 MiB retained |
|
|
42
|
+
| Production audit | Zero reported vulnerabilities; TLS verification retained |
|
|
43
|
+
|
|
44
|
+
## Full 60-minute soak
|
|
45
|
+
|
|
46
|
+
One default run began at 2026-08-31T01:41:14Z. Its original owned terminal session
|
|
47
|
+
completed with exit 0; the resulting file was independently checked against all
|
|
48
|
+
delivery, registry, trend, heap and handle predicates. No competing local
|
|
49
|
+
load/browser/test run was started during the measurement. Runtime source and the
|
|
50
|
+
soak script were unchanged; candidate tooling edits do not enter the soak process.
|
|
51
|
+
|
|
52
|
+
- 3,600 seconds, 64 clients, 720 samples.
|
|
53
|
+
- 2,104,941 messages sent; 2,104,808 received: **99.9936815% delivery** against
|
|
54
|
+
the existing 99% requirement. This is not lossless delivery: 133 replies were
|
|
55
|
+
not received during rotating-connection traffic.
|
|
56
|
+
- Warm heap 11,378,888 bytes; peak 11,918,736; final 11,296,552:
|
|
57
|
+
**99.276414%** of warm, below 110%.
|
|
58
|
+
- All final client/room/session/in-flight registries empty. All eight resource
|
|
59
|
+
trend predicates passed. Handles moved from one to two, within the allowed one.
|
|
60
|
+
- Result: `coverage/polish-soak-3166468-20260831.json`, SHA-256
|
|
61
|
+
`f402a73e26f207fb5e55b53365912169350bba2fad0bb33d4856719db6df49c3`.
|
|
62
|
+
- Script SHA-256:
|
|
63
|
+
`ce30f8abcda0e018b8c586bd53dba775aebdaaaaf5275aa8bdf2b2f8d9b1d22b`.
|
|
64
|
+
|
|
65
|
+
## Historical CI failure at `3166468`
|
|
66
|
+
|
|
67
|
+
At the same `3166468` revision, the
|
|
68
|
+
[push run](https://github.com/lakam99/redweb/actions/runs/33347952379) passed
|
|
69
|
+
all jobs. The [PR run](https://github.com/lakam99/redweb/actions/runs/33347954450)
|
|
70
|
+
passed Node 18/20/24 and lifecycle checks but failed Node 22 recovery. Its unit and
|
|
71
|
+
integration suites passed first: 83 suites, 858 passing tests and five existing
|
|
72
|
+
platform skips, with all-four 100% instrumented-library coverage.
|
|
73
|
+
|
|
74
|
+
PR storm 3 peaked at **110.111615%**, above the unchanged 110% limit; final heap
|
|
75
|
+
was 98.786034% with empty registries. The push Node 22 peak was 109.607980%.
|
|
76
|
+
Neither final cleanup, the green push run nor the long-soak pass waives this
|
|
77
|
+
failure. No selective rerun occurred. The senior critic independently verified
|
|
78
|
+
the CI and package evidence.
|
|
79
|
+
|
|
80
|
+
The local documentation site imports the same canonical source at commit
|
|
81
|
+
`6b528f1`: 98 pages, 154 assets, real HTTP/link/download and filesystem-rollback
|
|
82
|
+
checks, six documentation tests with 100% line/branch/function coverage across
|
|
83
|
+
its seven declared modules. Catalogue SHA-256:
|
|
84
|
+
`8b4d805a7f845af30175423eebc4da610e579b9a51a74ccd8e6f56a5e0d4fa73`.
|
|
85
|
+
This is not whole-site coverage or a hosting deployment.
|
|
86
|
+
|
|
87
|
+
At this checkpoint, the maintainer had authorized development/review of a
|
|
88
|
+
server-focused candidate, not yet its adoption. Its protocol and results required
|
|
89
|
+
separate assessment.
|
|
90
|
+
Redweb publication, released-site alignment, final requirement audit and merge
|
|
91
|
+
remain pending. The original gate and failed results remain intact.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Starter cleanup: unresolved CI observation
|
|
2
|
+
|
|
3
|
+
The [Node 20 push job for 08348fb](https://github.com/lakam99/redweb/actions/runs/33403291226/job/99524600675)
|
|
4
|
+
failed the immediate descendant-disappearance assertion in
|
|
5
|
+
`tests/integration/starter-verifier.integration.test.js`: signal zero did not
|
|
6
|
+
throw. Ubuntu 24.04.4 / Node 20.20.2 / npm 10.8.2 reported 1,530 passed,
|
|
7
|
+
one failed and six skipped tests. Its other three matrix jobs passed; the
|
|
8
|
+
separate PR workflow passed completely. Neither result waives this failure.
|
|
9
|
+
|
|
10
|
+
Independent inspection found that the frozen process-tree helper signals the
|
|
11
|
+
Linux group but awaits only the direct child's exit. The workspace owner also
|
|
12
|
+
waits for that child's close; the descendant has ignored stdio, so this does not
|
|
13
|
+
establish descendant disappearance. Signal zero checks PID existence, and a
|
|
14
|
+
terminated but unreaped process can still exist. That makes an exit/reaping race
|
|
15
|
+
plausible, not proven for this run. A surviving process or reused PID remains
|
|
16
|
+
possible. See the primary [kill semantics](https://man7.org/linux/man-pages/man2/kill.2.html)
|
|
17
|
+
and [wait/reaping semantics](https://man7.org/linux/man-pages/man2/wait.2.html).
|
|
18
|
+
|
|
19
|
+
The old log lacks process state and start identity. Its fallback sends another
|
|
20
|
+
signal before waiting, so successful fallback is not proof that original cleanup
|
|
21
|
+
alone succeeded. The test now also requires the captured command error to be
|
|
22
|
+
the actual timeout, not merely contain the fixture's output marker.
|
|
23
|
+
|
|
24
|
+
The diagnostic-enabled ordinary Node 20 CI execution retains the existing immediate assertion,
|
|
25
|
+
two-second command limit and five-second fallback limit. The fixture records
|
|
26
|
+
initial process identities. If an assertion fails, it samples descendant and
|
|
27
|
+
group-leader identity **before the fallback signal**, appends the command
|
|
28
|
+
error/cause and observations to the thrown error, and preserves them if fallback
|
|
29
|
+
also fails. No additional acceptance wait or successful-run retry is added.
|
|
30
|
+
|
|
31
|
+
A separate Linux-only negative control deliberately puts its owned descendant
|
|
32
|
+
in a different process group. It requires the unchanged immediate assertion to
|
|
33
|
+
fail, verifies that the diagnostic identifies the live escaped process and its
|
|
34
|
+
unchanged start identity, then confirms that the existing fallback terminated it.
|
|
35
|
+
This is not a reproduction of the original failure or permission to accept escape.
|
|
36
|
+
It must fail specifically at the immediate disappearance assertion and must not
|
|
37
|
+
return an aggregate fallback failure. Independent review caught that accepting
|
|
38
|
+
any error would have allowed a failed fallback to masquerade as a passed control.
|
|
39
|
+
Observation-read errors are recorded separately from the original command error;
|
|
40
|
+
a real malformed-file test verifies that they cannot replace the timeout evidence.
|
|
41
|
+
|
|
42
|
+
The helper retains only PID, state, parent/group/session IDs, process start ticks,
|
|
43
|
+
platform and observation time. It excludes command names, arguments and
|
|
44
|
+
environment. Start ticks remain text, avoiding integer precision loss. Field
|
|
45
|
+
positions follow [proc_pid_stat](https://man7.org/linux/man-pages/man5/proc_pid_stat.5.html).
|
|
46
|
+
Unsupported platforms and failed reads are explicit. A post-assertion snapshot
|
|
47
|
+
is not the process state at the exact failing instant; a later `ENOENT` or a
|
|
48
|
+
passing run is inconclusive. Direct-root exit/signal timestamps are still absent.
|
|
49
|
+
|
|
50
|
+
Local Windows tests exercise parsing and the real npm descendant workflow, but
|
|
51
|
+
cannot reproduce Linux reaping or validate the native `/proc` branch. The local
|
|
52
|
+
Docker Linux engine was unavailable; it was not started or reconfigured.
|
|
53
|
+
The final Windows run passed 21 tests with the one Linux-only negative control
|
|
54
|
+
skipped (7.439 seconds). Both [PR](https://github.com/lakam99/redweb/actions/runs/33406107275)
|
|
55
|
+
and [push](https://github.com/lakam99/redweb/actions/runs/33406101028) workflows
|
|
56
|
+
for `4fe0145` subsequently passed all jobs. The actual Node 20.20.2 push job
|
|
57
|
+
passed 1,573 tests with seven platform skips in 823.853 seconds, including the
|
|
58
|
+
Linux escaped-child negative control and malformed-observation regression.
|
|
59
|
+
This validates the diagnostic on Linux, not the cause of the original failure.
|
|
60
|
+
Frozen helpers/evaluation evidence, runtime code and acceptance thresholds remain
|
|
61
|
+
unchanged. No cause or fix for the original CI failure is claimed yet.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Descendant-reaping test synchronization
|
|
2
|
+
|
|
3
|
+
PR CI at `d24d734`, [run 33353677136, Node 22 job
|
|
4
|
+
99371666483](https://github.com/lakam99/redweb/actions/runs/33353677136/job/99371666483),
|
|
5
|
+
failed one test: the descendant PID was still addressable immediately after a
|
|
6
|
+
timed-out build returned. The job passed 915 tests, skipped five platform-specific
|
|
7
|
+
cases and failed one; library coverage remained all-four 100%. Its recovery step
|
|
8
|
+
was correctly skipped, not counted as passed. Other matrix and lifecycle jobs passed.
|
|
9
|
+
|
|
10
|
+
The frozen process helper sends a process-group kill on POSIX and awaits the root
|
|
11
|
+
process exit. That event does not notify the test that every descendant has been
|
|
12
|
+
reaped. Linux's [kill(2)](https://man7.org/linux/man-pages/man2/kill.2.html) and
|
|
13
|
+
[wait(2)](https://man7.org/linux/man-pages/man2/waitpid.2.html) documentation explain
|
|
14
|
+
that an exited process can retain a visible PID until reaping. The failed log
|
|
15
|
+
does not establish whether that PID was running, dying, a zombie, or reused; the
|
|
16
|
+
historical failure is not relabelled as proven harmless.
|
|
17
|
+
|
|
18
|
+
The three descendant checks now reuse the existing bounded condition observer.
|
|
19
|
+
They require actual `ESRCH` within five seconds, preserve the final strict
|
|
20
|
+
process-existence assertion, and reject every other error. The observer neither
|
|
21
|
+
sends a signal nor treats zombies as absent. A new real-process negative control
|
|
22
|
+
proves a live survivor times out and remains alive until the test's separate
|
|
23
|
+
owner explicitly stops it. Original build/cleanup deadlines and frozen helpers
|
|
24
|
+
are unchanged; outer test deadlines now cover the sum of the existing phases
|
|
25
|
+
plus the bounded observation.
|
|
26
|
+
|
|
27
|
+
All eight actual-process tests passed locally on Windows/Node 22.21.0 in 4.84
|
|
28
|
+
seconds. Linux verification follows through ordinary CI, not selective retries.
|
|
29
|
+
The senior critic approved the synchronization contract and negative control;
|
|
30
|
+
this is a test correction, not a server recovery-policy or runtime change.
|
|
@@ -20,6 +20,13 @@ WebSocket provides an ordered byte stream while a connection remains healthy. Re
|
|
|
20
20
|
## Roadmap gates
|
|
21
21
|
|
|
22
22
|
1. **Bounded transport:** pre-upgrade admission, origin policy, rate limits, slow-consumer enforcement, bounded ordered processing, payload limits, and route-level heartbeat.
|
|
23
|
+
|
|
24
|
+
Heartbeat expiry is deferred to the event-loop check phase before terminating a
|
|
25
|
+
peer, allowing already-dispatched pong handling to win after a server stall; an
|
|
26
|
+
actually silent peer is terminated by the deferred check.
|
|
27
|
+
`timeoutMs` is therefore a liveness threshold subject to event-loop scheduling,
|
|
28
|
+
not a hard wall-clock resource limit. The deferral owns at most one pending check
|
|
29
|
+
per expired connection; bound connections and queues independently.
|
|
23
30
|
2. **Multiplayer grouping:** route-scoped rooms, atomic membership cleanup, bounded session resumption, fixed-step services, and vendor-neutral metrics.
|
|
24
31
|
3. **Horizontal composition:** draining/readiness, adapter lifecycle, loop prevention, bounded validation, placement hooks, and documented partition behavior.
|
|
25
32
|
4. **Protocol and clients:** version negotiation, stable envelopes and error codes, generated client-facing types, binary replication hooks, and operational examples.
|
|
@@ -35,11 +42,13 @@ WebSocket provides an ordered byte stream while a connection remains healthy. Re
|
|
|
35
42
|
- Broadcast serializes once and remains O(n) in selected recipients.
|
|
36
43
|
- Slow clients cannot grow framework-owned memory without bound.
|
|
37
44
|
- A 60-minute soak shows no monotonic growth in timers, listeners, rooms, sessions, or queues.
|
|
38
|
-
-
|
|
45
|
+
- The blocking `server-steady-v1` reconnect gate requires every storm to retain at most 110% of the same warmed **server** heap after expiry and forced collection. Exact delivery, empty measured registries, unchanged inputs, complete logs and normal worker cleanup are mandatory. Client heap is reported separately; the original shared-process diagnostic remains visible and non-blocking, without relabelling its failures.
|
|
39
46
|
- Readiness becomes false before draining and shutdown completes within its documented bound.
|
|
40
47
|
|
|
41
48
|
The independent senior-review gate rejects releases that weaken any invariant, hide ambiguous delivery semantics, add mandatory brokers or identity libraries, or substitute coverage percentages for race, load, soak, and failure evidence.
|
|
42
49
|
|
|
50
|
+
See [operations verification](MULTIPLAYER_OPERATIONS.md#verification) for the current commands and the distinction between server acceptance and the original diagnostic. These are required gates, not a statement that the current development candidate has passed them; consult the [release checklist](AGENT_READY_ACCEPTANCE.md) for outstanding failures.
|
|
51
|
+
|
|
43
52
|
## Horizontal composition contract
|
|
44
53
|
|
|
45
54
|
- Placement runs before upgrade within the admission timeout. Redirects must use `wss`, contain no credentials or fragment, and may be restricted with `allowedPlacementOrigins`. Plain `ws` placement requires the explicit `allowInsecurePlacement` escape hatch for private development networks.
|
|
@@ -65,4 +74,4 @@ The independent senior-review gate rejects releases that weaken any invariant, h
|
|
|
65
74
|
- Timed-out admission hooks that ignore cancellation retain their reservation until they actually settle, preventing repeated timeout waves from accumulating unbounded application work.
|
|
66
75
|
- Fixed-step services clamp retained lag with `maxRetainedLagMs`; dropped time is observable rather than replayed forever.
|
|
67
76
|
- Session count, ID length, and lifetime are bounded by Redweb. Session `data` is application-owned, so applications must validate and cap its shape and byte size before storing it.
|
|
68
|
-
- Fully enabled idle routes have a 2 KiB framework-metadata budget per connection. Disabled features retain the legacy path
|
|
77
|
+
- Fully enabled idle routes have a 2 KiB framework-metadata budget per connection. Disabled features retain the legacy path; the performance gate compares against an explicitly prepared, identified release baseline. Historical 0.8 evidence does not establish performance against a newer baseline.
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Client heap survival investigation — 2026-08-30
|
|
2
|
+
|
|
3
|
+
Status: surviving code-related structures identified in the instrumented client;
|
|
4
|
+
the original recovery acceptance gate remains open. This follows the
|
|
5
|
+
[deoptimization investigation](RECOVERY_DEOPTIMIZATION.md).
|
|
6
|
+
|
|
7
|
+
## Predeclared method
|
|
8
|
+
|
|
9
|
+
One measured run after tests and senior critic preflight:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
node scripts/diagnostics/recovery-split.cjs client-heap
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The existing seven-phase, 7,400-connection split workload is unchanged. Both workers
|
|
16
|
+
retain normal `--expose-gc` flags; no compilation/deoptimization logger or coverage
|
|
17
|
+
is enabled. Only the native `ws` client captures snapshots, through separate RPCs
|
|
18
|
+
after its warm and storm-5 samples have returned. Server and client measurements
|
|
19
|
+
precede capture; the later workload therefore observes the warm snapshot's effects.
|
|
20
|
+
The client still does not import Redweb or redweb-client. No concurrent tests run
|
|
21
|
+
during measurement, and no rerun is selected because its memory result is greener.
|
|
22
|
+
|
|
23
|
+
[Node's pinned V8 API](https://nodejs.org/download/release/v22.21.0/docs/api/v8.html)
|
|
24
|
+
warns that snapshot generation blocks execution and may need roughly twice the
|
|
25
|
+
heap's memory. Its format is undocumented and version-specific. The analyzer is
|
|
26
|
+
pinned to Node 22.21.0 / V8 12.4.254.21-node.33. Snapshot capture initiates collection;
|
|
27
|
+
[Chrome's snapshot documentation](https://developer.chrome.com/docs/devtools/memory-problems/heap-snapshots)
|
|
28
|
+
distinguishes comparison, containment, shallow sizes and retained sizes. Our
|
|
29
|
+
comparison reports shallow bytes and graph paths, **not** dominators or retained size.
|
|
30
|
+
|
|
31
|
+
## Capture and analysis safeguards
|
|
32
|
+
|
|
33
|
+
- Raw snapshots stay in a newly created local temporary directory, outside the
|
|
34
|
+
repository. They may contain secrets; do not upload or commit them. Unix permissions
|
|
35
|
+
are restricted to the owner; Windows uses the current user's inherited temporary
|
|
36
|
+
directory ACL (the Unix mode is not an independent Windows privacy guarantee).
|
|
37
|
+
- Files are opened exclusively before capture and limited to 64 MiB of saved data.
|
|
38
|
+
Partial/failed captures invalidate the run and cannot be reused. This limit does
|
|
39
|
+
not bound native generation memory or its pause; the coordinator has a 60-second
|
|
40
|
+
capture deadline and owns child termination/cleanup.
|
|
41
|
+
- Both captures must have the same worker-generated UUID/PID identity, runtime,
|
|
42
|
+
ordered phases and verified SHA-256/file lengths. Snapshots are parsed offline,
|
|
43
|
+
after the workers exit, not inside the measured client.
|
|
44
|
+
- The existing validated graph parser is shared with the earlier marker-based
|
|
45
|
+
analyzer. Parsing is capped at 250,000 nodes and 1,500,000 edges per snapshot.
|
|
46
|
+
- A single breadth-first search starts at the validated synthetic root, excluding
|
|
47
|
+
weak and shortcut edges. Paths use only fixed category labels and edge kinds;
|
|
48
|
+
arbitrary function/property names, node IDs, addresses and contents are withheld.
|
|
49
|
+
Paths over 32 edges are explicitly truncated; unreachable nodes remain counted.
|
|
50
|
+
These are shortest paths in the filtered snapshot graph, not unique ownership
|
|
51
|
+
proofs or a complete interpretation of ephemeron/engine retention semantics.
|
|
52
|
+
- Added, removed and surviving IDs are separated. Survivor bytes/counts before and
|
|
53
|
+
after are both included, so size/category changes reconcile with gross deltas.
|
|
54
|
+
The final public comparison is bounded to 1 MiB; errors are redacted. Complete
|
|
55
|
+
category/cohort/path-status totals are retained; at most 128 detailed path groups
|
|
56
|
+
are shown, prioritizing added objects then descending shallow bytes. Omitted
|
|
57
|
+
group counts are explicit. These examples are not representative statistics.
|
|
58
|
+
|
|
59
|
+
This run can show which code-related objects survive in a snapshot-instrumented
|
|
60
|
+
client. It cannot identify the earlier run's exact surviving compiled versions,
|
|
61
|
+
equate instruction sizes with snapshot self sizes, or explain every byte of the
|
|
62
|
+
original shared-process recovery failure. No code amount is subtracted from heap
|
|
63
|
+
usage to manufacture acceptance.
|
|
64
|
+
|
|
65
|
+
## Verification before measurement
|
|
66
|
+
|
|
67
|
+
Sixteen focused unit and real snapshot/process/network tests pass. Native V8
|
|
68
|
+
coverage is 100% statements, branches, functions and lines across all five snapshot
|
|
69
|
+
capture/parser/analysis modules. Real integration tests use no mocks, check exact
|
|
70
|
+
request/reply IDs, exercise two captures in one worker, verify reusable listener
|
|
71
|
+
ports, reject altered identities/versions/lengths/hashes, enforce the capture size
|
|
72
|
+
limit, and preserve an existing file on overwrite attempts. Synthetic graph tests
|
|
73
|
+
cover cycles, weak/shortcut-only reachability, truncated paths and survivor changes.
|
|
74
|
+
The preexisting broader coordinator coverage gaps are not claimed closed by this
|
|
75
|
+
focused result.
|
|
76
|
+
|
|
77
|
+
## Original run and offline repair
|
|
78
|
+
|
|
79
|
+
Exactly one workload was run, at tooling commit `4d036b4`, from
|
|
80
|
+
20:37:09.177Z to 20:37:23.539Z. It reached the post-worker-cleanup comparison stage
|
|
81
|
+
after all 7,400 exact acknowledgements and empty client/server registries at every
|
|
82
|
+
sample. All four output logs were complete and empty. Source hashes were checked.
|
|
83
|
+
|
|
84
|
+
The run nevertheless **exited 1**: the initial detailed comparison was 1,391,590
|
|
85
|
+
bytes, exceeding the 1 MiB output cap. Its original report remains unchanged with
|
|
86
|
+
`deliveryAndCleanupPassed: false`. This is a failed diagnostic, not a release pass.
|
|
87
|
+
|
|
88
|
+
The correction at `bd68503` bounds detailed examples while preserving complete
|
|
89
|
+
numeric totals. Its new 3,000-path fixture checks omission accounting and output
|
|
90
|
+
size; a real CLI test checks provenance, redacted errors and overwrite refusal.
|
|
91
|
+
The same existing snapshots were reanalyzed offline, without another workload or
|
|
92
|
+
snapshot capture. Native coverage after the correction passed 17 tests and all-four
|
|
93
|
+
100% across the five snapshot modules. The senior critic independently reproduced
|
|
94
|
+
the reanalysis and verified hashes, reconciliation, omission counts and path totals.
|
|
95
|
+
|
|
96
|
+
Reproduction uses a new output file; it never overwrites the original report:
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
node scripts/diagnostics/HeapCodeComparison.cjs <original-report.json> <private-snapshot-directory> <new-summary.json>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## What survived
|
|
103
|
+
|
|
104
|
+
The snapshots contain 77,725 then 80,910 nodes: 4,771 added IDs, 1,586 removed IDs,
|
|
105
|
+
and 76,139 surviving IDs. Net snapshot shallow bytes increased by 937,387. The
|
|
106
|
+
complete V8 `code` category increased by 801,792 shallow bytes; it includes several
|
|
107
|
+
different kinds of internal data, not just executable instructions.
|
|
108
|
+
|
|
109
|
+
| Code-related category | Net shallow bytes |
|
|
110
|
+
| --- | ---: |
|
|
111
|
+
| Remaining unclassified code nodes | +543,408 |
|
|
112
|
+
| Deoptimization data | +113,880 |
|
|
113
|
+
| Relocation information | +91,608 |
|
|
114
|
+
| Bytecode arrays | +19,064 |
|
|
115
|
+
| Generic code objects | +14,520 |
|
|
116
|
+
| Feedback vectors | +9,928 |
|
|
117
|
+
| Constant pools | +7,440 |
|
|
118
|
+
| Feedback cells | +2,184 |
|
|
119
|
+
| Uncompiled data, combined | −240 |
|
|
120
|
+
|
|
121
|
+
These labels follow fixed tags in the pinned
|
|
122
|
+
[V8 snapshot generator](https://github.com/nodejs/node/blob/v22.21.0/deps/v8/src/profiler/heap-snapshot-generator.cc).
|
|
123
|
+
Unrecognized names remain unclassified. The other major net category was hidden
|
|
124
|
+
runtime data (+122,672 shallow bytes). These are distinct snapshot categories;
|
|
125
|
+
they must not be added to overlapping `getHeapCodeStatistics()` measurements.
|
|
126
|
+
|
|
127
|
+
There were no WebSocket, Sender, Receiver or Timeout instances in either snapshot.
|
|
128
|
+
All three Socket instances and all 51 HTTPParser instances survived unchanged,
|
|
129
|
+
with no additions. That narrows the evidence away from accumulating connection
|
|
130
|
+
instances in this client; it does not establish that every retained object is benign.
|
|
131
|
+
|
|
132
|
+
All 33,449 final code nodes are included in path totals: 33,441 have a path from the
|
|
133
|
+
root in the filtered graph; eight surviving nodes (512 shallow bytes) do not.
|
|
134
|
+
No path was depth-truncated. The 2,802 grouped paths yield 128 detailed examples
|
|
135
|
+
and 2,674 explicitly omitted groups. Some examples run through global handles,
|
|
136
|
+
closures and code objects; others include a Socket. A shortest path is neither a
|
|
137
|
+
unique owner nor evidence that such a Socket is a leftover workload connection.
|
|
138
|
+
|
|
139
|
+
## Observer effects and remaining causal question
|
|
140
|
+
|
|
141
|
+
| Phase | Server heap bytes | Client heap bytes |
|
|
142
|
+
| --- | ---: | ---: |
|
|
143
|
+
| Preconditioning | 10,176,480 | 6,596,520 |
|
|
144
|
+
| Warm, before first capture | 10,195,968 | 6,567,568 |
|
|
145
|
+
| Storm 1 | 10,480,392 | 7,498,024 |
|
|
146
|
+
| Storm 2 | 10,873,856 | 7,831,056 |
|
|
147
|
+
| Storm 3 | 10,965,904 | 8,014,120 |
|
|
148
|
+
| Storm 4 | 11,055,136 | 8,040,528 |
|
|
149
|
+
| Storm 5, before final capture | 9,925,432 | 8,054,112 |
|
|
150
|
+
|
|
151
|
+
Client heap growth was 1,486,544 bytes (122.63% of warm), while code/metadata
|
|
152
|
+
statistics grew by 534,410 bytes. Bytecode/metadata statistics changed from
|
|
153
|
+
758,616 to 666,216 after the warm snapshot. These readings are before capture,
|
|
154
|
+
whereas the snapshot inventories are collected during capture, with extra GC and
|
|
155
|
+
diagnostic machinery. The unequal deltas must not be treated as a missing-byte
|
|
156
|
+
equation or used to claim the original unsnapshotted growth is fully explained.
|
|
157
|
+
|
|
158
|
+
The next useful step requires **no new workload**: attribute the largest added
|
|
159
|
+
code/deoptimization groups to known Node, ws and harness functions through narrowly
|
|
160
|
+
allowlisted structural relationships in these snapshots. Distinguish module/cache
|
|
161
|
+
roots and standard-stream sockets from workload connections. This milestone does
|
|
162
|
+
not identify the exact earlier invalidated versions, prove exclusive retention,
|
|
163
|
+
explain all hidden data, or resolve the original recovery failure or historical
|
|
164
|
+
shutdown timeout. No speculative production optimization or acceptance change was made.
|
|
165
|
+
|
|
166
|
+
Follow-through: [offline function and root attribution](RECOVERY_CODE_ATTRIBUTION.md)
|
|
167
|
+
now records that analysis of the same snapshots, including persistent function
|
|
168
|
+
identities and all three standard-stream/prototype Socket roles. The original
|
|
169
|
+
capture and verification evidence below remains unchanged.
|
|
170
|
+
|
|
171
|
+
## Evidence identity
|
|
172
|
+
|
|
173
|
+
- Original local run: `coverage/recovery-split-f7owK8`.
|
|
174
|
+
- Original report SHA-256: `1b894777de9ec50f53faa7e66f144bfe4feb89793ae1bfe068365000833acbe7`.
|
|
175
|
+
- Warm snapshot: 7,512,482 bytes; SHA-256 `339a0fe74d9bb942c64a5514975b2918376004436125ca8af169ccdc86dfdaa3`.
|
|
176
|
+
- Final snapshot: 7,796,848 bytes; SHA-256 `7e494dbe82222c4045d673d5bd1cf79a953708025219ebb632fcaf0fdb59576d`.
|
|
177
|
+
- Separate offline report: `heap-reanalysis.json`, 88,196 bytes; SHA-256 `f3904afc8ee5786fec862737404f69ba1076cd46c8f828a5d530781c7dc64aa9`.
|
|
178
|
+
- Offline analyzer SHA-256: `afa8981ec976a6a9405207f4297257c518483941c919b2d3f0ffd868b3155392`.
|
|
179
|
+
|
|
180
|
+
The offline report includes the original report hash, unchanged failure status and
|
|
181
|
+
all analyzer input hashes. Raw snapshots remain private and local; no publication,
|
|
182
|
+
deployment, dependency change, npm-link change or merge occurred.
|
|
183
|
+
|
|
184
|
+
## Final verification
|
|
185
|
+
|
|
186
|
+
At implementation commit `bd68503`, the full suite passed **841 tests in 81 suites**
|
|
187
|
+
in 435.006 seconds, including the owned-HTTP-shutdown test. Pretest documentation,
|
|
188
|
+
generated examples/protocol types and all three TypeScript configurations passed.
|
|
189
|
+
The historical shutdown timeout is still unexplained, not waived by this pass.
|
|
190
|
+
|
|
191
|
+
Instrumented-library coverage remains all-four 100%: 5,445 statements, 4,044 branches
|
|
192
|
+
and 978 functions, none uncovered. The separate untransformed native snapshot-tool
|
|
193
|
+
run passed 17 tests with all-four 100% across `ClientHeapCapture`, `HeapSnapshotGraph`,
|
|
194
|
+
`HeapCodeComparison`, `recovery-heap-graph` and `recovery-heap-summary`, including the
|
|
195
|
+
offline CLI. Broader split-coordinator/worker coverage gaps remain outside that
|
|
196
|
+
five-module claim. No threshold was lowered or uncovered code excluded to obtain it.
|
|
197
|
+
|
|
198
|
+
- Full-suite JSON: `coverage/client-heap-full-suite.json`; SHA-256
|
|
199
|
+
`bb49cab38666d8d60c879aa970fcf44df494d7d900d5152548266662eea5d1cc`.
|
|
200
|
+
- Native snapshot-tool coverage JSON: `coverage/client-heap-native/coverage-final.json`;
|
|
201
|
+
SHA-256 `f90cdb7ce7e02d611f8c88d1fc3e224803f3dc57c51bba184969be880136a886`.
|