machine-bridge-mcp 3.0.0-beta.201 → 3.0.0-beta.205

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 (97) hide show
  1. package/CHANGELOG.md +14 -10
  2. package/README.md +5 -7
  3. package/SECURITY.md +5 -7
  4. package/bin/machine-mcp.mjs +11 -1
  5. package/browser-extension/manifest.json +1 -1
  6. package/cloudflare.config.ts +1 -0
  7. package/docs/AUDIT.md +8 -3
  8. package/docs/CLIENTS.md +5 -1
  9. package/docs/LOCAL_AUTHORIZATION.md +10 -13
  10. package/docs/LOGGING.md +2 -0
  11. package/docs/MULTI_ACCOUNT.md +7 -7
  12. package/docs/OPERATIONS.md +2 -0
  13. package/docs/POLICY_REFERENCE.md +8 -8
  14. package/docs/THREAT_MODEL.md +2 -2
  15. package/docs/TOOL_REFERENCE.md +49 -16
  16. package/docs/UPGRADING.md +3 -3
  17. package/package.json +6 -3
  18. package/scripts/github-push.mjs +4 -4
  19. package/scripts/github-release.mjs +4 -4
  20. package/scripts/network-retry.mjs +4 -1
  21. package/scripts/published-release.mjs +2 -0
  22. package/src/local/account-access.mjs +0 -2
  23. package/src/local/agent-context.mjs +27 -6
  24. package/src/local/agent-skill-discovery.mjs +14 -0
  25. package/src/local/agent-text-file.mjs +2 -0
  26. package/src/local/app-automation.mjs +17 -10
  27. package/src/local/authority-context.mjs +26 -5
  28. package/src/local/autostart-log-maintenance.mjs +1 -0
  29. package/src/local/bounded-output-helpers.mjs +29 -0
  30. package/src/local/bounded-output.mjs +35 -27
  31. package/src/local/browser-extension-path.mjs +2 -0
  32. package/src/local/browser-operation-service.mjs +1 -0
  33. package/src/local/cli-options.mjs +7 -2
  34. package/src/local/cli.mjs +9 -1
  35. package/src/local/computer-use-arguments.mjs +34 -4
  36. package/src/local/directory-metadata.mjs +7 -2
  37. package/src/local/errors.mjs +21 -5
  38. package/src/local/execution-routing.mjs +23 -4
  39. package/src/local/file-mutation-coordinator.mjs +6 -1
  40. package/src/local/git-content-service.mjs +83 -0
  41. package/src/local/git-sensitive-path-filter.mjs +63 -0
  42. package/src/local/git-service.mjs +11 -34
  43. package/src/local/managed-job-capacity-maintenance.mjs +24 -0
  44. package/src/local/managed-job-dependencies.mjs +16 -1
  45. package/src/local/managed-job-listing-records.mjs +45 -0
  46. package/src/local/managed-job-listing.mjs +3 -30
  47. package/src/local/managed-job-read-policy.mjs +7 -0
  48. package/src/local/managed-job-read-wait.mjs +14 -0
  49. package/src/local/managed-job-recovery-listing.mjs +3 -1
  50. package/src/local/managed-job-terminal-evidence-helpers.mjs +48 -0
  51. package/src/local/managed-job-terminal-evidence.mjs +71 -0
  52. package/src/local/managed-job-terminal-maintenance.mjs +20 -25
  53. package/src/local/managed-job-transient-recovery-capacity.mjs +1 -1
  54. package/src/local/managed-jobs.mjs +24 -17
  55. package/src/local/numbers.mjs +1 -21
  56. package/src/local/operation-authorization.mjs +61 -9
  57. package/src/local/operation-risk.mjs +10 -2
  58. package/src/local/process-fatal.mjs +40 -0
  59. package/src/local/process-output-stream.mjs +33 -7
  60. package/src/local/records.mjs +1 -9
  61. package/src/local/relay-peer-diagnostics.mjs +9 -3
  62. package/src/local/relay-tool-schema-extension.mjs +10 -2
  63. package/src/local/runtime-activity-projection.mjs +14 -6
  64. package/src/local/runtime-info-projection.mjs +5 -1
  65. package/src/local/runtime-info-relay-projection.mjs +18 -16
  66. package/src/local/runtime-tool-handlers.mjs +1 -1
  67. package/src/local/runtime.mjs +4 -4
  68. package/src/local/service.mjs +3 -0
  69. package/src/local/stdio.mjs +176 -16
  70. package/src/local/windows-launcher.mjs +3 -1
  71. package/src/local/workspace-file-rename-retry.mjs +32 -0
  72. package/src/local/workspace-file-service.mjs +54 -61
  73. package/src/local/workspace-file-transaction-helpers.mjs +73 -0
  74. package/src/local/workspace-file-transaction.mjs +35 -67
  75. package/src/local/workspace-profile-migration.mjs +55 -11
  76. package/src/local/workspace-search-service.mjs +212 -0
  77. package/src/local/workspace-search.mjs +18 -1
  78. package/src/shared/access-contract.json +9 -2
  79. package/src/shared/numbers.mjs +30 -0
  80. package/src/shared/project-overview-projection.mjs +10 -0
  81. package/src/shared/records.mjs +12 -0
  82. package/src/shared/result-projection.mjs +6 -4
  83. package/src/shared/server-metadata.json +3 -3
  84. package/src/shared/tool-call-capacity.mjs +4 -15
  85. package/src/shared/tool-catalog.json +49 -16
  86. package/src/worker/access.ts +0 -2
  87. package/src/worker/daemon-channel.ts +0 -8
  88. package/src/worker/index.ts +1 -1
  89. package/src/worker/mcp-http-contract.ts +7 -33
  90. package/src/worker/oauth-controller.ts +4 -1
  91. package/src/worker/oauth-refresh-exchange.ts +18 -15
  92. package/src/worker/oauth-refresh-retry.ts +34 -0
  93. package/src/worker/oauth-tokens.ts +5 -0
  94. package/src/worker/worker-entry.ts +7 -1
  95. package/tsconfig.local.json +41 -1
  96. package/wrangler.config.ts +1 -0
  97. package/wrangler.jsonc +1 -0
package/CHANGELOG.md CHANGED
@@ -1,17 +1,21 @@
1
1
  # Changelog
2
2
 
3
- ## 3.0.0-beta.201 - 2026-10-17
3
+ ## 3.0.0-beta.205 - 2026-10-19
4
4
 
5
- - Stop successful network commands before transient-output classification so application text cannot replay completed side effects.
6
- - Bound process-output and diagnostic-buffer allocation before copying; retain independent snapshots without holding oversized producer buffers, and remove unreachable overflow handling.
7
- - Preserve nested npm configuration/engine failure diagnostics while keeping successful verification output concise.
8
- - Make workflow-policy fault injection independent of historical action commit strings; apply the reviewed grouped Action updates.
9
- - Reconcile cf 1.0.0-beta.18, Wrangler 4.151.1, ESLint 10.13.0 and Node types 26.6.5 across exact source/private dependency contracts, Miniflare/workerd pins, install-script approvals, network artifact integrity and runtime type generation.
10
- - Exercise the upstream cf exported network factory directly instead of injecting an internal minifier symbol into a copied module.
11
- - Record a revision-bound comparison of 37 related projects, adopted improvements and retained compatibility/security boundaries.
5
+ - Supersede beta.203 after its Windows atomic-replacement and macOS resource CLI checks failed, and beta.204 after review reproduced an external-generation overwrite during a replacement retry. Repeat exact-package activation and deployed OAuth acceptance for the new candidate.
6
+ - Revalidate the expected content digest before every atomic-replacement attempt so an external edit after a transient sharing failure returns a conflict and retains the external generation; regression coverage also verifies staging cleanup.
7
+ - Preserve an absent coverage environment variable in uninstrumented CLI test children so an exact-runtime version probe retains its light resource classification; assert the actual CLI environment before submission.
8
+
9
+ - Keep one bridge Durable Object per deployment. The `x-mbm-workspace` / `?workspace=` shard selector is removed: it had no producer, and an unauthenticated request header could fork OAuth clients, tokens, the daemon registry, and pending calls into a second consistency domain.
10
+ - Add an opt-in `--compat` stdio mode for legacy hosts that refuse to start without `initialize`. It accepts the removed handshake and `notifications/initialized` without creating a session, advertises the server's own protocol version instead of echoing the client's, and fills request metadata only when fields are absent; explicit retired, future, or malformed metadata remains subject to normal rejection. `client-config` no longer injects the flag, and `--help` documents it.
11
+ - Make `browser_screenshot.allow_tab_switch` reachable over MCP: the catalog now declares the option and the service parses it as a strict boolean, so non-disruptive capture can fail on an inactive target instead of activating it.
12
+ - Replace the `MBM_DEBUG`-driven verbose error projection with an explicit per-call option. `MBM_DEBUG` no longer widens tool error output, the stdio server opts in per process with `MBM_VERBOSE_ERRORS=1`, the relay never opts in, and verbose messages and causes share the single sanitized 2000-character ceiling of the public message field.
13
+ - Drop the placeholder Desktop Automation and Power Management abstraction classes; capability reporting is now a plain function over the platform.
14
+ - Align `cloudflare.config.ts`, `wrangler.config.ts`, and `wrangler.jsonc` on the documented deployment topology, and relax `devEngines.packageManager` to `warn` so older npm setups do not hard-fail initialization.
15
+ - Bound stdio response backlog and output-buffer copying; harden protected-path resolution, terminal-job evidence checks, file-transaction cleanup reporting, and default instruction-context payloads. Add regression tests for the associated security, settlement, and performance boundaries.
16
+ - Retry bounded transient filesystem sharing errors during atomic file replacement so concurrent Windows readers do not cause a premature update failure; preserve the original error after exhaustion and reject non-transient failures immediately.
17
+ - Repository hygiene: ignore the generated `.workflow/` directory and drop cached review artifacts and intermediate backups from the local workspace.
12
18
 
13
- - Retire expired Scorecard exceptions no longer present in the latest provider report; re-review the three exact CodeQL findings, correct the admin request-body digest rationale, and validate checked-in exception expiry in the fast suite.
14
- - Preserve explicit native lifecycle contracts after verifying the controller's automatic inference; use a clean worktree to keep unrelated helper languages out of project verification.
15
19
 
16
20
  ## Historical releases
17
21
 
package/README.md CHANGED
@@ -50,10 +50,8 @@ The complete component and trust-boundary diagram is in [docs/OVERVIEW.md](docs/
50
50
 
51
51
  ## MCP protocol model
52
52
 
53
- Machine Bridge uses MCP `2026-07-28` for both stdio and remote HTTP. There is no successful initialization-era adapter: every supported request is current and request-scoped.
54
-
55
- - **Native current requests are self-describing.** Protocol version and client capabilities travel in `_meta`; HTTP requests also mirror the version, method, and applicable name/parameter values into validated headers. Current `2026-07-28` clients use `server/discover` and do not create an MCP protocol session.
56
- - **Removed protocol requests fail closed.** `initialize`, `Mcp-Session-Id`, `Last-Event-ID`, and other explicit removed session/replay markers do not dispatch tool work and receive bounded upgrade guidance. Remote `/mcp` is POST-only; GET remains a 405 method rejection. Obsolete clients must reconnect with MCP `2026-07-28`.
53
+ Machine Bridge uses MCP `2026-07-28` for both stdio and remote HTTP under one current request-scoped protocol contract. The default stdio path and remote HTTP require current request-scoped metadata. The opt-in stdio `--compat` shim answers only the legacy initialization handshake and fills metadata fields only when absent; explicit retired, future, or malformed versions remain rejected. It does not restore sessions or replay behavior.
54
+ Removed protocol requests fail closed with bounded upgrade guidance; hosted clients must reconnect with MCP `2026-07-28` and use `server/discover` rather than initialization.
57
55
  - **HTTP streams are request-scoped and non-resumable.** Closing the response stream cancels that request. There is no recovery GET, SSE event-ID replay, or session-bound delivery store.
58
56
  - **Removed session/replay semantics never execute.** Unsupported protocol dates and requests for the retired session/recovery model receive bounded rejection or upgrade guidance rather than legacy state or replay behavior.
59
57
  - **Transport identity is not conversation identity.** Stdio and HTTP processes/connections may interleave unrelated requests; state that spans calls must use an explicit tool, job, process-session, or resource identifier.
@@ -67,7 +65,7 @@ The Worker validates the actual `/mcp` Origin, mirrored headers, role-filtered t
67
65
  - Node.js 26 or newer
68
66
  - npm 12 or newer
69
67
 
70
- The project intentionally follows one current runtime baseline rather than carrying compatibility branches for older Node/npm behavior. Node 26 provides the tested process, module, permission, and platform semantics used by the release gates; npm 12 provides the installation-script controls used by the documented global install. `.node-version`, `.nvmrc`, `packageManager`, strict engines, local checks, and CI keep that baseline consistent.
68
+ The project intentionally follows one current runtime baseline rather than carrying compatibility branches for older Node/npm behavior. Node 26 provides the tested process, module, permission, and platform semantics used by the release gates; npm 12 provides the installation-script controls used by the documented global install. `.node-version`, `.nvmrc`, `packageManager`, published `engines`, and `.npmrc engine-strict=true` keep that baseline consistent; `devEngines` is advisory (`onFail: warn`) so dependency automation can still refresh the lockfile on a newer Node.
71
69
 
72
70
  ## Install
73
71
 
@@ -186,7 +184,7 @@ Planned shutdown sends `daemon_draining` before relay close. An interrupted `rea
186
184
 
187
185
  Hosted synchronous calls otherwise retain their ordinary 20-second execution plus separate five-second Worker settlement margin. Configurable browser/application tools use 20-second defaults; compound `computer_observe` / `computer_act` retain 30-second defaults, with a 45-second explicit maximum. Durable process acceptance and continuation have separate budgets below. These limits do not establish external host receipt or a whole-assistant-turn deadline.
188
186
 
189
- `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).
187
+ `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. Remote arbitrary process execution and process-session controls are owner-only, including under the `agent` profile. Process sessions, retained output, and managed jobs are additionally bound to account, client, and refresh-token family. See [local authorization](docs/LOCAL_AUTHORIZATION.md).
190
188
 
191
189
  ## Browser and application automation
192
190
 
@@ -215,7 +213,7 @@ The retained-state cap is 512. A hosted helper awaiting its promised terminal re
215
213
 
216
214
  Jobs can declare `depends_on`: the dependent remains `queued/dependency_wait` before main execution, upstream failure yields `dependency_failed`, and active/staged dependencies protect referenced results. Register secrets as local resource aliases and put idempotent cleanup in `finally_steps`. Timeout or cancellation alone does not prove process-tree settlement. See [managed jobs](docs/MANAGED_JOBS.md) for examples, retention, recovery, and privacy boundaries.
217
215
 
218
- The repository-tracked `workflow-bundle.json` is the project-native lifecycle authority for local readiness. Its `project-native:npm:check:fast` and `project-native:npm:check:full` stages must remain `sandbox: required`; a machine-local or untracked lifecycle file must not silently lower high-risk containment. Release architecture checks enforce both Git tracking and those required Seatbelt modes, so the job-local continuation contract above is validated under the same repository-owned verification authority used for the candidate.
216
+ The repository-tracked `workflow-bundle.json` is the project-native lifecycle authority for local readiness. Offline artifact, project, and architecture fixtures require Seatbelt containment. The complete `project-native:npm:check:fast` and `project-native:npm:check:full` stages use normal host permissions because their required checks exercise loopback servers, browser/native operations, and registry installation. Release architecture checks enforce the exact commands, provenance, and containment modes; a machine-local lifecycle file cannot replace them.
219
217
 
220
218
  The Job Monitor is deliberately a status surface, not a duplicate result viewer. Its app-only reads expose only bounded lifecycle state; command output, command text, paths, nested step results, and recovery/control capabilities remain on the normal managed-job result path. The `recovery_key` is present in the render input only because it is the View's read authority and is cleared from View memory on teardown. If optional monitor coordination storage is unavailable after `start_job` or `read_job` has already succeeded, Machine Bridge keeps the durable job result authoritative and falls back to normal model-side continuation rather than reporting a new job failure.
221
219
 
package/SECURITY.md CHANGED
@@ -68,7 +68,7 @@ The roles are:
68
68
 
69
69
  - `reviewer`: read-only selected-workspace access;
70
70
  - `editor`: selected-workspace reads and deterministic file mutation;
71
- - `operator`: workspace-confined mutation and direct process execution;
71
+ - `operator`: workspace-confined mutation through structured tools; arbitrary process execution is owner-only;
72
72
  - `owner`: complete bridge authority within the daemon policy ceiling.
73
73
 
74
74
  No approval ID, refresh token, reconnect, or client registration can expand a role. Out-of-role operations fail with `authorization_denied`.
@@ -93,13 +93,11 @@ Whether a process receives the complete parent environment is derived from that
93
93
 
94
94
  Owner execution is not OS-sandboxed by Machine Bridge. Use a dedicated low-privilege account, container, or VM for mutually untrusted workloads.
95
95
 
96
- ## Delegated process isolation
96
+ ## Remote process authority
97
97
 
98
- An `operator` process must pass a behaviorally verified OS-sandbox boundary. Restricting only cwd and environment is insufficient because an ordinary same-user process can otherwise read the user's home, Machine Bridge state, Keychain, and desktop session.
98
+ Remote `exec_command`, `run_process`, `run_local_command`, and process-session controls are owner-only. A workspace sandbox cannot prevent an arbitrary executable from reading credentials already present inside that workspace and sending them over the network. Delegated accounts use structured file and Git tools instead. The `agent` daemon profile remains a local capability ceiling and does not override this account-role restriction.
99
99
 
100
- The sandbox probe must demonstrate that the selected workspace is usable while protected roots remain unreadable. If the platform cannot demonstrate the negative boundary, delegated process execution fails closed.
101
-
102
- The existence of `sandbox-exec`, a container binary, or another sandbox command is not treated as proof of isolation.
100
+ The retained OS-sandbox implementation is defense in depth for internal restricted execution paths, not permission for delegated OAuth accounts to invoke arbitrary processes. Its probes must prove that the workspace is usable while protected roots remain unreadable; the existence of a sandbox executable alone proves nothing.
103
101
 
104
102
  ## Machine Bridge control plane
105
103
 
@@ -227,7 +225,7 @@ Managed jobs are durability, not sandboxing. Only `owner` may create remote pers
227
225
 
228
226
  Hosted managed-job recovery adds a separate Worker capability boundary. `start_job`, `stage_job`, and durable one-step process acceptance return deterministic HMAC-SHA256 `recovery_key` and `control_key` values bound to account version, OAuth client, refresh family, role, job ID, and purpose. Hosted `read_job` and dependency references require the read capability; hosted `cancel_job` requires the control capability. The Worker verifies them before daemon dispatch and strips them from daemon arguments. Capability values are derived with domain separation from the existing Worker OAuth identity key, are not persisted in local job state, are not mirrored into MCP parameter headers, and are covered by ordinary log/privacy redaction. Rotating the OAuth identity key invalidates outstanding hosted capabilities. Hosted `list_jobs` returns aggregate state only, while local CLI/stdio remains the global administration surface. This prevents Machine Bridge inventory from turning one hosted conversation into another conversation's job-discovery authority, but it cannot identify host-side conversation misrouting if the host itself supplies the other conversation's still-valid capability.
229
227
 
230
- Delegated `operator` accounts still cannot call `start_job` or `stage_job`, but remote `exec_command`, `run_process`, and `run_local_command` use internal `transient_process` managed-job carriers so an accepted one-step operation remains recoverable after a host boundary. Those carriers share the profile-wide 512-state job store. To keep the 24-hour hard undelivered-result promise from becoming a cross-principal capacity claim, one relay non-owner account version may hold at most 16 unresolved `transient_recovery_pending` carriers across all of its OAuth clients and refresh families. The fairness key is account ID plus account version; changing client or refresh-family identity does not reset it. The check runs inside the existing root `capacity.lock` before new durable status publication or runner launch and derives its count from persisted job truth rather than a second quota ledger. A securely readable valid persisted same-key job remains recoverable at quota because replay adds no reservation; deterministic-directory existence by itself is not replay, and a statusless partial publication must pass the account quota again. Present but unreadable, malformed, or integrity-invalid retained status fails closed. Already accepted pending results remain non-evictable for their full 24-hour grace, while hosted terminal delivery or terminal grace expiry releases the account quota. Owner/local work remains governed only by the existing global capacity contract. Quota errors expose only a bounded maximum and coarse capacity scope, not account/client/family/job identifiers, paths, command text, output, or recovery capabilities.
228
+ Remote process calls and managed-job creation are owner-only. The retained non-owner transient-carrier quota is defense in depth for previously accepted or internal restricted plans; it does not grant current delegated execution authority. Remote `exec_command`, `run_process`, and `run_local_command` use internal `transient_process` managed-job carriers so an accepted owner one-step operation remains recoverable after a host boundary. Those carriers share the profile-wide 512-state job store. To keep the 24-hour hard undelivered-result promise from becoming a cross-principal capacity claim, one relay non-owner account version may hold at most 16 unresolved `transient_recovery_pending` carriers across all of its OAuth clients and refresh families. The fairness key is account ID plus account version; changing client or refresh-family identity does not reset it. The check runs inside the existing root `capacity.lock` before new durable status publication or runner launch and derives its count from persisted job truth rather than a second quota ledger. A securely readable valid persisted same-key job remains recoverable at quota because replay adds no reservation; deterministic-directory existence by itself is not replay, and a statusless partial publication must pass the account quota again. Present but unreadable, malformed, or integrity-invalid retained status fails closed. Already accepted pending results remain non-evictable for their full 24-hour grace, while hosted terminal delivery or terminal grace expiry releases the account quota. Owner/local work remains governed only by the existing global capacity contract. Quota errors expose only a bounded maximum and coarse capacity scope, not account/client/family/job identifiers, paths, command text, output, or recovery capabilities.
231
229
 
232
230
  Job directories must remain canonical real children of the owner-only job root. Cancellation markers are atomically replaced owner-only timestamp files; unreadable, malformed, symlinked, or hard-linked markers fail closed instead of being treated as no cancellation.
233
231
 
@@ -1,6 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import { main } from "../src/local/cli.mjs";
3
- import { sanitizeLogText } from "../src/local/log.mjs";
3
+ import { createLogger, sanitizeLogText } from "../src/local/log.mjs";
4
+ import { installFatalProcessHandlers } from "../src/local/process-fatal.mjs";
5
+
6
+ installFatalProcessHandlers({
7
+ logger: createLogger({
8
+ component: "process-fatal",
9
+ level: "error",
10
+ format: process.env.MBM_LOG_FORMAT === "json" ? "json" : "text",
11
+ stderrOnly: true,
12
+ }),
13
+ });
4
14
 
5
15
  main().catch(error => {
6
16
  const message = process.env.MBM_DEBUG === "1"
@@ -29,6 +29,6 @@
29
29
  "action": {
30
30
  "default_title": "Machine Bridge Browser"
31
31
  },
32
- "version_name": "3.0.0-beta.201",
32
+ "version_name": "3.0.0-beta.205",
33
33
  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxryYkpZhq8+VAQLHcGS9BAHQcyKX8RHGIpIwvtIVRU/rcOcE0bNdnM0aZJ/h6xWQsGDHlhvjT2+1aJaAn/9k8473BRWajzVXld961CdHYVFVHoce2hHiSJ0xydWrHMMZhAm0mN0UzjEpgZ0tMw209efcZHIvSwuxhteZMRy4kyiVjwFlOf5oXFCxRuCJnPj3AK9CmCf4XgEBuPIJ0TZmjGHOOdBvJmbCNnAWXYEo5/mf7MfCGhV4IJ1hNuhpoNQfOFKMUcw9/v/IpT62XpfXdGYTfGYCmCjC+gntK1spbkr2P4/2+sYMQtLpse71mpSNGXfcf3abU55Vpn+gncSxRQIDAQAB"
34
34
  }
@@ -1,3 +1,4 @@
1
+ // Canonical Cloudflare deployment configuration for the `@cloudflare/workers-shared` / `cf` toolchain.
1
2
  import { bindings, defineConfig, exports as workerExports } from "cf/config";
2
3
 
3
4
  const name = process.env.MBM_WORKER_NAME || "machine-bridge-mcp";
package/docs/AUDIT.md CHANGED
@@ -12,13 +12,18 @@ This review is scoped to source contracts, risk-bearing control paths, isolated
12
12
 
13
13
  ## Current conclusions
14
14
 
15
- - **Output budgets include producer backing retention.** Both diagnostic and continuation buffers trim before allocating retained bytes and copy independent snapshots. Allocation/aliasing regressions and partition properties supplement the existing UTF-8 and continuation tests.
15
+ - **Delegated content paths are filtered before reads.** Search, project instructions, skills, and structured Git content omit sensitive paths; hard-linked text inputs are rejected. Empty Git path enumeration returns empty content without an unfiltered second command. Search reports omitted candidate files as incomplete and bounds surrounding text and serialized output. Filename classification cannot identify credentials stored under arbitrary ordinary filenames.
16
+ - **Arbitrary remote execution is owner-only.** Workspace isolation alone cannot prevent an executable from reading in-workspace credentials and exporting them. Local role gates and Worker discovery/dispatch enforce the same restriction. Fatal process events log only fixed event/error classes and terminate even when rejection inspection or logging throws; raw rejection content is not operational log data.
17
+ - **Refresh retries cannot recreate consumed replacements.** A retry may return only the still-active derived token pair. Revoked families and consumed replacements are rejected, and access-token authorization checks family revocation. Local regression fixtures do not replace deployed OAuth acceptance.
18
+ - **Branch and prerelease identities have different evidence.** Explicit branch requests match exact case-sensitive names despite pending version edits; explicit prerelease requests still reject contradictory package generations. Resolver regressions cover both paths.
19
+ - **Output budgets include producer backing retention.** Diagnostic and continuation buffers trim before allocating retained bytes and copy independent snapshots. Stdio response writes are serialized through an 8 MiB queue; input is paused as backlog rises, and exceeding the hard cap closes input rather than allowing unbounded queued responses. Allocation/aliasing regressions, backpressure integration, and partition properties supplement the existing UTF-8 and continuation tests.
16
20
  - **Successful settlement terminates retry classification.** Application stdout/stderr cannot cause a successful release command to run again. Failures retain bounded transient classification, while npm pre-lifecycle errors remain observable.
21
+ - **Workspace replacement retries remain bounded and atomic.** Transient sharing errors retry the staging-file rename without unlinking the visible destination. The expected content digest is rechecked before each attempt, so an external change after a sharing failure returns a conflict and preserves that generation. Exhausted and non-transient failures preserve the original error. Injected success/exhaustion/non-transient and retry-generation regressions supplement the concurrent-reader fixture; Windows CI remains the provider-level proof. This optimistic check does not provide an operating-system compare-and-swap against uncoordinated external writers.
17
22
 
18
23
  - **Authority remains an intersection, never an accumulation.** Effective MCP authority is bounded by authenticated account role, daemon capability ceiling, and tool-specific policy. Reconnects, retries, stale host schemas, browser focus changes, or recovery metadata do not expand authority.
19
- - **Removed protocol behavior stays removed.** Remote HTTP and stdio use the current MCP protocol only. Removed initialization, session, and replay behavior fails closed instead of silently falling back to historical compatibility.
24
+ - **Removed protocol behavior stays removed.** Remote HTTP and normal stdio use the current MCP protocol only. The sole exception is the opt-in stdio `--compat` handshake: it answers the removed `initialize`/`notifications/initialized` exchange with the supported version and creates no session or replay state. It supplies request metadata only when fields are absent; explicit retired/future versions and malformed metadata remain rejected, and the shim is never reachable from the remote relay.
20
25
  - **State publication is atomic, type-exact and identity-sensitive.** Security-sensitive state readers reject symlinks, unexpected hard links, malformed content, permission failures, persistent identity changes, and coercible PID/token/timestamp fields. Persisted strings, arrays, booleans or objects cannot become process, cleanup, lock, lease, waiter or termination authority through JavaScript conversion. Bounded retries are reserved for explicitly classified atomic-publication races; durable state is complete before it becomes visible.
21
- - **Durable execution owns continuity explicitly.** Managed jobs persist recovery state independently of the hosted MCP response. Idempotency keys bind uncertain acceptance retries only while the retained record exists; cancellation, dependency state, cleanup, output budgets, and terminal persistence have explicit fail-closed boundaries. Callers recover the same accepted job instead of replaying its side effect.
26
+ - **Durable execution owns continuity explicitly.** Managed jobs persist recovery state independently of the hosted MCP response. Idempotency keys bind uncertain acceptance retries only while the retained record exists; cancellation, dependency state, cleanup, output budgets, and terminal persistence have explicit fail-closed boundaries. Terminal evidence validation is bound to stable status/result file generations, and a live runner retains ownership of its final cleanup-status write. Routine inventory throttles full retention scans to 30 seconds, while capacity pressure, unreadable state, expired staged plans, and dependency-bearing active/staged jobs force maintenance. Callers recover the same accepted job instead of replaying its side effect.
22
27
  - **Daemon-owned Node children use a verified runtime launcher.** A live concrete runtime executable is preferred; if it disappears after a package-manager upgrade, only the original absolute Node launcher is eligible as fallback. Diagnostics expose provenance booleans rather than executable paths, and an unavailable launcher requires service restart instead of PATH guessing.
23
28
  - **Relay recovery separates transport, execution and quota pacing.** Authenticated WebSocket/HTTPS state is scoped to the current transport generation; ended-generation controls are discarded, and protocol violations affect their originating transport. Ambiguous side effects are not replayed. Cancellation removes ownership, terminal retention is bounded, and reconnects cannot accumulate execution time or delivery grace. Diagnostics retain sanitized classifications rather than peer text. The quota evidence and polling limits below distinguish repository mechanisms from provider usage.
24
29
  - **Operating-system sleep is an observable suspension boundary, not a network guarantee.** On supported macOS hosts, diagnostics correlate bounded sleep history with runtime stalls and recovered relay outages. Machine Bridge cannot keep JavaScript or a socket executing while the machine is suspended, and sleep correlation does not identify unrelated upstream network causes.
package/docs/CLIENTS.md CHANGED
@@ -43,7 +43,7 @@ It is therefore an optional compatibility and reuse surface, not a replacement f
43
43
 
44
44
  The MCP specification defines stdio and Streamable HTTP as standard transports. In stdio, the host launches the server as a subprocess and exchanges newline-delimited JSON-RPC through stdin/stdout. Streamable HTTP runs the server independently behind an HTTP endpoint.
45
45
 
46
- Machine Bridge uses MCP `2026-07-28` for both stdio and remote Streamable HTTP. Requests carry version and capabilities in `_meta`; `server/discover` replaces initialization, there is no MCP protocol session, and an HTTP response stream belongs to exactly one request. `initialize`, `Mcp-Session-Id`, `Last-Event-ID`, replay markers, and other explicit removed protocol-session markers receive bounded upgrade guidance and cannot dispatch tool work. Remote `/mcp` is POST-only, so GET returns 405 rather than acting as a recovery channel. Closing a current request stream cancels that request, and a connection, process, OAuth token, or stdio lifetime is never treated as conversation identity.
46
+ Machine Bridge uses MCP `2026-07-28` for both stdio and remote Streamable HTTP. Requests carry version and capabilities in `_meta`; `server/discover` replaces initialization, there is no MCP protocol session, and an HTTP response stream belongs to exactly one request. Under default protocol handling, `initialize`, `Mcp-Session-Id`, `Last-Event-ID`, replay markers, and other explicit removed protocol-session markers receive bounded upgrade guidance and cannot dispatch tool work; the opt-in stdio `--compat` shim is the only exception for the initialization handshake. Remote `/mcp` is POST-only, so GET returns 405 rather than acting as a recovery channel. Closing a current request stream cancels that request, and a connection, process, OAuth token, or stdio lifetime is never treated as conversation identity.
47
47
 
48
48
  ## Automatic capability selection
49
49
 
@@ -73,6 +73,10 @@ machine-mcp client-config --client all --workspace /path/to/project --profile ed
73
73
  machine-mcp client-config --client all --workspace /path/to/project --profile review
74
74
  ```
75
75
 
76
+ ## Current protocol requirements
77
+
78
+ Use a client that sends the current protocol version and client capabilities in request metadata on every supported request. The default stdio path and remote HTTP reject `initialize` and missing or unsupported request metadata. A narrow, opt-in stdio `--compat` shim answers `initialize`/`notifications/initialized` for hosts that require the handshake and fills metadata fields only when they are absent. It does not support older protocol versions: explicit retired, future, or malformed metadata is still rejected. The environment variable `MBM_MCP_COMPAT=1` enables the same stdio-only shim unless an explicit CLI value overrides it.
79
+
76
80
  ## JSON stdio configuration
77
81
 
78
82
  Claude Desktop, Cursor, and many generic clients use a shape similar to:
@@ -22,7 +22,7 @@ Local stdio does not use remote OAuth accounts. It runs as the local owner under
22
22
  |---|---|---|
23
23
  | `reviewer` | Read-only inspection of the selected workspace | No mutation or process execution |
24
24
  | `editor` | Workspace reads and deterministic file mutation | No process execution |
25
- | `operator` | Workspace-confined editing and direct process execution | No unrestricted paths, credentials, browser/desktop control, or persistent job creation |
25
+ | `operator` | Workspace-confined editing and read-only inspection | No process execution, unrestricted paths, credentials, browser/desktop control, or persistent job creation |
26
26
  | `owner` | Complete bridge authority within the daemon policy ceiling | Generic path-based tools cannot target Machine Bridge control-plane state; owner shell remains OS-user authority |
27
27
 
28
28
  The package catalog defines the stable discovery surface. The Worker filters `tools/list` by account role without rewriting it during a brief daemon outage. The live daemon advertisement remains the execution ceiling, and the local runtime independently recomputes and validates the role and policy boundary before dispatch.
@@ -62,7 +62,7 @@ Examples:
62
62
 
63
63
  - a reviewer may inspect files inside the selected workspace;
64
64
  - an editor may update ordinary workspace files;
65
- - an operator may run a workspace-confined process only when the delegated process sandbox is behaviorally verified;
65
+ - an operator may edit ordinary workspace files but cannot execute arbitrary programs remotely;
66
66
  - an owner may use shell, unrestricted paths, browser/application automation, resources, and managed jobs when enabled by the daemon policy.
67
67
 
68
68
  Risk classification still runs for every consequential request. It supplies structured audit metadata and enforces hard boundaries; it is not a mechanism for temporary privilege escalation.
@@ -91,20 +91,13 @@ Only `owner` may create persistent execution plans with `start_job` or non-execu
91
91
 
92
92
  `stage_job` does not execute and is not an approval workflow. The removed `machine-mcp job approve` path cannot turn a draft into a running job. Execution requires a trusted owner request through `start_job`, or an explicit local `job submit` operation performed by the machine operator.
93
93
 
94
- ## Delegated process isolation
94
+ ## Remote process execution
95
95
 
96
- An `operator` process is not accepted merely because its current directory and environment are restricted. Machine Bridge requires a behaviorally verified OS sandbox that:
96
+ Remote arbitrary process execution (`exec_command`, `run_process`, `start_process`, registered process commands, and process-session controls) is owner-only. The OS sandbox confines an operator's filesystem to the workspace, but the workspace may itself contain credentials; allowing arbitrary executables would let them read those files and send their contents over an allowed network connection. A working-directory restriction, minimal environment, or `shell: false` does not close that boundary.
97
97
 
98
- - exposes the selected workspace and an isolated runtime directory;
99
- - blocks the real user home and Machine Bridge state;
100
- - blocks Keychain and desktop automation access;
101
- - preserves the minimum system runtime needed by ordinary tools.
98
+ Use the structured file and Git tools for delegated inspection and editing. If a workflow needs arbitrary execution under a non-owner identity, run it in a separate OS account, container, or VM with an independently defined credential boundary.
102
99
 
103
- The probe is fail-closed. The presence of a sandbox executable is not sufficient.
104
-
105
- On platforms where the negative security boundary cannot be verified, delegated process execution is unavailable. Owner execution remains governed by the selected daemon policy. For mutually untrusted workloads, use a separate OS account, container, or VM.
106
-
107
- Implementation-owned metadata probes are a separate boundary from delegated arbitrary execution. `project_overview` and the read-only Git tools use fixed argv selected by Machine Bridge, never a caller-provided executable or shell string. Those probes run with a minimal isolated environment, bounded output and deadlines, cancellation/process-tree tracking, and the request’s path-visibility rules. They do not grant `run_process`, registered-command, or shell authority to reviewer/editor accounts.
100
+ Implementation-owned metadata probes are a separate boundary from delegated arbitrary execution. `project_overview` and the read-only Git tools use fixed argv selected by Machine Bridge, never a caller-provided executable or shell string. Those probes run with a minimal isolated environment, bounded output and deadlines, cancellation/process-tree tracking, and the request’s path-visibility rules. They do not grant `run_process`, registered-command, or shell authority to any non-owner account.
108
101
 
109
102
  ## Object ownership
110
103
 
@@ -152,3 +145,7 @@ For incident response:
152
145
  6. restart and reconnect only trusted clients.
153
146
 
154
147
  Version 3 has no capability-lease command or runtime surface and never creates pending approval IDs. Persisted state from unsupported older schemas is preserved and rejected rather than interpreted as current authorization state.
148
+
149
+ ## Machine-service control root and recursive traversal
150
+
151
+ Relay-originated path operations treat the machine-service control root as protected alongside profile security state and browser state. Direct access is denied, and recursive search and file listing apply the same protected-root check to each candidate rather than relying only on the requested root. Filtered results expose `skipped_files` and `truncated` so omitted content is not mistaken for no matches. This is a structured-tool boundary, not an operating-system sandbox.
package/docs/LOGGING.md CHANGED
@@ -32,6 +32,8 @@ Structured-field sanitizers use null-prototype intermediate maps, so prototype-s
32
32
 
33
33
  Top-level CLI failures pass through the shared free-form sanitizer before stderr output in both default and debug modes. The developer-only `MBM_DEBUG=1` may include a bounded exception stack; credential-pattern, home-path, control-character, and message-length protections still apply.
34
34
 
35
+ Tool error results have a separate boundary. `publicError()` redacts non-exposed messages by default, and a verbose projection is available only as an explicit per-call option at a local boundary. The stdio server enables it for the current process when `MBM_VERBOSE_ERRORS=1`; the remote relay never enables it, and `MBM_DEBUG` does not affect tool results. Verbose messages and their causes pass through the same sanitizer and share the single 2000-character ceiling of the public message field, so credential patterns, home paths, control characters, and message length stay bounded, and a debug copy never disagrees with the message it copies.
36
+
35
37
  The detached managed-job runner uses a stricter boundary for unexpected fatal failures: its operational stderr records only a fixed error class, never the exception message or user-controlled work content. This applies from process entry, including argument validation and the initial bounded status read before a runner claim is confirmed; an early filesystem failure must not expose a state path, system-error text, or stack. Details needed for recovery remain in the separate authority-checked job status/result surfaces.
36
38
 
37
39
  Human mode treats the message as the primary interface: it uses a natural-language explanation and includes only bounded diagnostic fields that add meaning. It does not repeat the machine event key. JSON mode retains the stable `event` field for ingestion and correlation. Routine `info`/`warn`/`error` events do not carry raw process IDs or managed-job IDs; exact ownership identity remains available through explicit status/diagnostic/job surfaces where it is the requested result. Event identifiers such as `relay.tool_result.discarded` are implementation contracts for structured logs, not text that should be shown as the warning itself.
@@ -14,7 +14,7 @@ Use separate OS accounts, containers, VMs, state roots, Workers, and workspaces
14
14
  |---|---|---|
15
15
  | `reviewer` | `review` | Read-only selected-workspace inspection |
16
16
  | `editor` | `edit` | Reviewer access plus deterministic workspace file mutation |
17
- | `operator` | `agent` | Editor access plus behaviorally sandboxed workspace-confined direct execution |
17
+ | `operator` | `agent` | Editor access plus read-only application inventory; arbitrary process execution is owner-only |
18
18
  | `owner` | `full` | Complete bridge authority within the daemon capability ceiling |
19
19
 
20
20
  Effective authority is the intersection of:
@@ -130,7 +130,9 @@ For delegated (non-owner) principals, a different account, client, or token fami
130
130
 
131
131
  Hosted managed-job recovery adds a stricter Worker boundary even for owner accounts: detailed `list_jobs` handles are not remotely enumerable, and `read_job`, `cancel_job`, and `depends_on` require purpose-scoped capabilities bound to the accepting account version, OAuth client, refresh family, role, and job. This prevents Machine Bridge's own global owner inventory from becoming cross-conversation recovery authority. It does not claim to distinguish two host conversations if the host itself incorrectly forwards the other conversation's valid capability.
132
132
 
133
- Explicit persistent plan creation (`stage_job` / `start_job`) remains owner-only. Delegated `operator` process tools nevertheless use internal durable `transient_process` carriers so accepted one-step work can be recovered without granting plan authority. All accounts share the same profile job root and its global 512-state ceiling, so relay non-owner pending recovery is additionally bounded to 16 unresolved carriers per account ID plus account version. The account-version key deliberately spans OAuth clients and refresh families: one account may authorize several clients, and changing either client or family cannot reset the quota. Object read/control authority remains more narrowly bound to the original account/client/family capability. The account quota is checked under the existing root capacity lock from persisted job state before a genuinely new carrier publishes status or launches; it has no separate mutable ledger. A securely persisted valid same-key replay is still allowed at quota because it creates no new reservation. A deterministic directory with no persisted status is an incomplete transaction, not replay and not an account reservation; its retry must pass quota again. Hosted terminal delivery clears the pending marker and releases the account slot, as does terminal expiry beyond the existing 24-hour hard recovery grace. Owner/local submissions remain outside this delegated-account quota.
133
+ Persistent plan creation (`stage_job` / `start_job`) and all arbitrary process/session tools are owner-only. Non-owner accounts cannot create a process carrier through a direct executable, shell, registered command, or process-session API. Local stdio and explicit local CLI operations remain separate local-owner entry points. The shared job store still applies its global retained-state cap and principal-bound recovery rules to accepted owner jobs; hosted recovery capabilities remain bound to the accepting account version, OAuth client, refresh family, and role.
134
+
135
+ Pending transient-recovery capacity remains a defense-in-depth invariant for retained or internally generated delegated carriers: it is capped at 16 unresolved carriers per account ID plus account version, across OAuth clients and refresh families, and changing either client or family cannot reset the quota. A securely persisted same-key replay does not reserve another slot. A deterministic directory with no persisted status is an incomplete transaction, not replay, so its retry must pass the account quota again. This capacity guard remains useful for safe reconciliation of carriers accepted by older daemon versions while the public role boundary now denies new delegated process calls.
134
136
 
135
137
  ## Administrative boundary
136
138
 
@@ -144,11 +146,9 @@ The first start of a new deployment creates an owner account automatically and p
144
146
 
145
147
  ## Delegated execution
146
148
 
147
- `operator` direct execution requires a behaviorally verified OS sandbox. The sandbox must expose the selected workspace while denying the real user home, Machine Bridge state, Keychain, and desktop automation.
148
-
149
- When the platform cannot prove that boundary, operator process execution is unavailable. The runtime does not fall back to a path blacklist that only appears isolated.
149
+ All remote arbitrary process execution is owner-only, including `run_process`, `exec_command`, registered commands, process sessions, and process-session controls. A workspace sandbox limits filesystem reach but cannot make arbitrary code safe when the workspace itself may contain credentials; a process can read those credentials and send them through its network access. A minimal environment and `shell: false` do not prevent this.
150
150
 
151
- Installed-application inventory is the deliberate read-only exception: reviewer/editor/operator accounts may use `list_local_applications`, with external paths projected rather than exposed absolutely. Browser/application content inspection or control, local data export, credential operations, persistent job creation, machine-wide runtime diagnostics, protected local-resource inventory, sensitive targets, and unrestricted paths remain owner-only. In the public remote catalog this additionally means `diagnose_runtime`, `list_local_resources`, `stage_job`, and `start_job` are not discoverable or callable by reviewer/editor/operator accounts even where the underlying local daemon profile would otherwise admit them.
151
+ Reviewer, editor, and operator accounts use structured file and Git operations for delegated work. Installed-application inventory remains a read-only exception: all three non-owner roles may use `list_local_applications`, with external paths projected rather than exposed absolutely. Browser/application content inspection or control, local data export, credential operations, persistent job creation, machine-wide runtime diagnostics, protected local-resource inventory, sensitive targets, unrestricted paths, and all process execution remain owner-only. The public remote catalog therefore hides and rejects `diagnose_runtime`, `list_local_resources`, all process/session tools, `stage_job`, and `start_job` for non-owner accounts even where the underlying local daemon profile would otherwise admit them.
152
152
 
153
153
  ## Concurrency and revocation
154
154
 
@@ -183,6 +183,6 @@ Do not place unrelated machines or mutually untrusted teams behind one broad own
183
183
 
184
184
  ## Security limits
185
185
 
186
- A reviewer is restricted by Machine Bridge, but a bug or compromised dependency remains possible. An operator can execute interpreters and repository code inside the verified sandbox and can still damage the selected workspace. An owner has effectively the authority of the local OS user and granted browser or Accessibility permissions.
186
+ A reviewer, editor, or operator is restricted by Machine Bridge, but a bug or compromised dependency remains possible. Non-owner roles cannot request arbitrary remote process execution; they can still inspect or mutate the workspace according to their role. An owner has effectively the authority of the local OS user and granted browser or Accessibility permissions.
187
187
 
188
188
  Roles, client binding, DPoP, object ownership, and targeted revocation are defense in depth. They do not replace least-privilege OS design, endpoint security, Cloudflare account protection, and careful review of untrusted repositories and instructions.
@@ -208,6 +208,8 @@ After global installation, Windows users may open any `cmd.exe` window and run `
208
208
 
209
209
  `service restart` uses the same owner/readiness convergence after its detached service-manager handoff, but unlike idempotent `service start` it must invoke the provider. When the service was already active, success requires both explicit provider restart evidence and a ready replacement daemon PID; the old daemon remaining ready is `daemon_replacement_not_observed`, not success. Windows restart remains fail closed from inside the running task because Task Scheduler `/End` may terminate the helper with the daemon; use an independent terminal stop/start sequence until a behaviorally verified Windows handoff exists.
210
210
 
211
+ Unexpected uncaught exceptions and unhandled promise rejections are logged through the shared redaction boundary and terminate the daemon with a non-zero exit code. The daemon does not continue operating after an unhandled programming failure. The platform supervisor then applies crash-loop throttling: launchd uses a ten-second throttle interval, systemd allows five starts per sixty seconds with a five-second restart delay, and the Windows launcher backs off through 5, 10, 20, 40, then 60 seconds. If systemd exhausts its start limit, inspect the daemon error log before using `systemctl --user reset-failed machine-bridge-mcp.service`; resetting the limit without fixing the startup failure can restart the same crash loop.
212
+
211
213
  A workspace/state selector does not grant authority over the machine-global service label. All service mutations share one fixed per-user machine-service lock. Operations that also need a workspace startup lock acquire machine-service first; foreground startup releases the machine lock after service takeover and daemon-lock acquisition rather than holding it for the lifetime of the foreground runtime. Stop, restart, foreground takeover, secret rotation, and uninstall still require exact live ownership evidence. Service status returns only provider state, bounded owner metadata, verified daemon state, PID/run counters, readiness, and classified termination state; provider environment dumps and owner paths are never returned.
212
214
 
213
215
  ### Candidate activation authentication recovery
@@ -88,7 +88,7 @@ This table describes the local daemon policy ceiling. Remote account roles apply
88
88
 
89
89
  ## Remote account-role tool access
90
90
 
91
- Account-access revision: **4**. Default role: **reviewer**. Remote effective authority is the intersection of this account-role ceiling with the connected daemon policy/tool ceiling; the MCP host may expose a further subset.
91
+ Account-access revision: **5**. Default role: **reviewer**. Remote effective authority is the intersection of this account-role ceiling with the connected daemon policy/tool ceiling; the MCP host may expose a further subset.
92
92
 
93
93
  | Tool | reviewer | editor | operator | owner |
94
94
  |---|---|---|---|---|
@@ -117,7 +117,7 @@ Account-access revision: **4**. Default role: **reviewer**. Remote effective aut
117
117
  | `git_show` | yes | yes | yes | yes |
118
118
  | `git_status` | yes | yes | yes | yes |
119
119
  | `inspect_local_application` | no | no | no | yes |
120
- | `kill_process` | no | no | yes | yes |
120
+ | `kill_process` | no | no | no | yes |
121
121
  | `list_dir` | yes | yes | yes | yes |
122
122
  | `list_files` | yes | yes | yes | yes |
123
123
  | `list_jobs` | yes | yes | yes | yes |
@@ -133,21 +133,21 @@ Account-access revision: **4**. Default role: **reviewer**. Remote effective aut
133
133
  | `project_overview` | yes | yes | yes | yes |
134
134
  | `read_file` | yes | yes | yes | yes |
135
135
  | `read_job` | yes | yes | yes | yes |
136
- | `read_process` | no | no | yes | yes |
136
+ | `read_process` | no | no | no | yes |
137
137
  | `resolve_task_capabilities` | yes | yes | yes | yes |
138
- | `run_local_command` | no | no | yes | yes |
139
- | `run_process` | no | no | yes | yes |
138
+ | `run_local_command` | no | no | no | yes |
139
+ | `run_process` | no | no | no | yes |
140
140
  | `search_text` | yes | yes | yes | yes |
141
141
  | `server_info` | yes | yes | yes | yes |
142
142
  | `session_bootstrap` | yes | yes | yes | yes |
143
143
  | `stage_job` | no | no | no | yes |
144
144
  | `start_job` | no | no | no | yes |
145
- | `start_process` | no | no | yes | yes |
145
+ | `start_process` | no | no | no | yes |
146
146
  | `view_image` | yes | yes | yes | yes |
147
147
  | `write_file` | no | yes | yes | yes |
148
- | `write_process` | no | no | yes | yes |
148
+ | `write_process` | no | no | no | yes |
149
149
 
150
- Owner-only remote tools: `diagnose_runtime`, `list_local_resources`, `stage_job`, `start_job`. Their local availability class is unchanged; the extra restriction applies only to authenticated remote account roles.
150
+ Owner-only remote tools: `diagnose_runtime`, `exec_command`, `kill_process`, `list_local_resources`, `read_process`, `run_local_command`, `run_process`, `stage_job`, `start_job`, `start_process`, `write_process`. Their local availability class is unchanged; the extra restriction applies only to authenticated remote account roles.
151
151
 
152
152
  ## Enforcement contract
153
153
 
@@ -74,7 +74,7 @@ The host, model output, repository instructions, and retrieved content may be ma
74
74
 
75
75
  The runtime relies on OS-user identity, filesystem permissions, process controls, macOS TCC/SIP, Windows ACLs, endpoint controls, and any VM/container boundary.
76
76
 
77
- For delegated process execution, Machine Bridge requires a behaviorally verified OS sandbox. If the negative boundary cannot be demonstrated, delegated execution fails closed. Owner execution is not sandboxed by Machine Bridge. Fixed implementation-owned Git operations are not caller-selected process authority: they use code-constructed argv, no shell, literal pathspecs, an isolated minimal environment, bounded deadlines/output, and ordinary cancellation/process tracking. Fixed UI launch/JXA/native-input helpers likewise use code-constructed argv rather than caller-selected script source. For those mutation-capable helpers a failure before process start remains definite; once process start is established, timeout, cancellation, process error, or lost settlement is non-retryable unknown evidence because the UI mutation may already have happened. Before a restricted principal reaches Git, filesystem-first discovery checks metadata roots and recursive alternate stores and rejects symbolic-link/special-file descendants in the metadata trees; repository configuration that can execute helpers, redirect external files, or enable lazy object fetching is rejected. This protects the authenticated principal boundary but is not a hostile same-UID filesystem transaction: another local process with the owner's OS authority can still race metadata after inspection.
77
+ Arbitrary remote process execution and process-session controls are owner-only. A workspace sandbox cannot protect credentials inside the permitted workspace from arbitrary code or network export. Retained restricted-process sandbox probes remain defense in depth and must prove their negative boundary; they do not grant delegated OAuth execution authority. Owner execution is not sandboxed by Machine Bridge. Fixed implementation-owned Git operations are not caller-selected process authority: they use code-constructed argv, no shell, literal pathspecs, an isolated minimal environment, bounded deadlines/output, and ordinary cancellation/process tracking. Fixed UI launch/JXA/native-input helpers likewise use code-constructed argv rather than caller-selected script source. For those mutation-capable helpers a failure before process start remains definite; once process start is established, timeout, cancellation, process error, or lost settlement is non-retryable unknown evidence because the UI mutation may already have happened. Before a restricted principal reaches Git, filesystem-first discovery checks metadata roots and recursive alternate stores and rejects symbolic-link/special-file descendants in the metadata trees; repository configuration that can execute helpers, redirect external files, or enable lazy object fetching is rejected. This protects the authenticated principal boundary but is not a hostile same-UID filesystem transaction: another local process with the owner's OS authority can still race metadata after inspection.
78
78
 
79
79
  ### Local runtime to browser extension
80
80
 
@@ -135,7 +135,7 @@ The implementation aims to preserve these invariants:
135
135
  - long-lived runtime objects are bound to account, account version, OAuth client, and refresh family;
136
136
  - generic path-based remote tools cannot target Machine Bridge control-plane state;
137
137
  - sensitive paths, persistence targets, browser/desktop control, data export, and persistent job creation are owner-only;
138
- - delegated process execution is accepted only when an OS sandbox is behaviorally verified;
138
+ - arbitrary process execution and process-session controls are rejected for delegated OAuth accounts before dispatch;
139
139
  - direct argv execution is used unless the explicit shell tool is authorized;
140
140
  - confined paths are canonicalized and symbolic-link write escape is rejected;
141
141
  - request bodies, files, messages, output, logs, state, retained results, concurrency, and error-cause traversal are bounded; byte limits stop further source consumption rather than merely truncating retained data;