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,39 @@
|
|
|
1
|
+
# Shared socket contracts
|
|
2
|
+
|
|
3
|
+
Status: unreleased on `codex/agent-ready`; not part of npm 0.12.0.
|
|
4
|
+
|
|
5
|
+
A contract declares message payloads once. The same schema supplies runtime validation and inferred TypeScript types for senders and handlers. The URL still selects the route (`/match`), and the envelope's `type` selects an individual handler (`join`, `move`, `resume`). No socket decorators or second action dispatcher are required.
|
|
6
|
+
|
|
7
|
+
Start with `npx redweb init my-match --template socket` after installing a release containing this feature. During development, use the checked-out CLI or packed artifact instead of the published 0.12.0 command. The complete maintained example lives in [the socket recipe](../recipes/socket/README.md): [contract](../recipes/socket/contract.ts), [handlers](../recipes/socket/handlers.ts), [server](../recipes/socket/app.tsx), and [real-network tests](../recipes/socket/app.test.cjs).
|
|
8
|
+
|
|
9
|
+
Session ownership is separate from room fan-out. For authenticated group delivery,
|
|
10
|
+
see [room authorization](ROOM_AUTHORIZATION.md) and the complete
|
|
11
|
+
[shared page/private-room example](snippets/room-access.tsx).
|
|
12
|
+
|
|
13
|
+
## One schema, two sides
|
|
14
|
+
|
|
15
|
+
Import `defineSocketContract` from `redweb/contract` for a shared module, or from `redweb` in server-only code. The standalone entry does not import the HTTP server or Node socket listener. Browser consumers need a bundler capable of consuming the CommonJS package; this is not a native browser script URL or a React integration.
|
|
16
|
+
|
|
17
|
+
`defineSocketContract(version, schemas, options?)` accepts an object mapping message names to [Standard Schema v1](https://standardschema.dev/) validators. Zod is used by the starter, but is not a Redweb runtime dependency. Use your existing compatible schema library. The version must match the negotiated protocol version, and `error` is reserved for protocol errors. Contracts support 1–256 types, names up to 256 characters, and versions up to 64 characters.
|
|
18
|
+
|
|
19
|
+
- `contract.handler(type, callback)` returns a `BaseHandler` subclass accepted by `SocketRoute.handlers`. The callback receives `(socket, payload, message)` after validation. Payload and message types are inferred from the schema output. Register one handler per inbound type; declaring an outbound type does not expose a handler for it.
|
|
20
|
+
- `contract.protocol` supplies the immutable `{ versions: [version] }` route configuration. The route requires negotiation: a browser URL can use `?redwebVersion=1`. Contract handlers refuse a socket negotiated to a different version.
|
|
21
|
+
- `contract.client(socket)` wraps an existing browser or Node WebSocket-like object with `send(data)`. It neither opens the connection nor reconnects it. Wait for the socket to open before sending.
|
|
22
|
+
- `client.send(type, payload, metadata?)` validates and sends a JSON envelope. `client.envelope(...)` validates and returns the envelope without sending it. Senders use schema **input** types; receivers get schema **output** types. Metadata supports the existing `requestId` and `sequence` fields.
|
|
23
|
+
- `client.parse(frame)` decodes and validates a response. It accepts text, byte arrays, ArrayBuffers, or a message event containing them. The result is a type-discriminated message union or protocol error. Catch parse failures in asynchronous message listeners.
|
|
24
|
+
- `contract.send(serverSocket, type, payload, metadata?)` validates server output and uses the existing `sendEvent` transport path, preserving backpressure behavior. Its boolean result means the transport accepted the send, not that a peer received or acknowledged it.
|
|
25
|
+
- `contract.parse(type, unknownPayload)` runs validation directly without sending. It returns inferred output; this method alone does not JSON-serialize its argument.
|
|
26
|
+
|
|
27
|
+
## Validation and wire behavior
|
|
28
|
+
|
|
29
|
+
Socket payloads use JSON. Declare ISO strings rather than `Date` objects on the wire, and encode bigint values as strings. Top-level `undefined`, bigint, and cyclic values cannot be sent. JSON conversion occurs before sender validation, so the validator sees the representation that a receiver will actually get.
|
|
30
|
+
|
|
31
|
+
Sender validation uses an isolated copy. The transmitted payload remains the original JSON input snapshot even if a validator mutates its argument. Receiver validation produces transformed output for the application. Validators execute on both sending and receiving sides; use deterministic validators and avoid side effects such as writing to a database inside a transform.
|
|
32
|
+
|
|
33
|
+
Validation accepts asynchronous validators and awaits thenable outputs within the same error boundary/deadline. The default `validationTimeoutMs` is 5,000; configure a positive integer no greater than 2,147,483,647. Overdue validation is rejected, including synchronous work that finishes after its deadline. **This does not preempt synchronous JavaScript or cancel a validator's external work.** Validators are trusted application code, not a CPU sandbox. Keep expensive work out of validation and enforce transport payload/queue/rate limits separately.
|
|
34
|
+
|
|
35
|
+
Invalid inbound payloads never reach the handler callback. The peer receives sanitized `INVALID_PAYLOAD` and closes with code 1008. Validator diagnostics are not exposed because they may contain private data. Unknown inbound handler types retain `UNKNOWN_HANDLER`; incompatible versions are rejected during negotiation. Ordinary uncontracted routes keep their existing behavior.
|
|
36
|
+
|
|
37
|
+
Invalid output from `contract.send()` rejects locally. If that rejection escapes a handler, it is an application failure (`HANDLER_FAILED`, close 1011), not a client policy violation. Handle intentional application rejections explicitly if you want a recoverable protocol response; schema validation does not replace authentication, authorization, or game rules.
|
|
38
|
+
|
|
39
|
+
The match recipe uses private, in-memory bearer sessions solely to demonstrate join/move/resume. Read its security, restart, expiry, and scaling boundaries before adapting it.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Authored split-recovery coverage
|
|
2
|
+
|
|
3
|
+
The maintained `npm run verify:recovery:coverage` gate now includes both original
|
|
4
|
+
split-runner source files, not just the server policy and command wrapper.
|
|
5
|
+
All 161 tests across ten suites passed in 32.290 seconds on Windows Node 22.21.0.
|
|
6
|
+
|
|
7
|
+
| Authored file | Statements | Branch outcomes | Functions | Lines |
|
|
8
|
+
| --- | ---: | ---: | ---: | ---: |
|
|
9
|
+
| `diagnostics/recovery-split.cjs` | 224 | 96 | 44 | 184 |
|
|
10
|
+
| `diagnostics/recovery-split-worker.cjs` | 101 | 49 | 17 | 84 |
|
|
11
|
+
| `lib/ServerRecoveryCandidate.js` | 68 | 13 | 15 | 61 |
|
|
12
|
+
| `lib/ServerRecoveryPolicy.js` | 60 | 10 | 8 | 55 |
|
|
13
|
+
| `verify-server-recovery.js` | 4 | 2 | 2 | 4 |
|
|
14
|
+
| Total, all 100% | 457 | 170 | 86 | 388 |
|
|
15
|
+
|
|
16
|
+
Paths in this table are relative to `scripts/`. Report:
|
|
17
|
+
`coverage/server-recovery-acceptance/coverage-final.json`, SHA-256
|
|
18
|
+
`7ed28a1a33d1fdfcb3e7724aabee7a669f0ffca706806e45c5680a2bb9b4fdb4`.
|
|
19
|
+
CI retains this directory after success or failure. No coverage threshold,
|
|
20
|
+
ignored source, workload, sampling or acceptance limit changes.
|
|
21
|
+
|
|
22
|
+
## What these tests establish
|
|
23
|
+
|
|
24
|
+
The existing real worker/IPC/socket integration suite runs once.
|
|
25
|
+
It is complemented by explicit process, transport, clock, GC and report-failure
|
|
26
|
+
unit boundaries. Synthetic byte counts are not memory evidence. The VM executes
|
|
27
|
+
the original file at its original filename, validates unchanged source bytes,
|
|
28
|
+
and verifies statement/function/branch maps against both its instrumenter and
|
|
29
|
+
any existing Jest map before merging into the explicitly selected tool scope.
|
|
30
|
+
All 61 functions in the two authored runner files are represented; historical
|
|
31
|
+
converted maps with smaller function denominators are not used as proof.
|
|
32
|
+
|
|
33
|
+
Tests cover exact batch ordering and delivery reconciliation, request failures,
|
|
34
|
+
deadline/listener cleanup, partial acquisition, late socket acquisition,
|
|
35
|
+
independent worker/output cleanup, snapshot privacy and identity, input changes,
|
|
36
|
+
and combined primary/report/finalization errors. The ten existing worker-error
|
|
37
|
+
units reuse the same boundary helper instead of duplicating VM setup. The
|
|
38
|
+
critic strengthened the finalization error-order oracle and late-acquisition
|
|
39
|
+
cleanup assertions before final verification.
|
|
40
|
+
|
|
41
|
+
An intermediate 68-test selection passed behavior but failed coverage at
|
|
42
|
+
99.38% statements / 99.31% branches / 100% functions / 99.25% lines. It lacked
|
|
43
|
+
the existing native output-limit path and the instrumented existing worker
|
|
44
|
+
error cases; including those original tests closes the gaps without adding
|
|
45
|
+
another default 7,400-message measurement. The partial report hash is
|
|
46
|
+
`b9ab23a8de56675a48478e4515d98119fe9475d62b5968a7df3e014658145575`.
|
|
47
|
+
|
|
48
|
+
Snapshot branches in this gate use explicit VM unit boundaries. Actual private
|
|
49
|
+
snapshot capture belongs to separate existing client-heap/recovery-verifier
|
|
50
|
+
integration and full-regression evidence, not this 161-test selection.
|
|
51
|
+
|
|
52
|
+
The separate uninstrumented server acceptance recorded in
|
|
53
|
+
[failure handling](SPLIT_RECOVERY_ERROR_HANDLING.md) remains the relevant clean
|
|
54
|
+
memory measurement. Completing source coverage does not resolve historical
|
|
55
|
+
throughput, cleanup or original shared-process diagnostic failures.
|
|
56
|
+
|
|
57
|
+
## Full regression and contrary hosted evidence
|
|
58
|
+
|
|
59
|
+
The full Windows suite at unchanged commit `df58f94` completed: 1,943 passed,
|
|
60
|
+
five skipped, 175 suites, 1,501.012 seconds. It predates the new boundary tests
|
|
61
|
+
and soak retention changes. Scoped `NODE_OPTIONS=--use-system-ca` enabled the
|
|
62
|
+
system certificate store for npm consumers; TLS verification stayed enabled.
|
|
63
|
+
Library coverage is 5,449 statements / 4,046 branch outcomes / 978 functions /
|
|
64
|
+
4,468 lines, all 100%, not whole-repository coverage.
|
|
65
|
+
|
|
66
|
+
- Full JSON: `coverage/release-df58f94-tests.json`, SHA-256 `49392363f314cb95e37b0b3adf42ff611af5937d6b8e6a2b8de7a4a4e3c03582`.
|
|
67
|
+
- Map: `coverage/release-df58f94/coverage-final.json`, SHA-256 `9961a216b47d33803286fab9bffe81d7400c0a8f61478459bd437b7b45cbfb82`.
|
|
68
|
+
- Both `019b010` hosted runs passed: PR 33431726293 and push 33431722990.
|
|
69
|
+
- `df58f94` push 33432417846 passed, but PR 33432429300 failed its Node 24 soak delivery assertion. That failure is not superseded by the Windows or push pass; see [soak observation](SOAK_ROTATION_OBSERVATION.md).
|
|
70
|
+
|
|
71
|
+
No new hour soak, publication, deployment, merge or release approval is claimed.
|
|
72
|
+
|
|
73
|
+
### Subsequent Linux artifact verification
|
|
74
|
+
|
|
75
|
+
At `2e6afe9`, PR run 33436490115 completed both the authored recovery coverage
|
|
76
|
+
step and its artifact upload successfully. The downloaded map at
|
|
77
|
+
`coverage/ci-recovery-2e6afe9/coverage-final.json` has SHA-256
|
|
78
|
+
`2647d1734b36ff0384f3d8ee292747a851b946db53d296f17ab9d3a32242d54a`.
|
|
79
|
+
Its exact five-file inventory and serialized statement/function/branch source
|
|
80
|
+
locations match the current authored files. All 457/170/86/388 counters remain
|
|
81
|
+
100%. This is the Linux lifecycle job's Node 22 scope; the full workflow was
|
|
82
|
+
still running when this artifact was inspected. A completed coverage step does
|
|
83
|
+
not certify the unfinished workflow or supersede earlier delivery failures.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Split recovery: failure-channel corrections
|
|
2
|
+
|
|
3
|
+
The shared diagnostic/server-acceptance runner now preserves three concrete
|
|
4
|
+
failure boundaries without changing its workload, thresholds or sampling:
|
|
5
|
+
|
|
6
|
+
- Synchronous native IPC serialization errors use the existing request cleanup
|
|
7
|
+
closure, removing listeners and cancelling the request deadline immediately.
|
|
8
|
+
- Falsy/non-Error failures are normalized through the existing shared
|
|
9
|
+
`verificationError` helper before failure tracking and report aggregation.
|
|
10
|
+
Original Error identity is retained; other values remain available as causes.
|
|
11
|
+
- Worker error replies remain failures for non-Error rejections and Errors with
|
|
12
|
+
missing/empty stacks. A fixed fallback prevents an empty error field from
|
|
13
|
+
being interpreted as successful IPC. Private snapshot replies retain their
|
|
14
|
+
fixed redaction message.
|
|
15
|
+
|
|
16
|
+
The newly imported helper is included in the measurement fingerprint. No frozen
|
|
17
|
+
evaluation code, process helper, network helper, acceptance limits, socket
|
|
18
|
+
library API or application workload changed.
|
|
19
|
+
|
|
20
|
+
## Regressions before and after correction
|
|
21
|
+
|
|
22
|
+
Two real-process tests initially failed in 1.360s. Circular request data left
|
|
23
|
+
one extra listener on each of `message`, `exit` and `error`. An output callback
|
|
24
|
+
throwing `0` rejected with that primitive instead of retaining a persistent
|
|
25
|
+
failure. These checks use actual workers/IPC/output and no mocked transport or
|
|
26
|
+
process APIs; deliberate callbacks supply the failing application boundary.
|
|
27
|
+
|
|
28
|
+
The separate process/clock/GC unit boundary initially had seven failures and one
|
|
29
|
+
pass in 0.441s: null/undefined crashed error reporting, while other primitives
|
|
30
|
+
and an object produced an undefined error field. Snapshot refusal was already
|
|
31
|
+
correct. The critic then identified two genuine-Error cases (absent/empty stack),
|
|
32
|
+
which failed before the fallback was added (eight passed, two failed, 0.475s).
|
|
33
|
+
Those VM units are not native memory or IPC evidence.
|
|
34
|
+
|
|
35
|
+
The final selection passed 47 tests in 12.243s across existing split-runner
|
|
36
|
+
unit/native integration tests and the two new error test files. It includes five
|
|
37
|
+
actual early worker-registration failures and verifies normal Error type,
|
|
38
|
+
message/cause, recorded worker exit and both closed pipes. Those assertions
|
|
39
|
+
explicitly reject an unrelated cleanup AggregateError. Existing checks exercise
|
|
40
|
+
actual rooms/sessions, bad replies, unreachable peers, output draining, trace/code
|
|
41
|
+
modes, deadlines, forced cleanup and listener reuse.
|
|
42
|
+
|
|
43
|
+
The established server policy/coordinator/CLI coverage scope also passed all
|
|
44
|
+
76 tests in 26.638s at all-four 100% before the final missing-stack fallback;
|
|
45
|
+
that fallback is covered by the subsequent 47-test selection. This scope does
|
|
46
|
+
**not** include the full authored coordinator/worker files. The subsequent
|
|
47
|
+
161-test maintained gate closes those source-matched maps at all-four 100%;
|
|
48
|
+
see [authored coverage](SPLIT_RECOVERY_COVERAGE.md) for the exact scope and limits.
|
|
49
|
+
|
|
50
|
+
## Fresh uninstrumented server acceptance
|
|
51
|
+
|
|
52
|
+
One final normal `verify:recovery:server` run used the corrected runner/worker:
|
|
53
|
+
|
|
54
|
+
- All 7,400 exact replies reconciled between server and client.
|
|
55
|
+
- Empty measured registries, identical initial/final input fingerprints, complete
|
|
56
|
+
logs, and normal zero-status worker exits with both pipes closed; no forced
|
|
57
|
+
cleanup was required.
|
|
58
|
+
- Server storm peak: 108.18707393318519% of warm heap; final: 97.15476818198938%.
|
|
59
|
+
- Client peak: 112.98160068884602%, retained as a diagnostic, not subject to the
|
|
60
|
+
server's 110% budget.
|
|
61
|
+
|
|
62
|
+
Report: `coverage/server-recovery-ipc-fix-20260831/report.json`, SHA-256
|
|
63
|
+
`a8458d98eb90e17d3ee19006938a4efb51e67090b78ebccefd3ce2f13a3cdd48`.
|
|
64
|
+
This is one Windows/Node 22.21.0 result, not cross-platform release acceptance
|
|
65
|
+
or a resolution of the original shared-process failure. Historical throughput,
|
|
66
|
+
cleanup and soak limitations remain unchanged. No publication, deployment or
|
|
67
|
+
merge is claimed.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Starter coordinator verification
|
|
2
|
+
|
|
3
|
+
Both starter coverage coordinators now have a maintained direct coverage gate:
|
|
4
|
+
`npm run verify:starter-coordinators:coverage`. This is a private-tool scope, not
|
|
5
|
+
a change to the shipped runtime or a whole-repository coverage claim.
|
|
6
|
+
|
|
7
|
+
## Corrections
|
|
8
|
+
|
|
9
|
+
The V8 measurement previously fingerprinted inputs only after testing. It now
|
|
10
|
+
records the generated source/test/configuration inventory before execution and
|
|
11
|
+
requires identical bytes afterward. A real copied-repository regression changes
|
|
12
|
+
a source comment during the generated test command: compilation and all 14 real
|
|
13
|
+
tests pass, but the coordinator rejects the changed input and retains raw output.
|
|
14
|
+
The authored-source coordinator already enforced this correspondence; the same
|
|
15
|
+
native regression now exercises it directly.
|
|
16
|
+
|
|
17
|
+
Both runners previously wrote their success summary before updating the latest
|
|
18
|
+
index. An index-write failure could therefore leave a successful summary behind
|
|
19
|
+
while the command failed. Shared `finishVerificationSummary` records failure and
|
|
20
|
+
attempts one best-effort rewrite. Recording failures always remain command
|
|
21
|
+
failures, including when the corrective write succeeds. Primary and secondary
|
|
22
|
+
errors remain available; retained-workspace metadata survives repeated aggregation.
|
|
23
|
+
This is not atomic storage: an unwritable filesystem can still leave partial or
|
|
24
|
+
stale artifacts, so a summary alone never overrides a failed command outcome.
|
|
25
|
+
|
|
26
|
+
Both runners defensively reject an empty template inventory, and measurement also
|
|
27
|
+
rejects an empty source inventory. These are explicit boundary tests, not a claim
|
|
28
|
+
that the current six-template inventory was empty in ordinary execution.
|
|
29
|
+
|
|
30
|
+
## Tests and ownership
|
|
31
|
+
|
|
32
|
+
On Windows / Node 22.21.0, 56 tests in three suites pass in 22.027 seconds:
|
|
33
|
+
|
|
34
|
+
- 47 explicit unit fault cases instrument the exact coordinator source in a VM.
|
|
35
|
+
Compiler, process, filesystem and collector boundaries are injected here; these
|
|
36
|
+
cases are not described as mock-free integration.
|
|
37
|
+
- Seven native managed-child/filesystem cases obstruct report paths and exercise
|
|
38
|
+
actual successful, failed, recoverable-write and persistent-write outcomes.
|
|
39
|
+
- Two native copied-repository cases use the real initializer, compiler, generated
|
|
40
|
+
HTTP/WebSocket tests and coverage tools to reject source mutation after testing.
|
|
41
|
+
|
|
42
|
+
The native repository fixture awaits the real private `main` entrypoint, avoiding
|
|
43
|
+
an outer process timeout that could orphan independently owned descendants. Each
|
|
44
|
+
inner command retains its existing deadline. Cleanup uncertainty preserves the
|
|
45
|
+
outer fixture before assertions; normal confirmed cleanup removes owned projects.
|
|
46
|
+
The fixture selects TAP output explicitly and restores the prior environment.
|
|
47
|
+
The ordinary CLI entrypoints remain separately exercised by full starter runs.
|
|
48
|
+
|
|
49
|
+
CI retains reports for 30 days and gives the scoped tests 90 minutes and the two
|
|
50
|
+
full starter commands 65 minutes. These conservative outer limits cover existing
|
|
51
|
+
failure/cleanup budgets; they do not increase inner command deadlines. Normal
|
|
52
|
+
execution is substantially shorter. No success is inferred from timeout expiry.
|
|
53
|
+
|
|
54
|
+
## Exact coverage identity
|
|
55
|
+
|
|
56
|
+
All four metrics are 100% over exactly three files: 180 statements, 34 branches,
|
|
57
|
+
25 functions and 148 lines. The VM maps join coverage only when this private scope
|
|
58
|
+
is explicitly selected; they do not enlarge the normal 91-file library scope.
|
|
59
|
+
|
|
60
|
+
| File | SHA-256 |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| `scripts/measure-starter-coverage.js` | `76d475e1f9fa2d3adbdcadd6947d3ed2179646bc0122dad2054a868923d4be3c` |
|
|
63
|
+
| `scripts/verify-starter-source-coverage.js` | `833c7511b3799ac4e9513db5a45584fd3095ad2c1409653e90bc1ed8368d6457` |
|
|
64
|
+
| `scripts/lib/finishVerificationSummary.js` | `ffd7bfa685e5d260ffa176377e1de6adb835244134f0cda290214961f9423b80` |
|
|
65
|
+
|
|
66
|
+
Report `coverage/starter-coordinators/coverage-final.json` SHA-256:
|
|
67
|
+
`1d5453ad7a2e9ba3450df49aa4fdf4ad65998b72b693eb25b9bda1dfd5a90415`.
|
|
68
|
+
|
|
69
|
+
The senior critic approved the final source and checked these identities. The
|
|
70
|
+
preceding 1,322-test regression does not include these 56 cases or the ten later
|
|
71
|
+
report-retention cases. Both hosted workflows for `7a25d48` and `1eddee0` passed;
|
|
72
|
+
those earlier results are not assigned to this new source.
|
|
73
|
+
|
|
74
|
+
## Full starter workflows
|
|
75
|
+
|
|
76
|
+
Both actual CLI entrypoints completed against the final source above. Measurement
|
|
77
|
+
ran all six applications and 104 tests, retaining `measured` status. Its separate
|
|
78
|
+
V8 function gaps remain realtime 58.33%, chat 59.09% and dashboard 88.70%; the other
|
|
79
|
+
three applications have all-four 100% in that map.
|
|
80
|
+
`coverage/starters/271e9e10-5069-4983-b60f-612d660b04c9/summary.json` SHA-256:
|
|
81
|
+
`0b6507753dc1d49a6c1e99bd59df6cf3000767f3317620307abc351260692159`.
|
|
82
|
+
|
|
83
|
+
The authored-source gate passed all six applications, 104 tests in each plain and
|
|
84
|
+
instrumented mode, no failures or skips, and all 96 process reports retained.
|
|
85
|
+
All-four 100% covers the unchanged 600 statements, 299 branches, 160 functions and
|
|
86
|
+
472 lines. Raw report/log hashes were checked against each summary entry. This
|
|
87
|
+
uses actual HTTP/WebSockets, files and SQLite, including the one-minute rate
|
|
88
|
+
window in each dashboard mode. The unchanged collector's five tests also pass.
|
|
89
|
+
`coverage/starter-source/900bf78d-3e77-40b4-b645-c6599a7b1728/summary.json` SHA-256:
|
|
90
|
+
`8679e03a06e441403f08bbfca069c3e82b56ec2bfdd9a23f427885b0e820f050`.
|
|
91
|
+
|
|
92
|
+
Full pretest/generated/type checks pass. The complete root regression selected
|
|
93
|
+
for this increment then passed 1,388 tests across 132 suites in 724.472 seconds,
|
|
94
|
+
with two POSIX-only skips on Windows. Exactly 91 library files retain all-four
|
|
95
|
+
100%: 5,449 statements, 4,046 branches, 978 functions and 4,468 lines. The private
|
|
96
|
+
VM maps did not enlarge that denominator. The subsequent lifecycle-coordinator
|
|
97
|
+
tests were added after selection and are not included in this inventory.
|
|
98
|
+
|
|
99
|
+
Full report `coverage/coverage-final.json` SHA-256:
|
|
100
|
+
`f9a99527a5d288640750ddab72858dc571e524864d5ed2a4012e34c6ee0df44b`.
|
|
101
|
+
Inventory `coverage/starter-coordinators-full-results.json` SHA-256:
|
|
102
|
+
`a17c022d9c38738bdcbe736496015781abb02a903548e1a52ef27012a1cd7348`.
|
|
103
|
+
|
|
104
|
+
The critic approved all 13 actual remote changed blobs at `377f029`, including
|
|
105
|
+
the retained full-starter artifacts. Both hosted workflows then passed completely:
|
|
106
|
+
PR `33380771673` and push `33380765217`. Later evidence/implementation heads retain
|
|
107
|
+
their own separate hosted outcomes.
|
|
108
|
+
|
|
109
|
+
No compiler/runtime behavior, coverage thresholds, frozen evaluation files,
|
|
110
|
+
publication, deployment or performance acceptance changed. V8 compiler-generated
|
|
111
|
+
function gaps remain diagnostic; authored-source coverage is the separate gate.
|
|
112
|
+
The unresolved throughput result in `BENCHMARK_VERIFICATION.md` remains open.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Lifecycle coverage must measure actual code
|
|
2
|
+
|
|
3
|
+
The lifecycle gate previously trusted c8's exit code. A real command with all four
|
|
4
|
+
100% thresholds and an empty source match exits successfully with `{}` coverage:
|
|
5
|
+
c8 compares a nonnumeric empty-map percentage against the thresholds.
|
|
6
|
+
|
|
7
|
+
The current generated lifecycle application exposed a concrete false-green too:
|
|
8
|
+
all 13 source-free tests passed, c8 exited zero, but its report was empty. The
|
|
9
|
+
generated JavaScript has an external map pointing to TypeScript removed by the
|
|
10
|
+
deployment check. The converter cannot read that original source; c8 catches the
|
|
11
|
+
conversion error and omits the module. This is a verification defect, not a
|
|
12
|
+
demonstrated runtime lifecycle failure. The failed evidence remains under
|
|
13
|
+
`coverage/starter-lifecycle/abb4623b-ed07-47cd-8f02-8a463bd7b788/`.
|
|
14
|
+
|
|
15
|
+
## Correction and scope
|
|
16
|
+
|
|
17
|
+
`verify-starter-lifecycle.js` now requires exactly the expected deployed
|
|
18
|
+
`dist/run-app.js` module, nonempty statement/branch/function/line inventories and
|
|
19
|
+
100% in each metric. Empty, wrong-module, extra-module and incomplete maps fail.
|
|
20
|
+
The existing source-free application checks run first, unchanged.
|
|
21
|
+
|
|
22
|
+
This gate deliberately measures emitted JavaScript, not authored TypeScript.
|
|
23
|
+
Inside its disposable application only, it removes the asserted trailing
|
|
24
|
+
`sourceMappingURL` comment. Every preceding executable byte remains unchanged;
|
|
25
|
+
the original JavaScript, original map and measured JavaScript are retained.
|
|
26
|
+
The measured file must remain byte-identical after testing. Merely moving the map
|
|
27
|
+
was tested and was insufficient: the converter also follows the unchanged comment
|
|
28
|
+
and fails when the map is missing. That failed attempt remains under
|
|
29
|
+
`coverage/starter-lifecycle/15a3915d-8803-46b2-8714-ec07bde0782a/`.
|
|
30
|
+
|
|
31
|
+
Each run retains raw JSON and successful test output in a unique directory before
|
|
32
|
+
temporary cleanup. It reuses the shared report/workspace owners; no new process
|
|
33
|
+
manager was added. Success output follows confirmed cleanup. Invalid reports or
|
|
34
|
+
recording/cleanup failures remain failures. The separate original-TypeScript
|
|
35
|
+
starter gate is unchanged and is not replaced by this emitted-code measurement.
|
|
36
|
+
|
|
37
|
+
## Verification
|
|
38
|
+
|
|
39
|
+
On Windows / Node 22.21.0, `npm run verify:starters:lifecycle:coverage` passes
|
|
40
|
+
26 tests across two suites in 16.827 seconds. Twenty-four explicitly labelled
|
|
41
|
+
unit faults cover orchestration, malformed/empty/incomplete inventories, import
|
|
42
|
+
and CLI entry, LF/CRLF metadata removal, changed executable bytes and cleanup.
|
|
43
|
+
Two no-API-mock integration tests reproduce the actual c8 empty-map success and
|
|
44
|
+
run the complete generated, compiled, source-free lifecycle workflow.
|
|
45
|
+
|
|
46
|
+
The exact coordinator scope is all-four 100%: 42 statements, six branches,
|
|
47
|
+
four functions and 39 lines. VM maps are merged only into this explicitly selected
|
|
48
|
+
scope, not the normal library denominator. Source SHA-256:
|
|
49
|
+
`0fd8c761f536b818eafcc07a521639216770dc4b8d87a8670cc79cfdbeba3e32`.
|
|
50
|
+
Report `coverage/starter-lifecycle-coordinator/coverage-final.json` SHA-256:
|
|
51
|
+
`adcfe7be6387d8d980262f78a551c07858449b93f8ef62e45b30adfbc6fa12c2`.
|
|
52
|
+
|
|
53
|
+
The ordinary `npm run verify:starters:lifecycle` CLI also passes after those tests.
|
|
54
|
+
Its 13 real lifecycle cases pass with no skips or failures; the report contains
|
|
55
|
+
exactly one emitted module, 57 statements/lines, 20 branches and four functions,
|
|
56
|
+
all covered. Existing tests use real child processes, HTTP/TCP/WebSockets and
|
|
57
|
+
timers. On Windows, signal events are explicitly emitted by the fixture; Linux
|
|
58
|
+
uses actual OS signals. This local result is not a new Linux execution claim.
|
|
59
|
+
|
|
60
|
+
Final CLI artifacts: `coverage/starter-lifecycle/d23cbdd7-93d3-4639-bb11-d79721fa4fb0/`.
|
|
61
|
+
|
|
62
|
+
| Artifact | SHA-256 |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| `coverage-final.json` | `e87cb491536901d88530db1ee9140c813b6e416ec60d5b26c8170e7ac1fa63d8` |
|
|
65
|
+
| `deployed-run-app.js` | `680c7c29aee7628f578c95df0d58ce7fa34252d9e13660194c5d1ed055bf9c3c` |
|
|
66
|
+
| `deployed-run-app.js.map` | `f42265ab86fcacf880083e9ada2b414fcac70c3bba05753f575a154b359d88ca` |
|
|
67
|
+
| `measured-run-app.js` | `3b06e16afa137a5b55b0d6a2ce95abc4f638e5dead30b1ae0260825ea2ca8f45` |
|
|
68
|
+
| `test-output.txt` | `df897133496bad53d81c4f1e44e09876321584b9eac3749dc70feda1da94ca2e` |
|
|
69
|
+
|
|
70
|
+
CI allows eight minutes for the scoped tests and five for the ordinary CLI,
|
|
71
|
+
covering existing inner command/cleanup budgets, and retains evidence for 30 days.
|
|
72
|
+
The critic approved the source and verified the metadata-only transformation.
|
|
73
|
+
The previous 1,388-test/132-suite regression does not include these 26 later cases.
|
|
74
|
+
No runtime/compiler changes, threshold relaxation, benchmark waiver, npm
|
|
75
|
+
publication, deployment or new hour-soak result is claimed.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Retaining failed starter coverage evidence
|
|
2
|
+
|
|
3
|
+
The starter coverage measurement and authored-source gate previously copied raw
|
|
4
|
+
reports only after child commands and parsing/collection succeeded. If a child
|
|
5
|
+
wrote coverage and then failed, or its output was malformed, workspace cleanup
|
|
6
|
+
could remove the only raw report. Successful authored runs also discarded the
|
|
7
|
+
individual process maps after combining them. This was an evidence-loss defect,
|
|
8
|
+
not a demonstrated false-green coverage result.
|
|
9
|
+
|
|
10
|
+
Both runners now create retained application directories before execution and
|
|
11
|
+
reuse `reportCommand` to preserve available raw bytes before parsing or collection.
|
|
12
|
+
The authored gate retains individual maps in `process-reports/`; both runners
|
|
13
|
+
save successful command logs immediately. Missing reports still fail validation,
|
|
14
|
+
and failed commands remain failures even when a report was written.
|
|
15
|
+
|
|
16
|
+
The shared helper handles a file or directory. A directory destination is first
|
|
17
|
+
reserved with an exclusive creation, preventing `cpSync` from silently merging
|
|
18
|
+
new files into an older report. Primary and copy failures remain visible together.
|
|
19
|
+
Copying is not atomic: partial bytes can survive a failed copy, are not certified
|
|
20
|
+
complete, and cannot be reused as a fresh destination.
|
|
21
|
+
|
|
22
|
+
## Tests and scope
|
|
23
|
+
|
|
24
|
+
`npm run verify:reports:coverage` passes 15 tests across two suites in 1.064 seconds
|
|
25
|
+
on Windows / Node 22.21.0. Five explicit fault units complement ten actual managed
|
|
26
|
+
child-process/filesystem cases. They check successful/failed exits, absent reports,
|
|
27
|
+
nested raw directories, malformed bytes retained after parsing failure, exclusive
|
|
28
|
+
destinations and combined failures. The mid-copy unit writes one actual file before
|
|
29
|
+
injecting a copy failure, then proves a second attempt cannot merge into it.
|
|
30
|
+
|
|
31
|
+
The exact `scripts/lib/reportCommand.js` scope is all-four 100%: 16 statements,
|
|
32
|
+
eight branches, one function and 14 lines. CI allows seven minutes for the summed
|
|
33
|
+
350-second outer failure budgets and retains the coverage report for 30 days.
|
|
34
|
+
This does not claim direct 100% coverage of either entire starter coordinator.
|
|
35
|
+
|
|
36
|
+
Source SHA-256:
|
|
37
|
+
`65ef5c11a4855b16b3d3277d5a541e88a0edeba96fd12e24efebae30c6ff029c`.
|
|
38
|
+
Report `coverage/command-report/coverage-final.json` SHA-256:
|
|
39
|
+
`1bcc4a8daa5da4f51e2567bfe007f4a1533150067292b315f261d31500dc787a`.
|
|
40
|
+
|
|
41
|
+
The new directory-retention regression failed in both real child exit modes before
|
|
42
|
+
the helper gained directory support. Both pass after the correction.
|
|
43
|
+
|
|
44
|
+
## Actual starter runs
|
|
45
|
+
|
|
46
|
+
The measurement runner completed all six applications, retaining its diagnostic
|
|
47
|
+
status `measured`, not a passing all-code gate. Compiler-generated function gaps
|
|
48
|
+
remain visible: realtime 58.33%, chat 59.09%, dashboard 88.70%; the other three
|
|
49
|
+
applications have all-four 100% in that separate V8 map.
|
|
50
|
+
`coverage/starters/e7da2be3-5366-4a21-8641-2420e7fca1ca/summary.json` SHA-256:
|
|
51
|
+
`ad7b088829ce1e88bfd68194d13900f548d6c42b08a082de9bdd28a9e806ac51`.
|
|
52
|
+
|
|
53
|
+
The authored-source gate then passed all six applications, 104 real tests in each
|
|
54
|
+
plain/instrumented mode, no failures or skips. Its unchanged authored denominator
|
|
55
|
+
is all-four 100%: 600 statements, 299 branches, 160 functions and 472 lines.
|
|
56
|
+
All 96 individual process maps are retained, matching the per-application reported
|
|
57
|
+
counts (14/15/14/14/24/15 for realtime/chat/site/socket/dashboard/http-ws).
|
|
58
|
+
`coverage/starter-source/ad9c5821-7437-4988-9c62-520d8ccb1a79/summary.json` SHA-256:
|
|
59
|
+
`971d8cd416080019a48bc901a24a19096ee86162aecd93fb61189b1e4043a702`.
|
|
60
|
+
These runs use actual generated applications, HTTP/WebSockets, files and SQLite,
|
|
61
|
+
including the dashboard's real one-minute rate window in each mode.
|
|
62
|
+
|
|
63
|
+
The unchanged application collector's five tests also pass at all-four 100%.
|
|
64
|
+
Compatibility with the existing client-report path passes 31 selected checks
|
|
65
|
+
across four suites in 4.546 seconds, with all-four 100% for `ClientSourceCoverage`
|
|
66
|
+
and the retention helper. This is not a rerun or resolution of the separate
|
|
67
|
+
standalone client V8 diagnostic.
|
|
68
|
+
|
|
69
|
+
The critic approved the implementation and partial-copy/exclusive-root tests.
|
|
70
|
+
The preceding 1,322-test full checkpoint in `ACTION_INPUT_VERIFICATION.md` does not
|
|
71
|
+
include the ten added cases in this follow-up. No coverage thresholds,
|
|
72
|
+
compiler/runtime behavior, frozen evaluation files, publication status or
|
|
73
|
+
performance acceptance were changed.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# 0.9.0 verification evidence
|
|
2
2
|
|
|
3
|
+
This is historical evidence for the 0.9.0 candidate, not certification of a newer release. Current commands, measurement scopes and unresolved gates are recorded in [operations](MULTIPLAYER_OPERATIONS.md#verification) and the [development release checklist](AGENT_READY_ACCEPTANCE.md).
|
|
4
|
+
|
|
3
5
|
Release-candidate measurements were taken on Windows x64, Node 22.21.0, and an AMD Ryzen 7 7800X3D. Performance numbers are machine-specific; the scripts and thresholds are the durable contract.
|
|
4
6
|
|
|
5
7
|
## Automated correctness
|