Skip to content

feat: hide Computer Use and Browser Use with a patched managed runtime (ADR 19) - #49

Merged
supermomonga merged 2 commits into
mainfrom
test/provider-zcode-computer-use
Oct 9, 2026
Merged

supermomonga merged 2 commits into
mainfrom
test/provider-zcode-computer-use

Conversation

@supermomonga

Copy link
Copy Markdown
Owner

Problem

ZCode Desktop installs official plugins into ~/.zcode/cli/plugins. The provider shares that storage, so provider sessions offer the computer-use, control-browser and web-gui-tester skills and the mcp__node_repl__js tool to the model. Neither capability can work in the provider's standalone Server:

  • Computer Use: Desktop's node_repl SDK launches the installed ZCode Computer Use.app. The Helper refuses with --launcher-pid did not verify as a code-signed ZCode process, and the call times out after 60 s. The public source also ships @zcode/zcode-cua only as a placeholder.
  • Browser Use: only the Desktop host supplies browserControlExecutor, so the Server always answers browsers: [].

Two official switches stop execution: ZCODE_CUA_PRODUCT_HELPER=0 and a per-turn toolDisallowlist. Nothing official can hide the skills per process:

  • app-server takes no config arguments, and env config covers only storage, network, logging and concurrency.
  • The ZCODE_CUA_PRODUCT_HELPER suppression set in resolveOfficialPluginRoots is built but never used.
  • A separate ZCODE_STORAGE_DIR drops every Desktop-bundled plugin. They cannot be reinstalled because they are not public or in the CDN marketplace.
  • ZCode does not accept issues.

Decision

ADR 19 amends ADR 15. It allows minimal build-time patches to the managed runtime under these conditions:

  • Each patch is a plain unified diff against the pinned TypeScript source, applied with git apply without fuzz.
  • A patch may only hide capabilities that the provider cannot support. Model requests, auth, storage, protocol and endpoints stay untouched.
  • Each patch documents its purpose, target and removal condition, under Apache-2.0.

Changes

  • Patch. patches/zcode/0001-hide-suppressed-official-plugins.patch (+8/−1 in NodePluginAdapter.discoverPluginsSync) skips the official plugin IDs listed in PASEO_ZCODE_SUPPRESSED_PLUGINS. It reuses the existing suppressedBuiltins check and writes no configuration, so Desktop is unaffected. With both plugins skipped, ZCode does not register node_repl either.
  • Build and release.
    • scripts/apply-zcode-patches.mjs checks all patches before applying any and refuses a dirty checkout. At packaging time it verifies that only the patches modify the source. npm run check:zcode-patches runs it read-only, and CI runs that on the pinned source.
    • The release workflow applies the patches before the official build. The archive ships patches/ and records them with their SHA-256 in BUILD-INFO.json (modified: true).
    • Tags and assets are named zcode-runtime-v<version>-paseo.<n>. The existing zcode-runtime-v3.14.3 release stays unmodified.
  • Provider. server/unsupported-capabilities.ts holds both settings below. Both also cover unpatched PASEO_ZCODE_RUNTIME runtimes.
    • The bridge always starts the Server with ZCODE_CUA_PRODUCT_HELPER=0 and the suppressed plugin list. Callers cannot override them.
    • Every input carries toolDisallowlist: ["mcp__node_repl__js"].
  • Pins. pins.ts now builds the URL from a release name. It still pins the unmodified 3.14.3 archive until the patched one is published.
  • Docs. AGENTS.md, the development guide (new "Runtime patches" section), README, NOTICE, docs/todo.md and docs/verification.md are updated.

Verification (macOS arm64)

  • Checks: typecheck, test (22 files, 201 tests), build, format:check and adrs doctor pass. The doctor reports only the existing warning on ADR 1.
  • Patch: npm run check:zcode-patches passes against 29628c9.
  • test:stdio-runtime on the unmodified managed 3.14.3: all existing checks pass. Also, mcp__node_repl__js is absent from the model request, and the Computer Use and Browser Use fixtures stay visible.
  • test:stdio-runtime on a local stand-in for the patched runtime: this is a copy of 3.14.3 with the same line replaced in agent/zcode.cjs and the patch recorded in BUILD-INFO.json. All checks pass, both fixtures are hidden from discovery and from the model's skill list, and the control fixture stays visible.
  • Same stand-in on real Desktop data, read-only RPCs:
    • computer-use, control-browser and web-gui-tester disappear from the skill catalog. Docs/PDF/slides/sheets, zcode-guide, skill-creator, plugin-creator, video2code and user skills remain.
    • computer-use is listed only as source: "missing", because Desktop's enabledPlugins names it.

Not verified yet

  • The patched build itself. This PR runs the runtime release workflow, which builds it and verifies it on all five platforms without publishing.
  • A real-model check on the published runtime: the model-io tool and skill lists, and node_repl not being registered.
  • The video2code skills url2video and video2fullstack assume Browser Use and remain listed.

After merge

  1. Push zcode-runtime-v3.14.3-paseo.1 to publish the patched runtime.
  2. Pin its SHA-256 and size in server/runtime/pins.ts. The same change updates the README runtime line and the Runtime tab hint, which still describe the unmodified 3.14.3.
  3. Record the real-model verification.

ZCode's official computer-use plugin is visible to provider sessions,
because the provider shares ~/.zcode with ZCode Desktop, but it cannot
work there:

- The public source ships @zcode/zcode-cua as a placeholder, so the
  managed runtime never starts a Computer Use Helper.
- Desktop's node_repl SDK launches the installed Helper, which refuses
  the launcher because it is not a code-signed ZCode process. The first
  real call times out after 60 seconds.

Record the evidence and the investigated ways to disable it. Two
official switches stop execution: ZCODE_CUA_PRODUCT_HELPER=0 on the
Server and a per-turn toolDisallowlist. Neither can hide the skills.
Computer Use and Browser Use cannot run in the provider's standalone
ZCode Server. The CUA Helper accepts only the signed Desktop app, and
only the Desktop host supplies browsers. The skills that Desktop
installed into the shared ~/.zcode were still offered to the model, and
no official switch can hide them per process. ADR 19 (amends ADR 15)
therefore allows minimal build-time patches to the managed runtime.

- patches/zcode/0001-hide-suppressed-official-plugins.patch makes
  plugin discovery skip official plugin IDs listed in
  PASEO_ZCODE_SUPPRESSED_PLUGINS, reusing the existing suppressedBuiltins
  check. Nothing is written back to configuration, so Desktop is
  unaffected.
- scripts/apply-zcode-patches.mjs checks every patch before applying
  any, refuses a dirty checkout and, at packaging time, verifies that
  only the patches modify the source. CI checks that they apply to the
  pinned source.
- The release workflow applies the patches before the official build.
  The archive ships the patches and records them with their SHA-256 in
  BUILD-INFO.json (modified: true). Releases are named
  zcode-runtime-v<version>-paseo.<n>. pins.ts still pins the unmodified
  3.14.3 release until the patched one is published.
- The bridge always starts the Server with ZCODE_CUA_PRODUCT_HELPER=0
  and the suppressed plugin list. Every input hides mcp__node_repl__js
  through toolDisallowlist. Both stay for unpatched PASEO_ZCODE_RUNTIME
  runtimes.
- test:stdio-runtime places Computer Use, Browser Use and a control
  plugin in the isolated plugin cache. On a runtime that lists the patch
  in BUILD-INFO.json, it requires the first two to be hidden from
  discovery and the model; on an unpatched runtime, it requires them to
  stay visible. The shared tool must be hidden on both.

Update AGENTS.md, the development guide, README, NOTICE, the remaining
work list and the verification record for the new policy.
@supermomonga
supermomonga merged commit 65d550f into main Oct 9, 2026
14 checks passed
@supermomonga
supermomonga deleted the test/provider-zcode-computer-use branch October 9, 2026 06:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant