machine-bridge-mcp 3.0.0-beta.30 → 3.0.0-beta.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +4 -2
  3. package/browser-extension/manifest.json +1 -1
  4. package/docs/ARCHITECTURE.md +7 -7
  5. package/docs/AUDIT.md +42 -0
  6. package/docs/CLIENTS.md +3 -1
  7. package/docs/LOGGING.md +6 -5
  8. package/docs/OPERATIONS.md +9 -9
  9. package/docs/RELEASING.md +1 -1
  10. package/docs/TESTING.md +6 -6
  11. package/docs/TOOL_REFERENCE.md +33 -33
  12. package/docs/UPGRADING.md +20 -0
  13. package/package.json +4 -2
  14. package/scripts/install-published-prerelease.mjs +3 -3
  15. package/scripts/prerelease-activation.mjs +33 -10
  16. package/scripts/start-release-candidate.mjs +4 -4
  17. package/src/local/cli.mjs +3 -7
  18. package/src/local/doctor-reporting.mjs +23 -0
  19. package/src/local/patch.mjs +20 -18
  20. package/src/local/relay-connection.mjs +12 -12
  21. package/src/local/relay-diagnostics.mjs +7 -0
  22. package/src/local/relay-peer-diagnostics.mjs +24 -0
  23. package/src/local/runtime-paths.mjs +2 -1
  24. package/src/local/runtime-relay.mjs +4 -5
  25. package/src/local/runtime.mjs +3 -3
  26. package/src/local/workspace-file-service.mjs +45 -44
  27. package/src/shared/relay-contract.json +2 -2
  28. package/src/shared/server-metadata.json +2 -1
  29. package/src/shared/tool-catalog.json +33 -33
  30. package/src/worker/daemon-relay-diagnostics.ts +110 -0
  31. package/src/worker/daemon-socket-attachment.ts +3 -0
  32. package/src/worker/daemon-sockets.ts +40 -5
  33. package/src/worker/index.ts +55 -55
  34. package/src/worker/mcp-resumption-config.ts +3 -1
  35. package/src/worker/mcp-stream-channel.ts +15 -15
  36. package/src/worker/mcp-stream-dispatch.ts +10 -3
  37. package/src/worker/observability.ts +57 -5
  38. package/src/worker/runtime-alarm-storage.ts +1 -1
  39. package/src/worker/runtime-alarm.ts +49 -41
  40. package/src/worker/tool-timeout.ts +16 -3
  41. package/src/worker/worker-task-lifetime.ts +18 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,81 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.0.0-beta.38 - 2026-08-05
4
+
5
+ ### Keep relay liveness acknowledgement off durable storage paths
6
+
7
+ - Send the Worker `pong` immediately after the authenticated socket attachment is refreshed, before any Durable Object alarm read or write. A slow alarm/storage operation can no longer delay heartbeat acknowledgement and make an otherwise healthy connection appear silent.
8
+ - Make daemon activity refresh scheduling-explicit. Heartbeats perform one alarm schedule after `pong`, and terminal tool results coalesce liveness and pending-call deadline updates into exactly one schedule instead of the previous implicit-plus-explicit pair.
9
+ - Isolate the complete event-time alarm scheduling path, not only the final alarm write. Durable deadline reads, invalid-socket cleanup, or diagnostic callback failures now become bounded observability events instead of aborting a registered call before dispatch or rejecting a WebSocket message event. The actual Durable Object `alarm()` handler remains failure-propagating so the platform can retry it.
10
+ - Add architecture regressions that require `pong` to precede alarm scheduling, forbid socket-touch helpers from acquiring hidden alarm ownership, and require one terminal-result alarm schedule.
11
+ - Record the live beta.37 incident boundary: the same launchd daemon (PID unchanged, `runs=1`) recovered a `1006 connection_interrupted` episode in 2.631 seconds on its first attempt. macOS changed the `utun5` link-quality classification from good to poor four seconds before the close while the default route remained inside the Karing system-extension tunnel. This is strong temporal correlation with OS Wi-Fi/TUN path degradation, not proof that Karing, a selected proxy node, Cloudflare, or any specific upstream component caused the close.
12
+
13
+ ## 3.0.0-beta.37 - 2026-08-04
14
+
15
+ ### Close second-order relay recovery races
16
+
17
+ - Bind asynchronous daemon-authentication proof failures to the WebSocket generation that requested them. A rejected proof from an already closed socket can no longer terminate a replacement connection that is currently connecting or ready.
18
+ - Apply explicit close-category precedence. The first specific connect, handshake, readiness, heartbeat, or Worker recovery cause survives later specific or generic close signals; only an empty or generic transport category may be upgraded.
19
+ - Separate socket cleanup from alarm ownership. Runtime-alarm invalidation no longer recursively schedules another alarm, and the final alarm deadline is recomputed after detach/rebind state changes so reconnect grace cannot inherit a stale pre-detach deadline.
20
+ - Close invalidated sockets before awaiting durable cleanup. Concurrent `error`/`close` callbacks share one cleanup Promise; successful cleanup remains terminal, while a transient failure is retried once in-event and releases its slot for a later callback without duplicating disconnected metrics or warning logs. Welcome, readiness-probe, replacement, liveness, send-failure, error, and close paths preserve the intended close reason even when storage cleanup fails.
21
+ - Mark the authenticated relay diagnostic snapshot as recovered when a probing socket becomes ready, extend outage duration through the actual readiness instant, canonicalize timestamps, and accept only stable coarse transport error classes. Failed reconnect attempts no longer erase the duration of the preceding healthy ready interval. A healthy `server_info.daemon.relay_transport` no longer reports the preceding reconnect as currently active or exposes arbitrary daemon metadata.
22
+ - Add fault-directed regressions for stale authentication promises, competing specific close causes, send-failure precedence, post-invalidation deadline recomputation, cleanup deduplication/retry, previous-ready-duration retention, ready-state diagnostic projection, and the scheduling-free cleanup architecture contract. Beta.36 was prepared but not activated; beta.37 supersedes that local candidate.
23
+
24
+ ## 3.0.0-beta.36 - 2026-08-04
25
+
26
+ ### Preserve and expose relay-disconnect evidence
27
+
28
+ - Preserve a specific connect, handshake, readiness, or heartbeat timeout classification when a later generic WebSocket error arrives before the close event. The late error can still terminate the socket, but it no longer erases the causal category used for recovery diagnosis.
29
+ - Make Worker daemon-socket cleanup idempotent. Error, close, candidate timeout, readiness timeout, liveness timeout, verified replacement, and send-failure paths converge on one expiry, pending-call detach, disconnected metric, and runtime-alarm transition, preventing duplicate Durable Object work when one socket emits both error and close. Synchronous stale-socket reclamation now retains its asynchronous cleanup with Durable Object `waitUntil` and converts storage failures into one bounded observability event instead of an unhandled rejection.
30
+ - Add a schema-versioned, privacy-bounded relay diagnostic summary to the authenticated daemon hello. The Worker sanitizes and preserves the immediately preceding reconnect episode in the daemon attachment and exposes it as authenticated `server_info.daemon.relay_transport`; endpoints, interface names, DNS data, arguments, and results remain excluded.
31
+ - Make `machine-mcp doctor` report its diagnostic scope explicitly. Doctor uses an isolated local runtime and does not inspect the running service process or its remote relay, so a green doctor result can no longer be mistaken for service WebSocket health.
32
+ - Add deterministic regressions for late-error classification, diagnostic bounding/projection, idempotent socket expiry, unified stale-candidate invalidation, retained asynchronous cleanup, authenticated server-info projection, and doctor scope.
33
+ - Pin the transitive `brace-expansion` and `undici` packages to fixed same-major releases through root overrides. The release audit discovered high-severity advisories in ESLint/Wrangler dependency paths; `npm audit fix --force` proposed an unrelated Wrangler downgrade, so beta.36 keeps the tested Wrangler/Miniflare versions while selecting `brace-expansion` 5.0.9 and `undici` 7.29.0.
34
+
35
+ ## 3.0.0-beta.35 - 2026-08-03
36
+
37
+ ### Enforce the patch-helper call contract
38
+
39
+ - Remove the obsolete third argument from the workspace patch call after beta.32 intentionally removed path data from `applyUpdateHunks` errors. The extra argument had no runtime effect but violated the helper contract and was rejected by the zero-unaccepted-findings CodeQL gate.
40
+ - Add an architecture source-contract regression requiring the single workspace call to match the two-argument helper signature, so local verification catches the mismatch before remote CodeQL.
41
+
42
+ ## 3.0.0-beta.34 - 2026-08-03
43
+
44
+ ### Classify daemon terminal-result dispositions
45
+
46
+ - Replace the ambiguous Worker `unmatched_results` interpretation with an explicit `terminal_results` disposition matrix. Successful transient and durable settlements are counted separately from owner-missing results that are acknowledged to terminate normal at-least-once replay and stale-connection results that are rejected without acknowledgement.
47
+ - Retain `calls.unmatched_results` as a compatibility aggregate of `owner_missing_acknowledged` and `stale_connection_rejected`, and mark that scope machine-readably. Operators no longer need to treat a harmless duplicate after cancellation, timeout, reconnect, deployment, or lost acknowledgement as evidence of a connection-identity defect.
48
+ - Centralize the settlement-to-acknowledgement decision and test all four outcomes. A deployed Worker integration regression completes a real call, consumes its acknowledgement, resends the identical result, proves a second acknowledgement, and verifies that only `owner_missing_acknowledged` increases.
49
+ - Update architecture and operations contracts so stale ownership is diagnosed from `stale_connection_rejected`, while sustained owner-missing growth is investigated as acknowledgement loss or bounded lifecycle overlap rather than automatically classified as protocol corruption.
50
+
51
+ ## 3.0.0-beta.33 - 2026-08-03
52
+
53
+ ### Clarify prerelease rollback evidence
54
+
55
+ - Upgrade prerelease activation records to schema 2 and replace the ambiguous `previous` field with `global_package_rollback_baseline`. The field now states exactly what activation records retain: the globally installed npm package version and entrypoint available for operator-directed disaster recovery, not the service runtime active immediately before activation.
56
+ - Keep schema 1 activation records readable without rewriting historical evidence. Legacy `previous` values are normalized in memory to the schema 2 field, while mixed-version fields, duplicate baseline fields, relative entrypoints, and malformed baselines fail closed.
57
+ - Keep transaction-scoped service recovery separate. `runtime-activation` continues to capture and verify the actual pre-handoff service version and entrypoint during activation; the persistent activation record no longer invites those two recovery concepts to be conflated.
58
+ - Make both local-candidate and published-prerelease writers consume the shared activation schema constant, add disk-level migration and rejection regressions, and enforce the field distinction in architecture and release documentation gates.
59
+
60
+ ## 3.0.0-beta.32 - 2026-08-03
61
+
62
+ ### Typed file mutation failures
63
+
64
+ - Replace ordinary exceptions in workspace file, patch, and remote path-boundary operations with the existing stable `BridgeError` contract. `write_file`, `edit_file`, and `apply_patch` now preserve actionable error codes and bounded `details.reason` values through local execution, stdio MCP, daemon WebSocket transport, Worker adaptation, and public MCP tool results instead of collapsing expected state failures to `execution_failed`.
65
+ - Classify create-only collisions, optimistic SHA-256 mismatches, targets that appear during commit, unsupported target types, symbolic-link destinations, duplicate patch paths, and stale or ambiguous patch contexts as `conflict`. Missing edit text is `not_found`; malformed patch envelopes, invalid text/image inputs, and invalid line ranges are `invalid_request`; bounded read/write violations are `limit_exceeded`; hard-link read denial is `permission_denied`; workspace escape is `path_boundary`.
66
+ - Keep sensitive and irrecoverable failures fail-closed. Error details contain only bounded reason tokens, counts, limits, and hunk/line indexes, never paths, file contents, old/new text, or expected/actual hashes. Incomplete staged-write cleanup and incomplete patch rollback remain non-exposed `internal_error` results while retaining their causes locally.
67
+ - Add direct runtime, atomic fault-injection, Worker-adapter, and live stdio regressions proving stable code/reason propagation, no overwrite after create-only or stale-precondition failure, transactional rollback, and absence of absolute paths in public error objects. Update tool discovery descriptions, generated reference, architecture, testing, and client guidance.
68
+
69
+ ## 3.0.0-beta.31 - 2026-08-03
70
+
71
+ ### Preserve host delivery margin for synchronous tools
72
+
73
+ - Reduce the remote synchronous foreground ceiling from 85 to 60 seconds. The previous 85-second execution allowance plus five seconds of Worker settlement could consume roughly 90 seconds before terminal handling completed; live evidence showed a temporally aligned 83.5-second command complete locally after the ChatGPT task had already ended with a message-send timeout. Defaults remain 30 or 60 seconds, owner-local commands retain their local budget, and longer remote work continues through process sessions or managed jobs.
74
+ - Separate the daemon execution deadline from the Worker settlement deadline. A second review found that the first beta.31 candidate sent the 65-second settlement deadline to the daemon as its local execution deadline, so the claimed five-second margin was not real for tools governed only by the relay envelope. The daemon now receives at most 60 seconds, while the Worker records a settlement deadline five seconds later for result acceptance, persistence, acknowledgement, and terminal settlement. Admission and transport latency may consume part of that internal interval, so it is not an external host guarantee.
75
+ - Replace the ambiguous zero-recipient counter with explicit Worker-internal transport metrics for terminal publication, live internal-subscriber sends, storage responses, and the completion-between-lookup-and-subscription race. These metrics do not assert public SSE consumption or host receipt; `server_info.tool_delivery.host_terminal_receipt_observable=false` makes that boundary machine-readable without logging call IDs, arguments, or results.
76
+ - Reduce the unactivated legacy-stream retention ceiling from the obsolete 730-second local-envelope-derived value to 185 seconds: the 65-second maximum hosted settlement deadline plus the 120-second terminal replay window. Activated calls still extend their records across the actual operation/reconnect state machine; abandoned prepare records no longer occupy the bounded 64-stream capacity for more than the hosted contract requires.
77
+ - Update the executable tool catalog, client guidance, generated reference, timeout regressions, and upgrade documentation. Existing MCP hosts may retain an older cached tool schema until they rediscover or reconnect; Worker validation remains authoritative and rejects oversized requests before dispatch.
78
+
3
79
  ## 3.0.0-beta.30 - 2026-08-02
4
80
 
5
81
  ### Resumable MCP delivery under transient interruption
package/README.md CHANGED
@@ -31,6 +31,8 @@ Support boundaries are defined in [SUPPORT.md](SUPPORT.md). Repository participa
31
31
 
32
32
  The remote Worker authenticates and relays requests. It cannot directly read local files or start local processes. Local-user authority remains in the daemon process.
33
33
 
34
+ Expected file-state failures are machine-readable. File mutations return stable codes such as `conflict`, `not_found`, `invalid_request`, and `limit_exceeded`, with bounded `details.reason` tokens where useful. Conflict responses should trigger a fresh read and reconciliation rather than a blind retry; public errors do not include file contents, compared hashes, or hidden paths.
35
+
34
36
  ```text
35
37
  Hosted MCP client
36
38
  -> HTTPS + OAuth 2.1 / PKCE
@@ -169,7 +171,7 @@ The shared source of truth is `src/shared/policy-contract.json`. The generated m
169
171
 
170
172
  For remote calls, `server_info.authorization.effective_policy` and `effective_tools` are authoritative. Daemon policy and tools describe only the local capability ceiling before account-role and host-side filtering.
171
173
 
172
- `tools/list` is a stable discovery catalog for the authenticated account role. A brief relay interruption does not withdraw tool definitions or require a tools-list-changed notification. Discovery is not authority: every `tools/call` is still intersected with the current end-to-end-ready daemon policy and tool ceiling, and fails retryably with `unavailable` when no daemon is ready. `server_info.tool_delivery` distinguishes the stable advertised catalog from the currently effective daemon/account intersection. The remote catalog also narrows configurable foreground timeouts to 85 seconds while preserving each tool’s 30- or 60-second default; larger requests fail before daemon dispatch instead of being silently truncated after side effects may have begun.
174
+ `tools/list` is a stable discovery catalog for the authenticated account role. A brief relay interruption does not withdraw tool definitions or require a tools-list-changed notification. Discovery is not authority: every `tools/call` is still intersected with the current end-to-end-ready daemon policy and tool ceiling, and fails retryably with `unavailable` when no daemon is ready. `server_info.tool_delivery` distinguishes the stable advertised catalog from the currently effective daemon/account intersection. The remote catalog also narrows configurable foreground timeouts to 60 seconds while preserving each tool’s 30- or 60-second default; larger requests fail before daemon dispatch instead of being silently truncated after side effects may have begun.
173
175
 
174
176
  `full` is the daemon capability ceiling. An authenticated owner may exercise it without per-operation approval IDs. Delegated reviewer, editor, and operator accounts remain inside immutable role ceilings; out-of-role operations are denied rather than converted into a temporary elevation workflow. Process sessions, retained output, and managed jobs are additionally bound to account, client, and refresh-token family. See [local authorization](docs/LOCAL_AUTHORIZATION.md).
175
177
 
@@ -188,7 +190,7 @@ Machine Bridge does not launch or identify a separate browser profile. It contro
188
190
 
189
191
  ## Durable work and local resources
190
192
 
191
- Remote foreground process, shell, browser, and application calls are bounded to 85 seconds. Keep mutations and validation in independently terminal calls. A timeout is a protocol result, not proof that descendant cleanup has already completed; inspect `diagnose_runtime.runtime.processes` remotely (or `server_info.runtime.processes` over local stdio) when a heavy filesystem or process operation is still draining. Long, cleanup-sensitive, or remotely initiated workflows should use process sessions or managed jobs; managed jobs persist ordered argv steps and `finally_steps` under owner-only local state and continue across an MCP disconnect.
193
+ Remote foreground process, shell, browser, and application calls are bounded to 60 seconds of daemon execution. The Worker retains separate settlement ownership for five additional seconds, but neither that margin nor its internal stream metrics prove that an external MCP host consumed the terminal frame. Keep mutations and validation in independently terminal calls. A timeout is a protocol result, not proof that descendant cleanup has already completed; inspect `diagnose_runtime.runtime.processes` remotely (or `server_info.runtime.processes` over local stdio) when a heavy filesystem or process operation is still draining. Long, cleanup-sensitive, or remotely initiated workflows should use process sessions or managed jobs; managed jobs persist ordered argv steps and `finally_steps` under owner-only local state and continue across an MCP disconnect.
192
194
 
193
195
  Credentials and files can be registered by alias without returning their contents through MCP:
194
196
 
@@ -30,6 +30,6 @@
30
30
  "action": {
31
31
  "default_title": "Machine Bridge Browser"
32
32
  },
33
- "version_name": "3.0.0-beta.30",
33
+ "version_name": "3.0.0-beta.38",
34
34
  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxryYkpZhq8+VAQLHcGS9BAHQcyKX8RHGIpIwvtIVRU/rcOcE0bNdnM0aZJ/h6xWQsGDHlhvjT2+1aJaAn/9k8473BRWajzVXld961CdHYVFVHoce2hHiSJ0xydWrHMMZhAm0mN0UzjEpgZ0tMw209efcZHIvSwuxhteZMRy4kyiVjwFlOf5oXFCxRuCJnPj3AK9CmCf4XgEBuPIJ0TZmjGHOOdBvJmbCNnAWXYEo5/mf7MfCGhV4IJ1hNuhpoNQfOFKMUcw9/v/IpT62XpfXdGYTfGYCmCjC+gntK1spbkr2P4/2+sYMQtLpse71mpSNGXfcf3abU55Vpn+gncSxRQIDAQAB"
35
35
  }
@@ -29,7 +29,7 @@ A canonical workspace receives an independent profile, Worker name, secret set,
29
29
 
30
30
  `LocalRuntime` is the transport-independent local tool orchestrator. It owns the shared authorization/execution pipeline, manager construction, mutation serialization, cancellation, and the narrow delegation surface used by stdio and relay transports. Domain behavior remains in focused services:
31
31
 
32
- - `workspace-file-service.mjs` and `git-service.mjs` own canonical filesystem/Git operations;
32
+ - `workspace-file-service.mjs` and `git-service.mjs` own canonical filesystem/Git operations; file and patch state failures use stable `BridgeError` codes with privacy-bounded reason tokens, while incomplete rollback/cleanup remains a non-exposed internal failure;
33
33
  - `process-contract.mjs` owns argv shape/size validation; `process-tree-signal.mjs`, `process-tree-supervisor.mjs`, `process-tree-snapshot.mjs`, and `process-tree-ownership.mjs` separate cross-platform signaling, asynchronous escalation, bounded process-group observation, and PID/start-time ownership; `process-execution.mjs` and `process-sessions.mjs` own one-shot and interactive execution; and `process-tracker.mjs` retains active and draining process ownership until close;
34
34
  - `shared/tool-call-capacity.mjs` defines the control-tool set and generic admission algebra; local `call-capacity.mjs` and Worker `pending-call-capacity.ts` apply it independently, while `runtime-reporting.mjs` builds privacy-aware runtime and project snapshots;
35
35
  - `runtime-diagnostics.mjs` owns fixed local probes and their stable interpretation, while `runtime-diagnostic-state.mjs` projects privacy-safe control-plane state for remote diagnosis;
@@ -193,7 +193,7 @@ Remote OAuth binds each code, access token, and refresh token to a named Machine
193
193
  10. A modern `tools/call` receives a random relay call ID only after role-visible name and raw arguments pass the shared schema gate. A JSON response remains in the initiating Durable Object event. If the Worker selects SSE, the outer Worker assigns a random private stream capability, makes one authenticated direct Durable Object request, and forwards the non-resumable response stream. If the public stream closes, a second credential-free internal request presents only that capability; it is handled before OAuth/DPoP and can cancel only the matching active call. No modern descriptor, terminal-result registry, recovery GET, event ID, or `Last-Event-ID` state exists. A legacy streamed call validates first, then binds OAuth token + signed session + typed JSON-RPC ID, commits bounded durable call/recovery state before daemon dispatch, and returns a descriptor that the outer Worker turns into the sequence-zero/sequence-one resumable stream.
194
194
  11. The local runtime validates policy and arguments, executes the tool, and produces a bounded JSON-serializable result. It retains the daemon-to-Worker terminal envelope after WebSocket queueing and replays it until the Worker returns `tool_result_ack`; queue acceptance is not durable delivery. This relay acknowledgement contract is independent of the public MCP era. Closing a modern HTTP response cancels its pending call through the private stream control. Closing a legacy response leaves the bounded operation recoverable; only legacy `notifications/cancelled`, a deadline, or reconnect-grace expiry cancels it.
195
195
  12. The Durable Object accepts a result only from the registered WebSocket generation. A transient modern call settles its in-memory pending record and current HTTP response; a legacy streamed call settles the generation-checked durable terminal store. If the daemon socket drops, both call classes may detach below the MCP transport for the bounded same-daemon reconnect interval. The same daemon-process identifier may reclaim them only after a fresh readiness probe; a new daemon process cannot. A stale socket result or close event cannot settle or detach a rebound call. Modern public HTTP recovery is still impossible: if that response stream is gone, its call is cancelled rather than exposed through replay.
196
- 13. Daemon delivery is at-least-once until `tool_result_ack`. The generation guard, idempotent already-terminal handling, and authoritative `resume_calls` set make duplicate delivery converge without reviving removed calls. Modern response closure and legacy explicit cancellation remove their respective pending ownership before a late result can be delivered. On readiness handover, the runtime cancels active calls and queued results absent from `resume_calls` before accepting `ready_ack`.
196
+ 13. Daemon delivery is at-least-once until `tool_result_ack`. The generation guard, idempotent already-terminal handling, and authoritative `resume_calls` set make duplicate delivery converge without reviving removed calls. Result handling records the disposition rather than collapsing every missing owner into one anomaly: committed transient and durable results are distinct from safely acknowledged owner-missing replays, while results from a stale connection are rejected without acknowledgement. The legacy `unmatched_results` metric is only the aggregate of owner-missing and stale-connection dispositions. Modern response closure and legacy explicit cancellation remove their respective pending ownership before a late result can be delivered. On readiness handover, the runtime cancels active calls and queued results absent from `resume_calls` before accepting `ready_ack`.
197
197
  14. A tool deadline cancels only that operation and never infers daemon death from tool duration. The independent daemon-liveness alarm owns socket invalidation. If same-instance readiness does not return before the grace deadline, the Worker rejects the detached request and the local runtime cancels ordinary calls, terminates their process trees, and discards queued results. A newly started daemon has a different instance identifier and cannot inherit prior calls.
198
198
  15. `start_job` is different: after durable acceptance, the detached runner is no longer bound to an MCP response stream or daemon socket. Later cancellation uses `cancel_job` or the local CLI.
199
199
 
@@ -267,13 +267,13 @@ Worker-name mutation is a separate identity transition. Existing state rejects a
267
267
 
268
268
  The local `RelayConnection` treats proxy selection, transport construction, WebSocket open, authentication, end-to-end readiness, and outage recovery as separate states. The shared proxy module maps WebSocket targets to standard HTTP(S) environment-proxy resolution, honors `NO_PROXY`, rejects non-HTTP(S) proxy schemes, and creates the proxy agent without exposing its URL or credentials. Invalid proxy configuration is a fatal configuration error rather than a retryable outage.
269
269
 
270
- A connection-attempt deadline terminates sockets stuck in `CONNECTING`. After open, the daemon sends `hello`; `hello_ack` establishes an authenticated relay generation and starts heartbeats, but does not resolve startup or advertise readiness. The Worker then sends a random `relay_probe`. Its result must traverse the local runtime dispatcher and `sendForSession` on that generation before `ready_ack` marks the connection usable. The daemon rejects ordinary tool calls before that state and rejects a premature readiness acknowledgement without locally recorded probe delivery. Independent handshake and readiness deadlines terminate candidates that authenticate but cannot return results. Once ready, application heartbeats require inbound activity; a silent half-open socket is terminated and reconnected. Worker error codes `daemon_transport_error` and `daemon_liveness_timeout` are connection-recovery signals, not protocol incompatibility: they terminate only the current socket, run normal disconnect cleanup, and enter bounded reconnect. The same classification is applied to the close frame if the preceding error frame is lost. Failure to send `hello`, or failure to deliver a readiness-probe result because its socket/session ended, follows the same transport-recovery path rather than being promoted to authentication or protocol failure. Unknown Worker errors, authentication rejection, malformed readiness sequencing, and identity/version mismatch remain fatal. Outage reminders run on their own exponential-backoff timer rather than depending on another transport callback.
270
+ A connection-attempt deadline terminates sockets stuck in `CONNECTING`. After open, the daemon sends `hello`; `hello_ack` establishes an authenticated relay generation and starts heartbeats, but does not resolve startup or advertise readiness. The Worker then sends a random `relay_probe`. Its result must traverse the local runtime dispatcher and `sendForSession` on that generation before `ready_ack` marks the connection usable. The daemon rejects ordinary tool calls before that state and rejects a premature readiness acknowledgement without locally recorded probe delivery. Independent handshake and readiness deadlines terminate candidates that authenticate but cannot return results. Once ready, application heartbeats require inbound activity; a silent half-open socket is terminated and reconnected. On the Worker, authenticated socket activity refresh is synchronous and `pong` is queued before Durable Object alarm inspection or mutation; heartbeat and terminal-result paths then own one explicit coalesced alarm schedule. Persistent deadline work therefore cannot sit in front of liveness acknowledgement or be scheduled twice through a hidden touch helper. Worker error codes `daemon_transport_error` and `daemon_liveness_timeout` are connection-recovery signals, not protocol incompatibility: they terminate only the current socket, run normal disconnect cleanup, and enter bounded reconnect. The same classification is applied to the close frame if the preceding error frame is lost. Failure to send `hello`, or failure to deliver a readiness-probe result because its socket/session ended, follows the same transport-recovery path rather than being promoted to authentication or protocol failure. Unknown Worker errors, authentication rejection, malformed readiness sequencing, and identity/version mismatch remain fatal. Outage reminders run on their own exponential-backoff timer rather than depending on another transport callback. Each new authenticated hello also carries a schema-versioned, bounded summary of the immediately preceding local reconnect episode. The Worker sanitizes that summary into the probing attachment; promotion to a ready daemon marks the episode recovered, canonicalizes timestamps, and retains only enumerated coarse error classes. Authenticated `server_info.daemon.relay_transport` therefore makes sub-warning-threshold interruptions diagnosable after recovery without claiming that the ready connection is still in outage or promoting every brief close to default logs.
271
271
 
272
272
  Reconnect uses bounded exponential backoff with jitter. Brief self-healing interruptions are debug-only. An unresolved outage is promoted to a rate-limited warning after a grace period, and recovery produces one summary. Raw close codes and reason strings remain debug-only.
273
273
 
274
274
  The Worker stores socket transitions in `DaemonSocketRegistry`: `candidate` before hello, `probing` after authentication, `daemon` only after the end-to-end result probe, and `expired` after terminal failure. Durable Object alarms enforce separate hello, readiness, and steady-state liveness deadlines across hibernation. A healthy incumbent remains active while a replacement is probed; a malformed, silent, incompatible, or identity-mismatched replacement is closed without displacing it. Only a verified candidate receives `ready_ack` and then replaces the old socket. Ready daemons stay live only while inbound traffic refreshes `lastSeenAt`; silent half-open or hibernation-restored sockets are reclaimed instead of advertising `daemon.connected` while tool calls time out.
275
275
 
276
- Each daemon process generates a random bounded `instance_id` at startup and includes it in every reconnect hello. Each accepted WebSocket additionally receives a random `connection_id` generation stored in its hibernation attachment. JSON-only pending calls retain an in-memory socket reference; streamed calls persist the opaque generation instead. On an unexpected socket loss, only calls owned by that generation are detached and the shared two-minute relay contract bounds recovery. During verified same-instance handover, the Worker transfers both already-detached and still-attached calls to the replacement generation before closing the incumbent. A delayed close or result from the incumbent fails the generation check and cannot mutate the rebound record. If replacement acknowledgement fails, ownership is restored to the still-open same-instance incumbent. Another process cannot inherit or resolve these calls. The local runtime mirrors that state machine by preserving active calls and completed-result envelopes until relay readiness returns. Before `ready_ack`, the Worker sends the exact IDs that still have remote waiters; the runtime cancels everything else and only then replays retained results through the verified socket. Grace expiry restores the terminal behavior: reject remote waiters, cancel local ordinary calls, terminate process trees, and discard undeliverable results. The shared execution envelope remains independent of reconnect grace. Worker operation countdown is paused while detached or transferred and resumed with its remaining budget, so handover cannot reset the normal timeout. The active stream record expiry is extended to cover each new reconnect deadline, remaining operation budget, and terminal replay window; repeated successful reconnect cycles cannot outlive and delete their own ownership record. JavaScript timers remain only the low-latency owner for JSON-only calls. Streamed operation and reconnect deadlines live in the durable call record, the earliest deadline is projected onto one Durable Object alarm, and every HTTP or WebSocket event performs a compensating overdue scan. A transient alarm-storage failure is observable but does not turn an already-dispatched operation into a false terminal failure; the next event scan remains the bounded recovery path. This does not make calls durable across daemon-process restart or machine failure; managed jobs remain the separate durable mechanism.
276
+ Each daemon process generates a random bounded `instance_id` at startup and includes it in every reconnect hello. Each accepted WebSocket additionally receives a random `connection_id` generation stored in its hibernation attachment. JSON-only pending calls retain an in-memory socket reference; streamed calls persist the opaque generation instead. On an unexpected socket loss, only calls owned by that generation are detached and the shared two-minute relay contract bounds recovery. During verified same-instance handover, the Worker transfers both already-detached and still-attached calls to the replacement generation before closing the incumbent. A delayed close or result from the incumbent fails the generation check and cannot mutate the rebound record. If replacement acknowledgement fails, ownership is restored to the still-open same-instance incumbent. Another process cannot inherit or resolve these calls. The local runtime mirrors that state machine by preserving active calls and completed-result envelopes until relay readiness returns. Before `ready_ack`, the Worker sends the exact IDs that still have remote waiters; the runtime cancels everything else and only then replays retained results through the verified socket. Grace expiry restores the terminal behavior: reject remote waiters, cancel local ordinary calls, terminate process trees, and discard undeliverable results. The shared execution envelope remains independent of reconnect grace. Worker operation countdown is paused while detached or transferred and resumed with its remaining budget, so handover cannot reset the normal timeout. The active stream record expiry is extended to cover each new reconnect deadline, remaining operation budget, and terminal replay window; repeated successful reconnect cycles cannot outlive and delete their own ownership record. JavaScript timers remain only the low-latency owner for JSON-only calls. Streamed operation and reconnect deadlines live in the durable call record, the earliest deadline is projected onto one Durable Object alarm, and every HTTP or WebSocket event performs a compensating overdue scan. Socket invalidation invoked by the alarm coordinator does not schedule recursively. After candidate/readiness/liveness transitions and call detach, the coordinator recomputes transient and durable deadlines from the resulting ownership state and performs one coalesced alarm write. The complete event-time scheduling calculation is failure-isolated: durable deadline reads, invalid-socket transitions, and alarm storage mutations become bounded observability events and do not abort a registered operation or WebSocket event. The platform-invoked alarm processor remains failure-propagating for retry, and the next ordinary event scan is the compensating recovery path. This does not make calls durable across daemon-process restart or machine failure; managed jobs remain the separate durable mechanism.
277
277
 
278
278
  ## Persistence
279
279
 
@@ -293,15 +293,15 @@ Browser-origin handling separates CORS response sharing from protocol authentica
293
293
 
294
294
  ## Observability
295
295
 
296
- Public health exposes only server identity and version. Authenticated `server_info` exposes bounded runtime status, managed-job counts, resource alias names without paths or values, relay route state without endpoint details, authenticated/probing/ready socket counts, end-to-end readiness evidence, local execution guardrails, explicit OS-enforcement gaps, and privacy-preserving capability-routing evidence. It separates the daemon capability ceiling from the authenticated account authority: `daemon.policy`/`daemon.tools` retain the pre-role ceiling, while `authorization.effective_policy`/`authorization.effective_tools` and the top-level `tools` report the role-intersected authority before any host-side filtering. It explicitly reports that the host-exposed subset is unknown to the server. The canonical MCP catalog advertises one foreground timeout contract of 1–85 seconds with tool-specific 30- or 60-second defaults, and the Worker rejects larger values before any daemon message is sent. `foreground-timeout.mjs` is the shared source for those defaults and limits; `process-foreground-timeout.mjs` applies them again at the local relay execution boundary so omitted values and registered-command manifests cannot outlive the Worker response. Owner-local registered commands may still use their explicit local manifest timeout. Longer remote work uses process sessions or managed jobs rather than a synchronous foreground response. `diagnose_runtime` runs fixed local probes, explicitly reports that its own request reached the daemon, and on macOS projects the default route into a coarse VPN/TUN interception class without returning interface or endpoint data.
296
+ Public health exposes only server identity and version. Authenticated `server_info` exposes bounded runtime status, managed-job counts, resource alias names without paths or values, the current daemon connection plus its sanitized preceding-reconnect summary without endpoint details, authenticated/probing/ready socket counts, end-to-end readiness evidence, local execution guardrails, explicit OS-enforcement gaps, and privacy-preserving capability-routing evidence. It separates the daemon capability ceiling from the authenticated account authority: `daemon.policy`/`daemon.tools` retain the pre-role ceiling, while `authorization.effective_policy`/`authorization.effective_tools` and the top-level `tools` report the role-intersected authority before any host-side filtering. It explicitly reports that the host-exposed subset is unknown to the server. The canonical MCP catalog advertises one foreground timeout contract of 1–60 seconds with tool-specific 30- or 60-second defaults, and the Worker rejects larger values before any daemon message is sent. `tool-timeout.ts` derives distinct daemon-execution and Worker-settlement deadlines, so the five-second settlement-deadline offset is not passed back to the daemon as additional execution time. `foreground-timeout.mjs` is the shared source for execution defaults and limits; `process-foreground-timeout.mjs` applies them again at the local relay execution boundary so omitted values and registered-command manifests cannot outlive the Worker response. Owner-local registered commands may still use their explicit local manifest timeout. Longer remote work uses process sessions or managed jobs rather than a synchronous foreground response. `diagnose_runtime` runs fixed local probes, explicitly reports that its own request reached the daemon, and on macOS projects the default route into a coarse VPN/TUN interception class without returning interface or endpoint data.
297
297
 
298
- Foreground logging defaults to `info`; autostart uses `warn`. Authenticated readiness, persistent degradation, and recovery are user-visible state transitions. Brief relay interruptions, raw transport close details, retry timing, and all per-tool starts/successes/failures/cancellations/durations are debug-only. Unexpected local and Worker infrastructure errors are reduced to classes. Messages, strings, arrays, object depth/key counts, and serialized fields are bounded.
298
+ Foreground logging defaults to `info`; autostart uses `warn`. Authenticated readiness, persistent degradation, and recovery are user-visible state transitions. Brief relay interruptions, raw transport close details, retry timing, and all per-tool starts/successes/failures/cancellations/durations remain debug-only in logs; the bounded preceding-reconnect summary is retained in authenticated `server_info` instead. Worker socket invalidation is single-owner: `error`, `close`, heartbeat, readiness, candidate expiry, replacement, and send-failure paths converge on one idempotent expiry and detach transition. Concurrent callbacks share one per-socket cleanup Promise; successful settlement remains cached for that socket, while a failed cleanup receives one immediate retry and then releases the slot for a later lifecycle callback. Only the first claim records disconnected metrics or a WebSocket warning. Transport closure begins before durable cleanup is awaited; alarm ownership remains with the initiating event or alarm coordinator rather than the cleanup primitive. Synchronous stale-socket detection starts expiry immediately but retains the asynchronous detach/storage work with Durable Object `waitUntil`; failures become one bounded error-class event rather than an unhandled Promise rejection. Unexpected local and Worker infrastructure errors are reduced to classes. Messages, strings, arrays, object depth/key counts, and serialized fields are bounded.
299
299
 
300
300
  Cloudflare sampling is size control rather than an audit log. The project intentionally does not claim complete forensic logging. See [LOGGING.md](LOGGING.md).
301
301
 
302
302
  ## Release integrity
303
303
 
304
- Repository-local checks cannot prove the ordinary deployed path. `local-release-acceptance.mjs` builds the exact tarball and promotion-content digest. The owner executes `release:candidate:activate`, which installs the tarball under the private state root and invokes the extracted `runtime-activation` state machine. The transaction acquires the machine-service lock before the workspace startup lock, rejects foreground or unverifiable ownership before provider mutation, authenticates the candidate daemon through the real Worker, and proves relay readiness before writing the service definition. Installation commits a machine-global owner record for the exact workspace, state root, entrypoint, and version. The login-service handoff succeeds only when that owner's daemon lock publishes the post-`ready_ack` readiness checkpoint; provider-active state alone cannot satisfy acceptance. A first explicit device-authentication rejection triggers one same-name, same-identity repair deployment and bounded candidate retry. If remote preparation has already advanced the deployment and activation still fails, cleanup installs and starts the compatible candidate service rather than restoring an incompatible previous runtime. Before remote transition, an older service is considered restored only when the same version and entrypoint reappear as a verified service daemon. The activation wrapper has no outer transaction-wide `SIGKILL`; each deployment, network, relay, service-manager, and convergence stage owns its bounded deadline so cleanup cannot be bypassed. Fault-injection tests cover lock ordering/release, pre-mutation foreground refusal, owner transaction failure, missing/corrupt/pending owner state, readiness failure, authentication repair and exhaustion, compatible-service recovery, legacy identity restoration, cleanup aggregation, failed service start, and convergence timeout.
304
+ Repository-local checks cannot prove the ordinary deployed path. `local-release-acceptance.mjs` builds the exact tarball and promotion-content digest. The owner executes `release:candidate:activate`, which installs the tarball under the private state root and invokes the extracted `runtime-activation` state machine. The transaction acquires the machine-service lock before the workspace startup lock, rejects foreground or unverifiable ownership before provider mutation, authenticates the candidate daemon through the real Worker, and proves relay readiness before writing the service definition. Installation commits a machine-global owner record for the exact workspace, state root, entrypoint, and version. The login-service handoff succeeds only when that owner's daemon lock publishes the post-`ready_ack` readiness checkpoint; provider-active state alone cannot satisfy acceptance. A first explicit device-authentication rejection triggers one same-name, same-identity repair deployment and bounded candidate retry. If remote preparation has already advanced the deployment and activation still fails, cleanup installs and starts the compatible candidate service rather than restoring an incompatible previous runtime. Before remote transition, an older service is considered restored only when the same version and entrypoint reappear as a verified service daemon. That transaction-scoped service identity is distinct from the activation record's optional `global_package_rollback_baseline`, which names only the globally installed npm package available for later operator-directed disaster recovery. Activation schema 2 makes the distinction explicit; schema 1 `previous` records are accepted only as legacy input and normalized to the new field. The activation wrapper has no outer transaction-wide `SIGKILL`; each deployment, network, relay, service-manager, and convergence stage owns its bounded deadline so cleanup cannot be bypassed. Fault-injection tests cover lock ordering/release, pre-mutation foreground refusal, owner transaction failure, missing/corrupt/pending owner state, readiness failure, authentication repair and exhaustion, compatible-service recovery, legacy identity restoration, cleanup aggregation, failed service start, and convergence timeout.
305
305
 
306
306
  Accepted prereleases use explicit npm/GitHub channels and a registry-verified activation record. `release-soak.mjs` enforces elapsed major/minor/patch observation windows. `promotion-digest.mjs` hashes the npm package inventory, file modes, and bytes while normalizing only synchronized version metadata; stable release is blocked if any functional packaged content differs. Guarded push, portable CI acceptance, GitHub source release, npm publication, and stable publication all validate the relevant acceptance/soak evidence. GitHub tag/Release mutation additionally requires an explicit confirmation flag and real owner TTYs before any fetch or verification, then holds a process-identity publication lock at the common Git state path so linked worktrees share the same owner. Release commands require `HEAD === origin/main` and never push `main` implicitly.
307
307
 
package/docs/AUDIT.md CHANGED
@@ -1,5 +1,47 @@
1
1
  # Security and privacy audit notes
2
2
 
3
+ ## 2026-08-05 version 3.0.0-beta.38 live relay-liveness review
4
+
5
+ The activated beta.37 daemon experienced one real short transport interruption at 2026-08-05 07:38:57 local time (`2026-08-04T23:38:57.893Z`). Authenticated `server_info.daemon.relay_transport` retained close code 1006, category `connection_interrupted`, one reconnect attempt, a 2,631-millisecond outage, and a preceding ready interval of 550,090 milliseconds. The socket returned to ready state with `outage_active=false`. The launchd process remained PID 73042 with `runs=1` and `last exit code = never exited`, excluding daemon crash or service restart as the immediate cause. No stale-connection result was accepted; one `owner_missing_acknowledged` result reflected the documented at-least-once terminal replay case in which the owner had already settled and the duplicate was acknowledged to stop replay.
6
+
7
+ macOS network evidence is temporally specific but not causally complete. The default route was carried by `utun5`. At 07:38:53, four seconds before the WebSocket close, several system connection monitors changed the `utun5` link-quality classification from good to poor. The tunnel was owned by the Karing system extension (`com.nebula.karing.karingServiceSE`), and multiple tunnel-carried connections closed or reopened in the same window. Neither Karing's unified-log stream nor readable recent product logs supplied a node-change or upstream-failure record. The defensible conclusion is therefore OS Wi-Fi/TUN path degradation correlated with the close; the evidence does not prove a Karing implementation defect, a proxy-node switch, Cloudflare failure, DNS/Fake-IP behavior, or another specific upstream trigger.
8
+
9
+ The fresh source review nevertheless found a Worker-side amplification hazard. For every heartbeat, `BridgeRoom` refreshed the hibernation attachment and awaited Durable Object alarm inspection/mutation before sending `pong`. Alarm storage is normally fast, but it is an unnecessary dependency in the liveness acknowledgement path: latency or contention there could make a healthy peer appear silent. The same helper implicitly scheduled an alarm for tool results, after which matched results scheduled it a second time. Beta.38 makes attachment touch synchronous, emits `pong` first, schedules once afterward, and gives terminal results one explicit coalesced schedule. A second fault-directed pass found that the scheduling helper still allowed pre-write failures—such as a durable deadline read or invalid-socket cleanup failure—to escape. That could reject a WebSocket event after `pong`, or abort a newly registered foreground call before its daemon dispatch. Event-time scheduling now catches the complete calculation/transition/write path and reports only a bounded error class; the platform-invoked `alarm()` processor still propagates failures for retry. Architecture tests freeze heartbeat ordering and ownership, while runtime tests inject both storage-write and durable-deadline-read failures. These corrections improve resistance to Worker-side delay and storage faults; they cannot prevent a TCP/WebSocket interruption caused below the application layer.
10
+
11
+ ## 2026-08-04 version 3.0.0-beta.37 second-order relay review
12
+
13
+ A fresh review of the unactivated beta.36 candidate did not reuse its green suite as proof. It found six second-order races. An asynchronous authentication proof created for an old socket could reject after reconnect and invoke the fatal path against the replacement. A send failure and two independent specific timeout sources could overwrite an earlier, more causal close category. Moving all invalidation through the idempotent cleanup owner caused runtime-alarm callbacks to enter alarm scheduling recursively. Removing that recursion without recalculating pending state would in turn retain a deadline computed before socket detach changed operation ownership. The hello-time diagnostic snapshot still had `outage_active=true` when stored on a ready socket. Finally, the Worker bounded but did not enumerate the claimed coarse transport error class, allowing arbitrary authenticated-daemon metadata into `server_info`.
14
+
15
+ Beta.37 binds authentication completion to the originating socket, applies a specificity-preserving close-category function, and makes alarm ownership explicit. Runtime-alarm callers invalidate with rescheduling disabled; after all socket transitions, the coordinator recomputes transient and durable deadlines from the resulting state and performs one coalesced alarm write. Socket closure starts before durable detach is awaited, so a storage exception cannot leave the invalidated transport open. A per-socket cleanup registry shares concurrent callback work, retains successful settlement, retries one transient failure in-event, and allows a later callback to retry persistent failure without duplicating disconnected metrics or warnings. Promotion from `probing` to `daemon` converts the reconnect snapshot to recovered state, extends its duration through actual readiness, canonicalizes timestamps, and restricts transport error classes to the stable operational vocabulary. Failed reconnect candidates preserve the prior healthy-ready duration rather than resetting it.
16
+
17
+ New tests reproduce an old-proof rejection after a replacement socket opens, a late send failure plus Worker liveness signal after a readiness timeout, a pending deadline that becomes earlier during candidate invalidation, concurrent cleanup plus persistent-failure retry, failed reconnect attempts after a healthy connection, and the exact ready-attachment diagnostic transition. Architecture tests forbid runtime-alarm invalidation from re-entering alarm scheduling and require the cleanup owner to remain scheduling-free. The existing beta.36 tarball is stale by promotion digest and was never activated, accepted, published, tagged, or deployed; beta.37 requires a new exact candidate and live owner verification.
18
+
19
+ ## 2026-08-04 version 3.0.0-beta.36 relay-disconnect review
20
+
21
+ The reported disconnect did not coincide with a daemon restart. Launchd still owned the same process that began at 08:02:02 local time, while the Worker-facing connection identity was established again at 19:36:29. During final verification the same PID and `runs=1` service established another connection at 20:36:53 without a warning-level relay event, proving a second sub-ten-second same-process interruption. The daemon warning log contained earlier 1006 and transport-timeout outages but no record for either brief reconnect because the background service runs at `warn` and suppresses recovered interruptions shorter than ten seconds. The active socket used the operating-system network stack through a TUN route; Karing and Tailscale packet-tunnel components were both present. macOS recorded a Tailscale network-configuration change at 19:32. Around 20:34, shortly before the second reconnect, the system reported Wi-Fi link quality changing from Good to Poor, Tailscale closing and reopening several DERP paths, and repeated Karing network-path checks. This repeated correlation strengthens the system-network/TUN-path churn hypothesis, but no source proved which tunnel, upstream node, DNS/Fake-IP mapping, Worker edge, or TCP event caused either reconnect. The exact external trigger therefore remains unknown and is not represented as a code-proven Karing or Tailscale defect.
22
+
23
+ Source review found four internal defects that made this class of incident harder or more expensive to handle. First, a timeout path could set a specific close category and call `terminate()`, after which a generic WebSocket `error` event overwrote it with `relay_transport_error` before `close`. Second, Cloudflare can deliver both `webSocketError` and `webSocketClose` for one socket; both entered cleanup, repeating disconnected metrics, pending detach attempts, durable storage transactions, and alarm scheduling. Several candidate/readiness invalidation branches also expired or closed a socket outside that cleanup owner. Third, synchronous stale-socket reclamation discarded the asynchronous invalidation Promise with `void`; a Durable Object storage failure could therefore escape as an unhandled rejection and the cleanup was not retained by the event lifecycle. Fourth, the daemon already retained bounded outage state in memory, but a brief recovered interruption was unavailable from the authenticated remote `server_info`; `machine-mcp doctor` created a separate non-relay runtime and still displayed its skipped remote-relay check inside an otherwise green result.
24
+
25
+ Beta.36 keeps the first specific close category, makes attachment expiry return a one-time ownership claim, and routes every Worker invalidation through one cleanup method before closure. Stale-socket cleanup is retained through Durable Object `waitUntil`; its rejection is reduced to the coarse `daemon.socket.cleanup.failed` error class and cannot create a second rejection if observability itself fails. The next authenticated hello carries only schema 1 bounded fields: coarse application network route, outage count/active state/start/duration/attempts, close category/code, coarse transport error class, last disconnect time, and previous ready duration. The Worker validates enums, timestamps, integer ranges, metadata lengths, and schema before storing the summary in its hibernation-safe socket attachment. Only authenticated `server_info.daemon.relay_transport` returns it. Public health and default logs remain unchanged. Doctor now reports `running_service_process_inspected=false` and `remote_relay_inspected=false` and directs operators to authenticated server info.
26
+
27
+ The release dependency audit then found two newly disclosed high-severity transitive issues: `brace-expansion` 5.0.8 through ESLint/minimatch and `undici` 7.28.0 through Wrangler/Miniflare. The ordinary fix safely advanced `brace-expansion` to 5.0.9, while npm's forced remediation proposed an unrelated Wrangler downgrade even though `undici` 7.29.0 is the fixed 7.x release. Beta.36 therefore retains the already tested Wrangler 4.115.0 and Miniflare 4.20260722.1 packages but adds deterministic root overrides for `brace-expansion` 5.0.9 and `undici` 7.29.0. Complete and production dependency audits now report zero vulnerabilities, all 117 registry package signatures verify, and 38 packages carry verified attestations.
28
+
29
+ The existing 120-second same-daemon call recovery remains the continuity boundary. These changes improve causal evidence and remove duplicate Worker work; they do not guarantee that an external MCP host will keep its foreground HTTP/SSE request open during every network transition, and they cannot stabilize a third-party VPN/TUN or edge path. Long or cleanup-sensitive work still belongs in process sessions or managed jobs.
30
+
31
+ ## 2026-08-03 version 3.0.0-beta.31 host-delivery margin review
32
+
33
+ The reported “message send timed out” interruption did not coincide with a daemon crash or a current relay outage. Launchd still owned one verified beta.30 daemon process with `runs=1`; Worker and daemon versions matched; and the local security-audit chain recorded a temporally aligned `exec_command` as successfully completed after 83,514 milliseconds. During the incident the Worker showed two durable `exec_command` calls still active, the oldest at roughly 81 seconds. Both later reached terminal state, while the host ended the task. The privacy-preserving audit deliberately omits raw command text, so an exact one-to-one mapping to the UI task cannot be proven; the timestamps and active-call counts nevertheless align. This separates execution completion from message delivery: persistence can preserve a legacy result, but it cannot force a host that has abandoned the response to resume it.
34
+
35
+ The beta.30 claim that 85 seconds was host-safe was therefore too strong. Its maximum execution budget plus the five-second Worker overhead allowed a terminal deadline of 90 seconds, leaving no credible allowance for request admission, Durable Object work, public SSE forwarding, host processing, or final assistant-message submission. The exact host deadline is external and not a Machine Bridge contract, so beta.31 does not claim a mathematically guaranteed bound. It conservatively caps remote synchronous execution at 60 seconds, records the Worker settlement deadline five seconds later, and directs longer work to durable process sessions or managed jobs. Admission and transport latency can consume part of that interval.
36
+
37
+ A second source review found that the first beta.31 candidate did not actually preserve that split. `daemonToolTimeoutMs` returned the execution budget plus overhead, and the Worker reused the same value both for its pending-call deadline and for the daemon `tool_call.timeout_ms`. Tools whose handler had no narrower inner timeout could therefore execute for the entire 65 seconds and consume the intended settlement margin. Beta.31 now computes an explicit `{executionTimeoutMs, settlementTimeoutMs}` budget: the daemon receives 60 seconds at most, while the Worker deadline is recorded at 65 seconds from Worker registration. Tests assert the two values independently for transient and durable stream paths, including the one-second integration timeout case.
38
+
39
+ The same review found a discovery-cache mismatch outside the current repository source: the live beta.30 Worker and canonical catalog enforced an 85-second maximum, while the tool schema supplied to the active ChatGPT conversation still advertised 600 seconds. A 120-second request was consequently generated by the host and rejected before dispatch. Beta.31 publishes a 60-second canonical schema and documents that an already-open host may need rediscovery or reconnection; the Worker remains the authoritative validation boundary. Because Machine Bridge cannot invalidate a host-owned schema cache, it must continue failing oversized requests with `side_effects_started=false`.
40
+
41
+ The same second review rejected the first observability fix as semantically ambiguous. A terminal publication with zero live internal subscribers can be normal: completion may precede subscription, after which the outer Worker obtains the persisted result through a storage-backed HTTP response. Conversely, a successful internal WebSocket send proves only Durable Object-to-outer-Worker queueing, not public SSE consumption or host receipt. Beta.31 therefore exposes separate aggregate counters for terminal publications, live internal-subscriber sends, storage responses, and storage-race sends/failures. `server_info.tool_delivery` explicitly states that host terminal receipt is not observable and that these counters cover legacy resumable Worker-internal storage and subscription transport only. Request identity, tool arguments, command text, and result content remain absent.
42
+
43
+ The resumption configuration retained another stale dependency on the former local 610-second relay envelope. A stream created during legacy prepare but never activated could remain for 730 seconds, consuming one of 64 bounded stream slots, even though hosted settlement now ends by 65 seconds. New unactivated records are capped at 185 seconds: maximum hosted settlement plus the 120-second replay window. Once activated, the existing operation/reconnect expiry algebra remains authoritative and extends the record as required.
44
+
3
45
  ## 2026-08-02 version 3.0.0-beta.30 interruption and recovery review
4
46
 
5
47
  A repeated-call incident was reproduced while the local launchd daemon remained the same healthy beta.29 process. Recent security-audit records showed that many 20–78 second local calls reached terminal state even when the MCP host reported interruption, and the public MCP endpoint was briefly unreachable while the daemon connection identity remained unchanged. Live Cloudflare sampling after recovery showed no Worker exceptions; internal legacy subscription WebSockets closed frequently as part of their ordinary terminal lifecycle. The evidence therefore separates three cases: local execution failure, Worker/DO delivery interruption after admission, and a connection failure before Worker code runs. Only the first two are observable or repairable inside this repository; a pre-Worker edge/TCP/TLS failure still requires host retry or an independently operated alternate endpoint.
package/docs/CLIENTS.md CHANGED
@@ -163,7 +163,9 @@ The local `full` profile controls Machine Bridge's own tool catalog, path resolv
163
163
 
164
164
  Machine Bridge itself does not block files because their names look sensitive. In remote mode, first inspect `server_info.authorization.effective_policy` and `effective_tools`; `daemon.policy` is only the local ceiling. If the effective profile is `full` and the effective tool is present but a direct call is still rejected before a structured result, the host/connector may have blocked delivery. If `diagnose_runtime` responds but its fixed process or shell probe fails, the likely source is local OS policy, endpoint-security software, permissions, or shell configuration. Changing `--profile`, `--unrestricted-paths`, or `--absolute-paths` cannot override either layer.
165
165
 
166
- Remote configurable foreground tools advertise an 85-second maximum while preserving each tool’s 30- or 60-second default. Missing or role-hidden tools, non-object arguments, and requests above that limit fail at the shared Worker schema boundary before daemon dispatch; schema failures include `side_effects_started=false`. A legacy client asking for SSE receives the same pre-persistence rejection as a JSON client rather than an allocated recovery stream. Do not treat this as a retry invitation for the same oversized mutation, and do not attempt to evade a host refusal by renaming, encoding, or switching to another arbitrary execution tool. Instead:
166
+ Expected file-operation failures arrive as ordinary MCP tool-error results, not JSON-RPC transport failures. Clients should branch first on `structuredContent.error.code`, then optionally on the bounded `details.reason`. For example, `conflict/already_exists`, `conflict/hash_mismatch`, `conflict/text_ambiguous`, and `conflict/context_not_found` require a fresh read and reconciliation; `not_found/text_not_found` means the requested edit fragment is absent; `invalid_request` means the request or patch syntax must change. Do not log or display tool arguments to reconstruct diagnostics: public error details intentionally omit paths, file content, edit fragments, and compared hashes.
167
+
168
+ Remote configurable foreground tools advertise a 60-second maximum while preserving each tool’s 30- or 60-second default. That value bounds daemon execution; the Worker records its settlement deadline five seconds later. Admission and transport latency may consume part of that interval, and it is not a guarantee of host receipt. Missing or role-hidden tools, non-object arguments, and requests above that limit fail at the shared Worker schema boundary before daemon dispatch; schema failures include `side_effects_started=false`. A legacy client asking for SSE receives the same pre-persistence rejection as a JSON client rather than an allocated recovery stream. Do not treat this as a retry invitation for the same oversized mutation, and do not attempt to evade a host refusal by renaming, encoding, or switching to another arbitrary execution tool. Instead:
167
169
 
168
170
  1. register credentials locally as resource aliases so their values never enter MCP arguments;
169
171
  2. submit a complete owner-authorized `start_job` plan before the workflow depends on later cleanup calls; `stage_job` is only a non-running draft, while an explicit local operator may use `machine-mcp job submit PLAN.json`;
package/docs/LOGGING.md CHANGED
@@ -63,11 +63,12 @@ Brief network interruptions are expected on laptop network changes, Worker deplo
63
63
  - a verified replacement is a distinct warning and permanently stops the older daemon;
64
64
  - failure to receive `hello_ack` within the handshake deadline, or `ready_ack` within the independent end-to-end readiness deadline, terminates the candidate socket and retries;
65
65
  - lack of inbound heartbeat activity terminates a half-open socket and reconnects;
66
+ - the Worker refreshes authenticated socket activity and queues `pong` before Durable Object alarm inspection or mutation, then performs one explicit coalesced schedule; storage latency is not allowed to sit ahead of heartbeat acknowledgement;
66
67
  - a late local heartbeat tick is classified as `runtime.event_loop.stall`, sends a fresh probe, and defers disconnect for a bounded recovery interval instead of being mislabeled as immediate remote failure; a macOS sleep/wake interval may legitimately produce this warning without a daemon fault.
67
68
 
68
- A WebSocket close code such as `1006` means the transport ended without a normal close handshake. It is useful for debug diagnosis but not useful as the default user message. It is not evidence that the daemon process restarted. Worker `daemon_transport_error` / `daemon_liveness_timeout` messages and their 1012 close frames are likewise retryable connection conditions, not upgrade instructions. Only an unknown/incompatible Worker error, authentication failure, or identity/version mismatch may produce the fatal protocol/configuration log and daemon exit. Default logs therefore describe the affected layer, duration, classification, and recovery behavior rather than printing raw close envelopes.
69
+ A WebSocket close code such as `1006` means the transport ended without a normal close handshake. If it recovers inside ten seconds, the warning-level service log is intentionally silent and the authenticated `daemon.relay_transport` snapshot is the post-event evidence surface. It is useful for debug diagnosis but not useful as the default user message. It is not evidence that the daemon process restarted. Worker `daemon_transport_error` / `daemon_liveness_timeout` messages and their 1012 close frames are likewise retryable connection conditions, not upgrade instructions. Only an unknown/incompatible Worker error, authentication failure, or identity/version mismatch may produce the fatal protocol/configuration log and daemon exit. Default logs therefore describe the affected layer, duration, classification, and recovery behavior rather than printing raw close envelopes.
69
70
 
70
- Streamed-call diagnostics are deliberately coarse. Modern request-scoped stream ownership is memory-only; legacy MCP `2025-11-25` may additionally report aggregate persistent active/detached counts, oldest age, tool-name counts, alarm mutations, unmatched-result counts, opened/coexisting/limited delivery-subscriber counts, and whether a legacy call is transient or durable. Worker event counters are scoped to the current isolate and say so in `metric_scope`; persisted durable calls can begin in one isolate and complete in another, so `started`, `completed`, and `failed` are not algebraically closed process-lifetime totals. The persistent pending-call snapshot is authoritative for current ownership. Logs and `server_info` must not include tool arguments, terminal results, command text, request keys, account identifiers, raw call IDs, raw connection generations, mirrored parameter values, private paths, or subscriber payloads. A stale-generation result is counted as unmatched rather than logged with its envelope.
71
+ Streamed-call diagnostics are deliberately coarse. Modern request-scoped stream ownership is memory-only; legacy MCP `2025-11-25` may additionally report aggregate persistent active/detached counts, oldest age, tool-name counts, alarm mutations, unmatched-result counts, opened/coexisting/limited delivery-subscriber counts, terminal publications, live internal-subscriber sends, storage responses, and storage-race sends/failures. These counters describe legacy resumable Worker-internal storage and subscription transport; they do not prove public SSE consumption or MCP-host receipt. Worker event counters are scoped to the current isolate and say so in `metric_scope`; persisted durable calls can begin in one isolate and complete in another, so `started`, `completed`, and `failed` are not algebraically closed process-lifetime totals. The persistent pending-call snapshot is authoritative for current ownership. Logs and `server_info` must not include tool arguments, terminal results, command text, request keys, account identifiers, raw call IDs, raw connection generations, mirrored parameter values, private paths, or subscriber payloads. A stale-generation result is counted as unmatched rather than logged with its envelope.
71
72
 
72
73
  Examples:
73
74
 
@@ -126,7 +127,7 @@ This is defense in depth, not content classification. Unknown, split, transforme
126
127
 
127
128
  Security-audit enqueue/persistence failures are warning-level operational faults, but repeated failures are rate-limited per event class. The first warning is emitted immediately; duplicates within one minute are suppressed, and the next emitted warning reports the suppressed count. Warning fields contain only the tool name and a coarse error class, never the rejected audit payload or principal identifiers.
128
129
 
129
- The local execution middleware emits bounded events such as `tool.call.started`, `tool.call.completed`, `tool.call.failed`, `tool.call.slow`, and `tool.call.cancel_requested`. Stable fields include a shortened call ID, tool name, origin, duration, error code, and retryability. The Worker emits JSON events for HTTP failures and daemon socket errors. Structured values still pass through field-name and value redaction; JSON format is not permission to log arguments or results.
130
+ The local execution middleware emits bounded events such as `tool.call.started`, `tool.call.completed`, `tool.call.failed`, `tool.call.slow`, and `tool.call.cancel_requested`. Stable fields include a shortened call ID, tool name, origin, duration, error code, and retryability. The Worker emits JSON events for HTTP failures and daemon socket errors. Structured values still pass through field-name and value redaction; JSON format is not permission to log arguments or results. A retained stale-socket cleanup failure uses `daemon.socket.cleanup.failed` with only `error_class`; it contains no socket identity, endpoint, arguments, or results.
130
131
 
131
132
  `server_info` is the operational metrics surface. Local metrics include lifecycle state, active and maximum calls, oldest-call age, active-process ownership, per-tool duration buckets, and error-code counts. Worker metrics include HTTP status classes, pending internal/request-key indexes, per-tool outcomes, daemon candidate/authenticated/ready/disconnected event counts, current authenticated/probing/ready socket counts, and protocol-error counts. Metrics contain counts and bounded identifiers, not request arguments or result contents.
132
133
 
@@ -149,7 +150,7 @@ Each managed job has owner-only runner diagnostic logs. Child-step output is ret
149
150
 
150
151
  `network_route` describes only Machine Bridge's application-level proxy decision. `system-network-stack` does **not** mean a direct physical path: an operating-system VPN, TUN, packet tunnel, DNS interceptor, or endpoint-security product may still carry the connection. `network_route_scope` therefore remains `application-proxy-selection-only`.
151
152
 
152
- During an outage, remote `diagnose_runtime.runtime.relay` and local stdio `server_info.runtime.relay` expose bounded operational fields: outage count/start/duration, last close category/code, coarse transport error class, last disconnect/ready time, prior ready duration, and next retry timing. On macOS, `diagnose_runtime` may also return a coarse default-route class and `operating_system_interception` boolean. That diagnostic is returned on demand and is not promoted to default logs; interface names, IP addresses, DNS answers, proxy endpoints/credentials, Worker endpoints, tool arguments, and results remain absent. `relay.outage.active` and `relay.outage.recovered` carry the existing safe relay fields.
153
+ During an outage, remote `diagnose_runtime.runtime.relay` and local stdio `server_info.runtime.relay` expose bounded live fields: outage count/start/duration, attempts, last close category/code, coarse transport error class, last disconnect/ready time, prior ready duration, and next retry timing. After recovery, authenticated remote `server_info.daemon.relay_transport` retains the bounded preceding episode that the daemon supplied during the current connection handshake, including brief interruptions below the default warning threshold. Promotion to a ready socket sets `outage_active=false`, extends the duration through actual readiness, preserves the preceding healthy-ready duration across failed candidates, canonicalizes timestamps, and accepts only enumerated coarse operational error classes; it does not claim that the recovered connection remains in outage. On macOS, `diagnose_runtime` may also return a coarse default-route class and `operating_system_interception` boolean. That diagnostic is returned on demand and is not promoted to default logs; interface names, IP addresses, DNS answers, proxy endpoints/credentials, Worker endpoints, tool arguments, and results remain absent. `relay.outage.active` and `relay.outage.recovered` carry the existing safe relay fields.
153
154
 
154
155
  Schema 4 is strict NDJSON. Before daemon startup, both active log files are opened as owner-only regular single-link files. A schema change clears both only after validation and commits the marker only after the transition succeeds. A symlink, multiple-hard-link inode, permission error, or marker-write failure blocks startup rather than mixing formats or repeatedly erasing evidence.
155
156
 
@@ -157,7 +158,7 @@ Schema 4 is strict NDJSON. Before daemon startup, both active log files are open
157
158
 
158
159
  Canonical `full` does not remove tools based on filenames. For remote execution, the operation classifier treats credential-sensitive paths and persistence targets as hard authorization boundaries: delegated roles are denied, while owner requests remain risk-classified and audited. An MCP host, connector, model provider, desktop application, operating system, or endpoint-security layer may independently reject a request before it reaches Machine Bridge.
159
160
 
160
- Use `server_info`, `project_overview`, `machine-mcp status`, `machine-mcp doctor`, and `diagnose_runtime` to distinguish local policy from host-side enforcement. Capability-routing status is returned on demand rather than written as task logs. The in-memory observer stores a runtime-keyed task fingerprint, selected skill/match counts, recommended tool names, primary route, ambiguity class, and score gap; it never stores raw task text, static instruction content, application inventory, or route explanations. Changing the Machine Bridge profile cannot override another layer.
161
+ Use `server_info`, `project_overview`, `machine-mcp status`, `machine-mcp doctor`, and `diagnose_runtime` to distinguish local policy from host-side enforcement. `doctor` explicitly reports that its isolated runtime did not inspect the running service process or remote relay; it must not be used as a substitute for `server_info.daemon.relay_transport`. Capability-routing status is returned on demand rather than written as task logs. The in-memory observer stores a runtime-keyed task fingerprint, selected skill/match counts, recommended tool names, primary route, ambiguity class, and score gap; it never stores raw task text, static instruction content, application inventory, or route explanations. Changing the Machine Bridge profile cannot override another layer.
161
162
 
162
163
  ## Adding or changing logs
163
164
 
@@ -8,7 +8,7 @@ machine-mcp doctor
8
8
  machine-mcp service status
9
9
  ```
10
10
 
11
- `status` prints redacted profile state and verifies the deployed Worker version. Resource source paths remain redacted. `doctor` checks Node.js, the package-installed Wrangler binary, Cloudflare login, Worker health, the configured policy, the automatic-without-per-operation-prompts authorization model, and the same fixed local filesystem/process/shell/job-storage/resource probes exposed by `diagnose_runtime`. Authenticated `server_info.authorization.execution_model` reports the same contract and identifies whether the account has daemon-OS-user ambient authority. Public `/healthz` output contains only server identity and version; daemon details require an authenticated `server_info` call.
11
+ `status` prints redacted profile state and verifies the deployed Worker version. Resource source paths remain redacted. `doctor` checks Node.js, the package-installed Wrangler binary, Cloudflare login, Worker health, the configured policy, the automatic-without-per-operation-prompts authorization model, and the same fixed local filesystem/process/shell/job-storage/resource probes exposed by `diagnose_runtime`. It constructs an isolated local runtime: `diagnosticScope.running_service_process_inspected=false` and `remote_relay_inspected=false` are deliberate, so a green doctor result is not evidence that the launchd/systemd/Scheduled Task daemon retained its Worker WebSocket. Inspect authenticated `server_info.daemon.relay_transport` for the running service relay. Authenticated `server_info.authorization.execution_model` reports the authority contract and identifies whether the account has daemon-OS-user ambient authority. Public `/healthz` output contains only server identity and version; daemon details require an authenticated `server_info` call.
12
12
 
13
13
  ### Worker deployment and health convergence
14
14
 
@@ -61,7 +61,7 @@ A successful diagnostic result applies only to that probe. An MCP host can still
61
61
 
62
62
  Machine Bridge supports concurrent calls: the Worker admits 32 pending daemon calls (30 ordinary plus two reserved control calls), and the local runtime admits 16 active tool calls (14 ordinary plus two reserved control calls). The same `diagnose_runtime`/`list_roots` control set is enforced at both layers. These are capacity limits, not a single global execution queue. Modern MCP `2026-07-28` HTTP requests are independent: JSON-RPC IDs are scoped to each request/response stream, so separate clients may reuse the same numeric ID even when they share one OAuth account and token. Legacy MCP `2025-11-25` initialization still receives a signed `Mcp-Session-Id`; idempotency, explicit cancellation, and replay for that compatibility path remain session-scoped. Within the bounded two-minute recovery window, a typed request ID denotes one operation and must not be intentionally reused for new work.
63
63
 
64
- `server_info.worker.pending_calls` reports `active`, `detached`, `request_keys`, `maximum`, `oldest_ms`, `by_tool`, `transient`, and `durable_streams`. `worker.sockets_live` separately reports `authenticated`, `probing`, `ready`, and `candidates`; only `ready` sockets contribute to `daemon.connected` and `authorization.effective_tools`. A nonzero `active` count means work is in flight, not that the bridge is globally locked. `detached > 0` means the daemon WebSocket was lost and calls are inside the bounded same-daemon reconnect interval. This relay-layer state exists below both MCP eras.
64
+ `server_info.worker.pending_calls` reports `active`, `detached`, `request_keys`, `maximum`, `oldest_ms`, `by_tool`, `transient`, and `durable_streams`. `worker.sockets_live` separately reports `authenticated`, `probing`, `ready`, and `candidates`; only `ready` sockets contribute to `daemon.connected` and `authorization.effective_tools`. `daemon.relay_transport` is the bounded, daemon-supplied summary captured during the current connection handshake: it records the immediately preceding reconnect episode without endpoints, interface names, arguments, or results. A nonzero `active` count means work is in flight, not that the bridge is globally locked. `detached > 0` means the daemon WebSocket was lost and calls are inside the bounded same-daemon reconnect interval. This relay-layer state exists below both MCP eras.
65
65
 
66
66
  For modern MCP `2026-07-28`, the public response stream is the request owner: closing it cancels the transient pending call, and no request-key or replay record should remain. For legacy MCP `2025-11-25`, the signed session and typed JSON-RPC ID own bounded idempotency and explicit `notifications/cancelled`; closing a resumable public stream alone does not cancel the operation. Legacy terminal completion, explicit cancellation, timeout, or reconnect-grace expiry must eventually return active/detached/pending-call request-key counts to zero, while the separate stream-level replay identity may remain until the two-minute recovery record expires. A verified same-daemon replacement may reclaim detached relay calls after readiness, while a new daemon process cannot. Delayed results from the old socket are rejected. `detached > 0` materially beyond the two-minute grace, a modern transient call surviving response closure, or a legacy request-key count remaining after active calls reach zero is a lifecycle defect.
67
67
 
@@ -71,21 +71,21 @@ For modern MCP `2026-07-28`, every POST advertises both `application/json` and `
71
71
 
72
72
  Legacy MCP `2025-11-25` retains the older delivery contract for existing hosts. Name, account-visible tool membership, and raw arguments are validated before any resumable record is allocated; malformed or role-hidden calls return `-32602` with no daemon dispatch. For a valid call, the outer Worker emits sequence-zero and sequence-one event IDs while `BridgeRoom` persists bounded session-bound stream/call ownership before daemon dispatch. A compatible legacy host should recover with authenticated `GET /mcp`, its original `Mcp-Session-Id`, and `Last-Event-ID`. If transport loss makes the original POST preparation or terminal response uncertain, an exact signed-session retry is safe throughout the stream's bounded recovery lifetime: the request identity and canonical argument fingerprint reattach it to the active or terminal stream, while changed arguments are rejected. Intentional new work must use a fresh typed request ID until that record expires or the client explicitly acknowledges sequence one, which deletes the replay record. Sessionless legacy POSTs remain independent for compatibility with clients that share one bearer token; without a signed session they do not receive POST idempotency, the outer Worker does not retry an ambiguous prepare, and the client must not blindly repeat an ambiguous side-effecting request. Legacy records are token/session-bound, retained for at most two minutes, limited to 64 streams, and persist at most 1.5 MiB of terminal JSON. Errors `-32002`, `-32003`, and `-32005` in this area are legacy recovery diagnostics, not modern protocol errors. Caller-supplied internal stream headers are removed at the public boundary in both eras.
73
73
 
74
- The daemon-to-Worker terminal protocol is at-least-once until `tool_result_ack`. Queueing a WebSocket frame is not durable delivery: the runtime retains a bounded terminal envelope, replays it after same-daemon reconnect or heartbeat, and removes it only after acknowledgement or the authoritative `resume_calls` reconciliation excludes it. The modern public stream has no replay surface; the legacy terminal store is generation-checked and exactly-once from the client's recovery perspective. `server_info.worker.observability.calls.unmatched_results` counts late results whose pending owner was already removed. A small increase may accompany cancellation or timeout races; sustained growth together with old pending calls indicates mixed versions or a lifecycle defect. The counter contains no arguments or result data.
74
+ The daemon-to-Worker terminal protocol is at-least-once until `tool_result_ack`. Queueing a WebSocket frame is not durable delivery: the runtime retains a bounded terminal envelope, replays it after same-daemon reconnect or heartbeat, and removes it only after acknowledgement or the authoritative `resume_calls` reconciliation excludes it. The modern public stream has no replay surface; the legacy terminal store is generation-checked and exactly-once from the client's recovery perspective. `server_info.worker.observability.terminal_results` separates the actual disposition of daemon result envelopes: `transient_committed` and `durable_committed` reached their owners; `owner_missing_acknowledged` arrived after the owner had already settled or been removed and was safely acknowledged to stop at-least-once replay; `stale_connection_rejected` came from a connection that no longer owned the durable call and was not acknowledged. The older `calls.unmatched_results` field remains a compatibility aggregate of the last two counters and must not be interpreted alone. Growth only in `owner_missing_acknowledged` usually indicates acknowledgement loss, cancellation, timeout, or deployment/reconnect overlap; growth in `stale_connection_rejected`, especially with old pending calls or protocol errors, indicates a connection-identity or lifecycle defect. These counters contain no arguments or result data.
75
75
 
76
76
  ### MCP host or connector internal-storage errors
77
77
 
78
78
  An error naming an internal shard mapper, temporary keyspace, backfill store, connector database, or host-side cache is not automatically a Machine Bridge Worker or daemon error. Check whether the exact text appears in repository source, Worker events, daemon logs, or local process output, and whether Worker `requests.server_error` increased. If even `server_info` fails before reaching the Worker while local readiness remains healthy, preserve credentials and state; report the host/connector incident separately rather than rotating OAuth/device secrets or redeploying blindly.
79
79
 
80
- After the host path recovers, compare `server_info`, `machine-mcp doctor`, and `machine-mcp service status`: ready socket count, pending age, daemon PID/start time, relay outage fields, and local logs. A host-storage incident and a genuine stale pending call can coexist; investigate the latter independently if it exceeds its operation or reconnect deadline.
80
+ After the host path recovers, compare authenticated `server_info`, `machine-mcp doctor`, and `machine-mcp service status`: ready socket count, pending age, daemon PID/start time, `daemon.relay_transport`, and local logs. Treat doctor as local dependency/probe evidence only; it does not inspect the running service relay. A host-storage incident and a genuine stale pending call can coexist; investigate the latter independently if it exceeds its operation or reconnect deadline.
81
81
 
82
82
  ### Relay interruption messages
83
83
 
84
- A reconnect warning proves a transport interruption, not a daemon crash. Compare daemon PID and process start time with `connected_at`, `last_seen_at`, relay close category/code, outage count, and the coarse system-route diagnostic. A VPN/TUN UI may remain “connected” while its upstream route is unusable. Machine Bridge reports only coarse route/proxy classes and never logs interface names, addresses, DNS answers, proxy credentials, or Worker secrets.
84
+ A reconnect warning proves a transport interruption, not a daemon crash. Compare daemon PID and process start time with `connected_at`, `last_seen_at`, `daemon.relay_transport.last_close_category`, `last_close_code`, `outage_count`, `outage_attempts`, and the coarse network-route class. A VPN/TUN UI may remain “connected” while its upstream route is unusable. Local OS logs can be compared with the exact `last_disconnected_at` timestamp, but an interface-quality change or tunnel-process correlation is not by itself proof of which product, node, edge, or upstream failed. Machine Bridge reports only coarse route/proxy classes and never sends or logs interface names, addresses, DNS answers, proxy credentials, or Worker secrets.
85
85
 
86
- Brief retryable outages reconnect automatically. A persistent outage emits bounded summaries; identity/version mismatch, authentication rejection, and unexpected protocol messages remain permanent failures requiring version convergence or credential repair. Compare outage intervals with sleep/wake records and `diagnose_runtime.runtime.relay.heartbeat` before classifying them as active network faults; local stdio `server_info.runtime.relay.heartbeat` exposes the same state. A nonzero `event_loop_stall_count` with a large `max_event_loop_lag_ms` means the local daemon was not scheduled promptly; during recovery grace it sends a new heartbeat and deliberately postpones disconnect. That is distinct from a relay that remains silent after local scheduling has recovered. Use `--verbose` only when close codes, heartbeat deadlines, and retry delays are required.
86
+ Brief retryable outages reconnect automatically. On a ready beta.37-or-newer socket, `server_info.daemon.relay_transport.outage_active=false`; the remaining fields describe the immediately preceding reconnect episode rather than a current outage. Because the login service logs at `warn`, a recovered interruption shorter than ten seconds intentionally has no default log line; inspect the authenticated relay snapshot instead. A persistent outage emits bounded summaries; identity/version mismatch, authentication rejection, and unexpected protocol messages remain permanent failures requiring version convergence or credential repair. Compare outage intervals with sleep/wake records and `diagnose_runtime.runtime.relay.heartbeat` before classifying them as active network faults; local stdio `server_info.runtime.relay.heartbeat` exposes the same state. A nonzero `event_loop_stall_count` with a large `max_event_loop_lag_ms` means the local daemon was not scheduled promptly; during recovery grace it sends a new heartbeat and deliberately postpones disconnect. That is distinct from a relay that remains silent after local scheduling has recovered. Use `--verbose` only when close codes, heartbeat deadlines, and retry delays are required.
87
87
 
88
- A foreground MCP tool is not a durable job. Every advertised MCP surface accepts at most 85 seconds and reserves terminal-delivery margin. Relay execution applies the same 30- or 60-second default when the field is omitted, and a registered-command manifest cannot extend a relay call past 85 seconds. An owner-local registered command may retain a longer explicit manifest timeout because it does not depend on a hosted response stream. Longer remote work belongs in `start_process` plus bounded `read_process`, or in a managed job. Keep mutation and verification in independently terminal calls when a host exposes only a foreground shell tool.
88
+ A foreground MCP tool is not a durable job. Every advertised MCP surface accepts at most 60 seconds of daemon execution. The Worker records a settlement deadline five seconds later than the daemon execution duration for result acceptance, persistence, acknowledgement, and terminal settlement. Admission and transport latency may consume part of that interval, and it is not a guarantee that an external host will consume the final frame. Relay execution applies the same 30- or 60-second default when the field is omitted, and a registered-command manifest cannot extend a relay call past 60 seconds. An owner-local registered command may retain a longer explicit manifest timeout because it does not depend on a hosted response stream. Longer remote work belongs in `start_process` plus bounded `read_process`, or in a managed job. Keep mutation and verification in independently terminal calls when a host exposes only a foreground shell tool.
89
89
 
90
90
  The daemon honors `HTTPS_PROXY`/`HTTP_PROXY` and `NO_PROXY` through standard environment-proxy resolution for remote Worker health and relay traffic. `wss:` targets use HTTPS proxy selection and `ws:` targets use HTTP proxy selection. Only HTTP and HTTPS proxy URLs are accepted. Invalid URLs or unsupported protocols fail startup with corrective guidance instead of entering the reconnect loop. `diagnose_runtime.runtime.relay.network_route` reports remotely, while local stdio `server_info.runtime.relay.network_route` reports `system-network-stack`, `application-http-proxy`, or `invalid-application-proxy-configuration`. This field describes only Machine Bridge application-level proxy selection: an operating-system VPN/TUN may still intercept `system-network-stack` traffic. `network_route_scope`, outage timestamps/durations, close category/code, transport error class, and next retry timing make that distinction explicit; proxy endpoints and credentials are never returned or logged. The browser-broker CLI health probe is a separate loopback-only path: it accepts only canonical `127.0.0.1`, uses direct Node HTTP with no proxy agent, and does not depend on `NO_PROXY`.
91
91
 
@@ -199,7 +199,7 @@ Uninstall acquires a state-root `maintenance.lock` that blocks new profile/state
199
199
 
200
200
  ### Lifecycle and pending-call diagnosis
201
201
 
202
- Remote `diagnose_runtime.runtime.lifecycle` reports `ready`, `starting`, `running`, `failed`, `stopping`, or `stopped`; `diagnose_runtime.observability.in_flight_calls` reports ordinary versus reserved local capacity; and `diagnose_runtime.runtime.processes` distinguishes active calls, draining calls whose protocol result already settled, currently terminating processes, and pending escalation checks. It also returns `runtime.execution_guardrails` and `runtime.security_audit`. Local stdio `server_info` exposes the equivalent fields under `server_info.runtime`, `server_info.observability`, and `server_info.security_audit`. A returned timeout therefore does not claim that all kernel or descendant work has already stopped. Worker `server_info.worker.pending_calls` reports the internal-call index, legacy request-key index, detached-call count, ordinary/control capacity, and current ordinary/control occupancy across transient and durable calls. Modern HTTP stream closure should remove its transient stream owner and pending daemon call; there is no modern replay record or request-key entry. Legacy terminal result, explicit cancellation, timeout, or reconnect-grace expiry must return active/detached/pending-call request-key counts to zero; the stream-level idempotency identity remains only for bounded replay retention. During a brief daemon interruption, legacy `active` and `request_keys` may remain nonzero while `detached` identifies the recoverable subset; after same-instance readiness, `detached` returns to zero without losing those requests. Nonzero legacy request-key counts after active calls reach zero indicate a lifecycle defect rather than normal load. `worker.observability.calls.unmatched_results` is the bounded counter for late results that no longer have a receiver.
202
+ Remote `diagnose_runtime.runtime.lifecycle` reports `ready`, `starting`, `running`, `failed`, `stopping`, or `stopped`; `diagnose_runtime.observability.in_flight_calls` reports ordinary versus reserved local capacity; and `diagnose_runtime.runtime.processes` distinguishes active calls, draining calls whose protocol result already settled, currently terminating processes, and pending escalation checks. It also returns `runtime.execution_guardrails` and `runtime.security_audit`. Local stdio `server_info` exposes the equivalent fields under `server_info.runtime`, `server_info.observability`, and `server_info.security_audit`. A returned timeout therefore does not claim that all kernel or descendant work has already stopped. Worker `server_info.worker.pending_calls` reports the internal-call index, legacy request-key index, detached-call count, ordinary/control capacity, and current ordinary/control occupancy across transient and durable calls. Modern HTTP stream closure should remove its transient stream owner and pending daemon call; there is no modern replay record or request-key entry. Legacy terminal result, explicit cancellation, timeout, or reconnect-grace expiry must return active/detached/pending-call request-key counts to zero; the stream-level idempotency identity remains only for bounded replay retention. During a brief daemon interruption, legacy `active` and `request_keys` may remain nonzero while `detached` identifies the recoverable subset; after same-instance readiness, `detached` returns to zero without losing those requests. Nonzero legacy request-key counts after active calls reach zero indicate a lifecycle defect rather than normal load. Diagnose late results through `worker.observability.terminal_results`: `owner_missing_acknowledged` is a safely terminated replay or race, while `stale_connection_rejected` is an ownership mismatch. `worker.observability.calls.unmatched_results` is retained only as their compatibility aggregate.
203
203
 
204
204
  Stable errors include `policy_denied`, `invalid_request`, `timeout`, `cancelled`, `network_error`, `unavailable`, `limit_exceeded`, and `integrity_error`, with retryability metadata. Diagnose by code first; free-form messages are guidance, not an API contract.
205
205
 
@@ -306,7 +306,7 @@ Defense-in-depth limits include:
306
306
  - process stdin write: 64 KiB per call;
307
307
  - local simultaneous tool calls: 16 total, with 14 ordinary slots and two reserved for bounded control-plane diagnosis/recovery;
308
308
  - Worker pending daemon calls: 32 total, with 30 ordinary slots and two reserved for bounded control-plane diagnosis/recovery;
309
- - synchronous foreground timeout schema on every MCP surface: 1–85 seconds with tool-specific 30- or 60-second defaults; the Worker reserves five seconds for terminal delivery, and the relay execution boundary reapplies the same default/ceiling before process spawn, including registered commands whose local manifest is longer; use process sessions or managed jobs for longer remote work;
309
+ - synchronous foreground timeout schema on every MCP surface: 1–60 seconds with tool-specific 30- or 60-second defaults; the daemon execution deadline is capped at that value, while the Worker uses a separate deadline five seconds later for terminal settlement; the relay execution boundary reapplies the execution default/ceiling before process spawn, including registered commands whose local manifest is longer; use process sessions or managed jobs for longer remote work;
310
310
  - process-session read wait: at most 30 seconds, measured with monotonic elapsed time;
311
311
  - direct directory result: 10,000 entries and 4 MiB of path metadata;
312
312
  - recursive walk: 200,000 visited entries;
package/docs/RELEASING.md CHANGED
@@ -165,7 +165,7 @@ From the exact accepted source checkout, the owner runs:
165
165
  npm run prerelease:install -- --allow-worker-deploy
166
166
  ```
167
167
 
168
- This command verifies that the npm registry tarball SHA-1/SHA-512 and dist-tag match the locally accepted candidate, installs that exact published version globally, updates the Worker and login daemon, verifies both versions, and writes an owner-only `npm-prerelease` activation record. The formal soak clock starts from this activation record, not from a local unpublished candidate.
168
+ This command verifies that the npm registry tarball SHA-1/SHA-512 and dist-tag match the locally accepted candidate, installs that exact published version globally, updates the Worker and login daemon, verifies both versions, and writes an owner-only `npm-prerelease` activation record. Schema 2 names any retained fallback explicitly as `global_package_rollback_baseline`: it identifies the globally installed npm package and entrypoint available for operator-directed disaster recovery, not the service runtime that was active immediately before activation. The activation transaction captures and verifies that previous service identity separately while the handoff is in progress. Schema 1 records using the legacy `previous` field remain readable and are normalized in memory without rewriting historical evidence. The formal soak clock starts from this activation record, not from a local unpublished candidate.
169
169
 
170
170
  Use the prerelease normally. Exercise the changed areas under real workloads. A crash, authorization anomaly, data-loss risk, repeated relay failure, incorrect service lifecycle, significant compatibility regression, or security/privacy defect is blocking.
171
171
 
package/docs/TESTING.md CHANGED
@@ -78,11 +78,11 @@ The suite includes:
78
78
  - guarded state-root removal, unsafe state-root/workspace overlap rejection before creation, all-profile lock/daemon scanning, strict current-schema validation, corrupt-JSON isolation, and policy-origin persistence;
79
79
  - no filename-based sensitive-file denial under unrestricted policy;
80
80
  - shared local/Worker free-form log redaction, sensitive content under non-sensitive Worker keys, immutable local/Worker structured metadata, control-character handling, message/field bounds, suppression of both successful and failed per-tool events outside debug, service warning-level configuration, JSON-mode parity across event and direct logger methods with timestamp/stream/redaction assertions, current-schema reset, and bounded tail trimming;
81
- - deterministic relay connection lifecycle coverage for transport construction/error/deadline, failed `hello` delivery, pre-handshake `welcome` validation, separate `hello_ack` authentication and `ready_ack` end-to-end readiness, session-bound probe return and probe-delivery races, pre-ready tool rejection, premature-ready rejection, identity/version mismatch, retryable Worker hello/readiness/transport/liveness errors, retryable close-only transport/liveness delivery, fatal unknown protocol errors, autonomous outage-reminder backoff, handshake/readiness/heartbeat timeout, brief-outage suppression, sustained-outage escalation, recovery summaries, and supersession;
82
- - shared no-follow bounded-file reads for normal files, over-limit data, directories, and symbolic links;
81
+ - deterministic relay connection lifecycle coverage for transport construction/error/deadline, failed `hello` delivery, pre-handshake `welcome` validation, separate `hello_ack` authentication and `ready_ack` end-to-end readiness, session-bound probe return and probe-delivery races, pre-ready tool rejection, premature-ready rejection, identity/version mismatch, retryable Worker hello/readiness/transport/liveness errors, retryable close-only transport/liveness delivery, preservation of a specific timeout classification when a late generic error arrives, fatal unknown protocol errors, autonomous outage-reminder backoff, handshake/readiness/heartbeat timeout, brief-outage suppression, sustained-outage escalation, recovery summaries, and supersession;
82
+ - shared no-follow bounded-file reads for normal files, over-limit data, directories, symbolic links, and multiple-hard-link denial; typed file-mutation regressions cover create-only collisions, stale SHA-256 preconditions, missing/ambiguous edit text, malformed/stale patches, transactional rollback, Worker preservation, stdio projection, and path/content/hash non-disclosure;
83
83
  - owner-only directory enforcement rejecting final symlinks, failing closed on POSIX chmod errors, verifying `0700`, and retaining Windows portability; Worker temporary-secret lifecycle coverage for process-start-bound names, valid stale-owner reclamation, ambiguous-owner retention, `0600` mode, deletion failures, and simultaneous deployment/cleanup failures;
84
84
  - SARIF security-gate behavior for unknown findings, exact accepted rule/path matches, path mismatch rejection, rationale quality, and exception expiry;
85
- - deterministic property tests over hostile browser-protocol byte strings, canonical/custom policy combinations, argv bounds/NULs, and a real direct process proving shell metacharacters remain literal argv; direct timeout-alignment tests prove relay shell/direct-process defaults are 60 seconds, relay registered commands are capped at 85 seconds even when their owner manifest is longer, and owner-local registered commands retain the manifest budget; process-tree tests also assert Darwin uses a target-PGID `ps` query, preserve the global inspection budget, and repeatedly prove anti-`SIGTERM` descendants exit after foreground timeout;
85
+ - deterministic property tests over hostile browser-protocol byte strings, canonical/custom policy combinations, argv bounds/NULs, and a real direct process proving shell metacharacters remain literal argv; direct timeout-alignment tests prove relay shell/direct-process defaults are 60 seconds, relay registered commands are capped at 60 seconds even when their owner manifest is longer, daemon execution and Worker settlement deadlines remain distinct, and owner-local registered commands retain the manifest budget; process-tree tests also assert Darwin uses a target-PGID `ps` query, preserve the global inspection budget, and repeatedly prove anti-`SIGTERM` descendants exit after foreground timeout;
86
86
  - prototype-shaped command, action, role, profile, form-field, keyboard, and resource names proving that inherited object properties are never interpreted as dispatch or authority; current-schema malformed OAuth roles are repaired to disabled reviewer accounts with credential revocation;
87
87
  - canonical Worker deployment URL extraction proving unrelated `/mcp`, `/healthz`, path-bearing, and wrong-name URLs cannot be persisted as upload evidence;
88
88
  - byte-exact UTF-8 DOM-source truncation across emoji and Chinese partial-code-point boundaries, including equality between the reported byte count and the encoded returned source;
@@ -93,7 +93,7 @@ The suite includes:
93
93
  - P-256 root generation, root-certified ephemeral session issuance, macOS trust-broker build/signature checks, signed WebSocket preflight, one-time transactional nonce consumption, challenge transcript binding, wrong-root/session/tamper/expiry/replay rejection, and prevention of unauthenticated candidate churn;
94
94
  - request-scoped effective authority and catalog-wide risk review; non-escalatable reviewer/editor/operator ceilings; authenticated-owner direct execution; control-plane root denial; external and sensitive path composition; persistence-target rejection; symbolic-link ancestor and patch-move canonicalization; owner-only browser/application/data-export and persistent-plan effects; account/client/refresh-family ownership of processes, output sessions, and jobs; delegated sandbox fail-closed behavior; legacy-lease non-consumption; and malformed-record rejection;
95
95
  - root-certified ephemeral P-256 account-administration requests with origin/method/path/body/key/time/nonce binding, transactional one-time nonce consumption, removal of the long-lived administration secret, certificate/signature/body tamper rejection, nonce replay rejection, malformed nonce-state fail-closed behavior, one-megabyte response bounds, immediate oversized-response cancellation, and strict successful JSON-object validation;
96
- - live local Worker OAuth registration and authorization metadata; PKCE, DCR, refresh rotation/replay, account/client/family revocation, DPoP, actual `/mcp` Origin checks, bounded CORS/CSP, exact callback handling, and bounded OAuth persistence; modern MCP `2026-07-28` per-request `_meta`, open-JSON structural budgets, bounded resource subscriptions, strict dual-media `Accept` quality values, mirrored header/body validation, `server/discover`, result identity, cache hints, same-token/same-request-ID concurrency, role-hidden/unknown/schema `-32602` non-dispatch, credential-free private cancellation (including public-header forgery and DPoP replay controls), request-scoped streaming, filtered `subscriptions/listen`, removed-method 404 behavior, and no session/replay leakage; plus the complete legacy MCP `2025-11-25` initialize, pre-persistence raw-argument validation, signed-session cancellation, sequence event, recovery GET, `Last-Event-ID`, bounded idempotent-retry/conflict domain, and replay-isolation suite. The same integration covers the shared 85-second foreground timeout ceiling and matching local relay execution defaults, signed-session cloned prepare retry, DPoP proof/retry-ID atomic binding and replay isolation, sessionless no-retry safety, and active-or-terminal stream reattachment, canonical argument fingerprints, concurrent legacy subscriber multicast/limits/cancellation cleanup, layered global/subject rate-limit identity, daemon candidate/probing/ready replacement, malformed daemon messages, rich content, account-role projection, and stable catalog behavior before/during/after daemon availability.
96
+ - live local Worker OAuth registration and authorization metadata; PKCE, DCR, refresh rotation/replay, account/client/family revocation, DPoP, actual `/mcp` Origin checks, bounded CORS/CSP, exact callback handling, and bounded OAuth persistence; modern MCP `2026-07-28` per-request `_meta`, open-JSON structural budgets, bounded resource subscriptions, strict dual-media `Accept` quality values, mirrored header/body validation, `server/discover`, result identity, cache hints, same-token/same-request-ID concurrency, role-hidden/unknown/schema `-32602` non-dispatch, credential-free private cancellation (including public-header forgery and DPoP replay controls), request-scoped streaming, filtered `subscriptions/listen`, removed-method 404 behavior, and no session/replay leakage; plus the complete legacy MCP `2025-11-25` initialize, pre-persistence raw-argument validation, signed-session cancellation, sequence event, recovery GET, `Last-Event-ID`, bounded idempotent-retry/conflict domain, and replay-isolation suite. The same integration covers the shared 60-second foreground timeout ceiling and matching local relay execution defaults, signed-session cloned prepare retry, DPoP proof/retry-ID atomic binding and replay isolation, sessionless no-retry safety, and active-or-terminal stream reattachment, canonical argument fingerprints, concurrent legacy subscriber multicast/limits/cancellation cleanup, layered global/subject rate-limit identity, daemon candidate/probing/ready replacement, malformed daemon messages, rich content, account-role projection, and stable catalog behavior before/during/after daemon availability.
97
97
  - local runtime proof that one blocked tool handler does not serialize an independent handler, plus relay fault injection proving an undeliverable terminal result interrupts the ambiguous socket and enters reconnect backoff.
98
98
  - a real headless-Chrome OAuth navigation regression with bounded browser startup, DevTools discovery, WebSocket connection, and per-command deadlines, covering four cases: `form-action 'self'` blocks the first cross-origin callback, allowing only the registered callback blocks the regional redirect, allowing the registered and regional callbacks blocks the final Copilot Studio redirect, and the complete policy preserves `code` and `state` through all three cross-origin hops. Linux CI fails if Chrome is unavailable; other environments skip only this browser executable check while retaining the Worker CSP assertions.
99
99
 
@@ -115,7 +115,7 @@ For deterministic release validation, perform an isolated-profile smoke test wit
115
115
  `npm run control-plane-resilience:test` is the focused accident-regression gate. It exercises synchronous/asynchronous audit failures, cached-state invalidation after external alteration, count- and byte-bounded retention anchoring, POSIX/Windows process-tree fallbacks, escalation-supervisor exception isolation, mixed transient/durable Worker capacity, and the shared 30+2 / 14+2 control-plane admission contract. `npm run security-audit:test` additionally runs two independent audit workers against one owner-only state file and requires continuous sequence numbers with no lost events, covering the lock release/acquire race. Both are part of the fast plan rather than coverage-only evidence.
116
116
 
117
117
  - control-plane resilience under host pressure: local event-loop stalls versus genuine relay silence, fresh-heartbeat recovery grace, asynchronous process-group identity capture before `SIGTERM`, bounded post-signal revalidation, draining-process visibility after result settlement, two reserved diagnostic slots at both Worker and local layers under mixed transient/durable ordinary-call saturation, non-blocking audit dispatch, batched Worker persistence, queue/drop health, warning suppression, and privacy-safe audit projection;
118
- - relay outage diagnostics and recovery: application-proxy versus OS-network scope, timestamped close/outage/recovery fields, fifteen-second maximum reconnect delay, heartbeat timeout, same-instance call continuation, Worker pong/welcome send failure, and `diagnose_runtime` relay history;
118
+ - relay outage diagnostics and recovery: application-proxy versus OS-network scope, timestamped close/outage/recovery fields, bounded authenticated hello projection and recovered ready-state semantics in `server_info.daemon.relay_transport`, fifteen-second maximum reconnect delay, socket-generation-bound authentication proofs, specificity-preserving close causes, heartbeat timeout, same-instance call continuation, idempotent Worker cleanup across `error` plus `close`, scheduling-free candidate/readiness/liveness invalidation, post-detach deadline recomputation, concurrent cleanup deduplication plus failure retry, previous-ready-duration retention, retained asynchronous stale-socket cleanup with rejection containment, Worker pong-before-alarm ordering, one explicit terminal-result alarm schedule, event-time alarm write and durable-deadline-read failure isolation, pong/welcome send failure, and `diagnose_runtime` relay history;
119
119
  - recoverable managed-job terminal commits under injected result/status/delete/confirmation failures, result-only terminal reconstruction, private runtime/plan scrubbing, 24-hour staged-plan expiry, and minimal/full runner-environment inheritance;
120
120
  - cross-process security-audit serialization, continuous hash-chain sequence, uninstall blocking for audit/authorization/job transition/recovery locks, workspace recovery-envelope validation, and symlink/multiple-hard-link rejection at owner state and operational logs;
121
121
  - browser fixed identity, role-separated credentials, legacy migration, socket replacement/reconnect/timer cleanup, duplicate request rejection, response-delivery failure, and read-only broker load projection;
@@ -180,7 +180,7 @@ The stdio integration test also sends an oversized line, verifies bounded reject
180
180
 
181
181
  `npm run mcp-resumption:test` directly exercises stream cursor parsing, OAuth-token/MCP-session isolation, immediate pending/terminal polls, active and completed replay, orphaned-stream restart ambiguity, persisted-call restart recovery, strict call-record validation, request-key uniqueness, operation/reconnect deadlines, repeated detach/rebind retention extension, stale-generation rejection, prototype-safe aggregation, exactly-once completion, result-size fallback, SHA-256 tamper detection, transient persistence failure, expiry, capacity, completed-record eviction, the four-row plain-stream budget, and the fixed six-row durable-call lifecycle budget.
182
182
 
183
- `npm run worker-runtime-infrastructure:test` verifies both delivery eras. Modern coverage proves private prepare/subscribe/cancel control headers are stripped at the public edge, transient ownership is memory-only, cancellation releases it exactly once, no event ID or replay record is created, and already-attached internal settlement cannot make a cancelled stream reusable. Legacy coverage retains descriptor/subscriber adaptation, sequence-zero/sequence-one framing, hibernatable subscription replacement, durable ownership/settlement, timeout/reconnect alarms, two-minute/64-stream/1.5-MiB bounds, stale-generation rejection, result acknowledgement/replay, and same-instance handover. Shared checks cover stateful burst limiting, gateway failures, daemon call deadlines, socket isolation, output/log maintenance, and no request-key leaks.
183
+ `npm run worker-runtime-infrastructure:test` verifies both delivery eras. Modern coverage proves private prepare/subscribe/cancel control headers are stripped at the public edge, transient ownership is memory-only, cancellation releases it exactly once, no event ID or replay record is created, and already-attached internal settlement cannot make a cancelled stream reusable. Legacy coverage retains descriptor/subscriber adaptation, sequence-zero/sequence-one framing, hibernatable subscription replacement, durable ownership/settlement, timeout/reconnect alarms, two-minute/64-stream/1.5-MiB bounds, stale-generation rejection, result acknowledgement/replay, and same-instance handover. Shared checks cover stateful burst limiting, gateway failures, separate daemon-execution/Worker-settlement deadlines, storage-backed versus live-subscriber terminal paths, socket isolation, output/log maintenance, and no request-key leaks.
184
184
 
185
185
  `npm run worker:integration-test` exercises the real Wrangler/OAuth/daemon path. It runs ordinary modern and legacy regression cases by default. When `MBM_OFFICIAL_CONFORMANCE_CHECKOUT` and `MBM_OFFICIAL_CONFORMANCE_SCENARIOS` are set, it also drives the pinned official MCP conformance checkout through a test-only loopback proxy that injects the already-created short-lived test bearer token. The production OAuth endpoint is unchanged, the alpha conformance package is not added to the dependency graph, and `tests/mcp-conformance-baseline.yml` contains only check-scoped exclusions for capabilities the production server intentionally does not advertise. A new unrelated failure or a stale expected-failure entry fails the run. The checkout must be a real directory with a committed lockfile and installed dependencies; missing or cleaned checkouts fail before Worker startup rather than surfacing as an ambiguous spawn error. Treat the alpha runner as an external audit tool: record its exact commit, inspect its own `npm audit` result, run it only against the loopback proxy, and remove the checkout afterward.
186
186