Repository navigation
refactor(host): read every configuration value from an explicit host (#3794) - #3798
Conversation
Size Report
Startup median (7 runs, lower is better):
|
|
Reviewed 7c10533. The refactor looks sound, but the macOS helper route has no live run, and typecheck fails against current main. Typecheck fails with TS2741 because of a real semantic conflict. This PR makes The macOS helper and native-app routes changed, but the PR's live run covers only the iOS simulator runner route. The env is now threaded into runMacOsHelper, the ghost-cursor and helper-path overrides, and the native-app backend choice. That choice now reads Not blocking, and you can take or leave these: (1) the Apple runner host slot (runner-host.ts:78) feeds about 20 runner config reads, yet every test binds it to the live env or Could the env be bound when the local Linux and Apple tool providers are built (for example I did not review every Linux, Vega and web leaf for a missed host thread, though the required parameter types turn a miss into a compile error. Some ambient Before merge, please rebase onto 11de319 and pass |
7c10533 to
17ac24f
Compare
|
All items from the 12:41Z review applied. Rebased onto Blocking
Contract (0.21.x additive)
Simplify
Tests and hygiene
Also noted
Gate: |
17ac24f to
0968cb7
Compare
|
Coverage failure on The job was not a coverage gap: the
Live macOS evidence and the item-by-item replies above are unchanged by this push (the diff only reverts MCP test-file stubs). |
|
One remaining issue at P1 — Linux host isolation: Please bind display configuration to the runtime host/provider at construction and scope the input-tool cache to that owner (or remove the cache if it is unnecessary). Reuse one display detector for input, clipboard and screenshot selection. Keep env out of individual port methods. Add an A(X11) → B(Wayland) → A test with independent explicit hosts and an opposing process env, without cache resets between calls. The gate in #3753 must not exempt these configuration reads as command execution. This corrects the coordinator's earlier ruling; the PR's macOS evidence and exact-head validation receipt remain useful. I have inspected this path read-only and have not run a Linux device session. |
|
Reviewed 0968cb7. Two Linux and Vega configuration reads still depend on process-wide stored state, so the host is not the only source of configuration yet. The CI checks are green: 17 checks, 0 failing at 0968cb7. The earlier Coverage failure (the test-file-size limit on command-tools.test.ts) is fixed by the MCP stub revert. Before merge, the Linux and Vega tool providers need to be bound to their host. The first problem is in linux-env.ts. The Linux plugin's createInteractor drops the host it receives (register-builtins.ts:35). The second problem is the same rule in the Vega tool provider. Not blocking, and you can take or leave these: the "scoped ? resolveWebProvider() : createAgentBrowserWebProvider({host})" rule appears three times (platform-web interactor.ts:20, network-web-transport.ts:14 and audio-probe-host.ts:68), so one Could the host the plugin port already delivers be enough here? If On evidence: the live macOS run was on 17ac24f, which I could not find locally, so I did not confirm that the range to 0968cb7 touches only MCP test files. The native-backend live run starts the daemon with its own process env, so it cannot tell the runtime host from the process env. The unit daemon-composition test carries that proof, and I did not re-run it. I did not run a two-runtime Linux or Vega session; both findings come from reading the code, and the memo key and singleton resolution are confirmed by grep. The macOS evidence the PR needs is in place. No conflicts are known. |
|
Coordinator note for the #3794 owner. The 16:35Z review is only partly covered by the local round I see (
When done, post one comment that maps each item to its commit. |
0968cb7 to
613e66b
Compare
|
Linux host-isolation P1 from the coordinator review fixed and pushed as What changed:
Validation: |
613e66b to
5b1d1a5
Compare
|
Round 3 — the 16:35Z review items and the four remaining items from the 17:23Z note, each mapped to its commit at head 1. Linux input-tool memo on the provider instance; reset helper dropped — 2. Vega host bound at the plugin route — 3. One web provider policy — resolver added in 4. PR body + commit titles — body rewritten at this push. Boundary reads are now exactly the two Two dead-code removals the fallow gate flagged on this round's diff: the Evidence notes: on the live-run observation — agreed, the native-backend refusal run starts the daemon from its own process env, so it cannot separate runtime host from process env there; the composed-route proof stays the
|
5b1d1a5 to
22ce597
Compare
|
Coverage failure on The Coverage gate flagged |
|
The earlier findings from 0968cb7 are mostly fixed at 22ce597, but two things remain before merge. The Vega executable lookup now gives different answers inside one runtime, and the plugin binding added this round has no test. The adapter's default-install lookup in tool-provider.ts now uses The fix for the earlier second finding binds the host-bound provider in Not blocking, and you can take or leave these: CI is green with 17 checks and none failing at 22ce597, and the Linux Smoke workflow covers the reworked X11 interactor route. There are no conflicts. I ran no tests and did not run a two-HOME Vega session; the first finding comes from reading the inventory, doctor and adapter code at this commit. No Wayland or Vega device lane exists in CI, so those routes are proven only by unit tests. I also did not check whether production embeddings ever set HOME apart from the process, which the divergence needs. Before merge, please route Vega inventory, doctor and the interactor adapter through one host-derived resolver and add the two-host |
22ce597 to
4a6c731
Compare
|
Round 4 — the 22:39Z review, each item mapped to its commit at head 1. BLOCKING — one Vega executable resolver — resolver + call sites in 2. BLOCKING — test the plugin binding — 3. Recommended (all applied) — Linux items in
Commit titles stayed accurate: the contracts commit is retitled Validation: |
|
The Vega fix from the earlier review (22ce597) is in at 4a6c731, but it has no test that fails without it. Please add one before merge. Reverting All 17 checks pass at 4a6c731, and Linux Smoke covers the reworked X11 interactor route. No Vega or Wayland lane exists, so those routes are proven only by unit tests. There are no conflicts. I ran no tests, so the red and green claims above come from reading the code. I did not run a live Vega session with two hosts. In production the router's |
4a6c731 to
c466c4e
Compare
|
Round 5 — the 07:39Z review, each item mapped to its commit at head 1. Inventory test through the production constructor — 2. Doctor test through the production constructor, unscoped — 3. Validation: both red/green checks were run by reverting the two cited lines and restoring them, on the exact code now pushed. |
|
The earlier findings from 4a6c731 are mostly fixed, but one problem remains at c466c4e. When the captured host env has neither HOME nor USERPROFILE (env -i, a systemd unit without User=, some launchd or MDM contexts), createDeviceInventoryHost throws COMMAND_FAILED host_home_unbound. |
c466c4e to
e2501b1
Compare
|
Round 6 — the 09:35Z review, each item mapped to its commit at head 1. BLOCKING — a host that names no home turned off the whole host (
2. Recommended (applied) — a no-HOME case through the gateways. I also covered the Android branch directly in Red/green evidence (your claims from reading the code held, and I verified both directions rather than asserting them):
Gate. On the notes you flagged as not checked: no lane runs with HOME unset, which is exactly the gap this adds a test for, and your reading that the Windows lanes were not exercised is right — the two new tests are the only new coverage on this route, neither spawns a shell, and both run on every OS lane. |
|
Thanks, e2501b1 resolves the last blocker. Smoke Tests was still running when I checked, and there are no conflicts. This is ready for human review. |
|
#3763 and #3798 made claim storage and recovery read an explicit host. exec now takes the host from the CLI entry like web does, and passes host.env and host.cwd to the claim store, the recovery gateway, device inventory, and the child process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Every non-test configuration read on the converted routes now takes an explicit
HostEnvironmentinstead of the ambientcommandHostEnvironment():34ambient reads outside host-kit command execution became required-host parameters, per-runtime state, or construction-bound ports. The boundary reads are twowhichCmdPATH lookups — applewhichCommandand linuxwhichOnPath— which read the command-host scope (the runtime host plus the per-request env overlay) at the point of spawning a host command. They are part of the command-execution boundary that #3753's gate will allow; they are not configuration owners. One out-of-composition fallback remains: the Linux display decision for standalone leaf callers that name no host, reading the command host at call time with no memo. Composed routes never reach it — the Linux interactor always enters the provider bound to its own host. Vega has no ambient read at all any more: inventory, doctor and the interactor adapter share one resolver over the runtime host, and the un-bound scope default refuses.Every platform package now derives display, tool, and home configuration from the host bound at construction of its local tool provider: the Linux interactor builds
createLocalLinuxToolProvider({ host })per instance and owns its display decision on that object (no module cache, no reset helper; input resolution is not memoized because the interactor itself lives one request); the Vega plugin buildscreateLocalVegaCliAdapter(host)per interactor, and inventory, doctor and the adapter all resolve the executable through ONE resolver (vega-executable.ts) over that runtime host's PATH and host-derived home —createDeviceInventoryHostderives itshomeDirectoryfromhost.env(hostHomeDirectoryFromEnv— HOME ?? USERPROFILE, never the process home; a host that names none yieldshomeDirectory: undefined, which turns off only the home-derived default paths — Android's~/Android/Sdkroot and Vega's default-install probe — never the whole host, so inventory still works for every family),createHostDiagnosticspasses its host intovegaToolchainCheck, and the un-bound scope default refuses withvega-adapter-host-unboundinstead of reading an ambient environment; the Apple runner reads its configuration through the per-runtime host slot entered by the daemon route.platform-webexports one policy for the provider of a web request,resolveWebProviderForHost(host)— request-scoped provider wins, else the agent-browser provider bound to the composing host — and the interactor, the network transport and the audio probe all resolve through it, so every reader of one web request agrees on one provider. The un-scoped fallback stays fail-closed (web-provider-missing).Work is split into four commits by layer: contracts + shared test-kit, Apple, Linux/Vega/web/HarmonyOS, root composition.
Part of #3747. Part of #3794 — part 2 (one entered runtime store, collapsing the per-module
runtimeStatesaggregation) is the next PR.Validation
c466c4ee0a:pnpm check:affected --run --headpassed (receiptrun-LwZ5BO),exactCommit=true.commandHostEnvironment()reads outside host-kit: 34 at basec966724bea→ 2 spawn-boundwhichCmdPATH lookups + 1 memo-less out-of-composition display fallback (standalone Linux leaves) at head. For composed runtimes none of these is a configuration read: display, tool and home configuration is bound at provider construction from the runtime host.DebugSymbolsOptions.cwdstays optional andAgentDeviceClientgains nohost; the CLI and MCP surfaces pass their own captured host env intoformatCliOutput.interactors.test.ts); the composed daemon route configures interactors from its host, not the process (daemon-composition.test.ts); two runner runtime states with differentAGENT_DEVICE_IOS_RUNNER_LEASE_DIReach resolve their own value and neither the process value, plus a read outside any entered runtime refusing withapple_runner_host_unbound(runner-lease-runtime-host.test.ts,runner-owner-state.test.ts); theweb-provider-missingrefusal for every un-scoped web provider operation (provider-composition-fallback.test.ts); two interactors on different hosts keep their own display decision across A(X11) → B(Wayland) → A with an opposing process env (interactor-host-isolation.test.ts); two Vega hosts resolve the CLI executable from their own PATH and HOME, each adapter memoizes on its own instance, and neither reuses the other's answer (tool-provider-host-isolation.test.ts);vegaPlugin.createInteractorbinds each caller's host so the returned interactor runs that host's executable, against a process command host naming a third location — removing the binding makes it fall through to thevega-adapter-host-unboundrefusal (index.test.ts);createVegaInventory(createDeviceInventoryHost(host))lists devices through a host whose HOME differs from the process HOME and names the only vega (platform-runtime-host.test.ts), andcreateHostDiagnostics(host).toolchainCheckreports the CLI found for the same host with no provider scope (platform-runtime-host-diagnostics.test.ts) — both go red when the host-derived home or the doctor host binding is reverted.CI obligations
Full CI on this head; device lanes run there. The macOS helper lane and the native-backend refusal were run live on
17ac24fb79— see the evidence comment; the Apple routes are unchanged since.Unresolved risks
None known beyond the review.