Skip to content

feat(computer): computer envs deploy on local Docker - #369

Merged
earakely-scale merged 23 commits into
mainfrom
edgararakelyan/fd-4358-m07-computer-envs-deploy-on-local-docker-the-computer-env
Oct 28, 2026
Merged

earakely-scale merged 23 commits into
mainfrom
edgararakelyan/fd-4358-m07-computer-envs-deploy-on-local-docker-the-computer-env

Conversation

@earakely-scale

@earakely-scale earakely-scale commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

M0.7 of the CUA env epic (FD-4345): computer envs deploy on local Docker, FD-4358, with M0.8 (deploy_env env_params, FD-4349), M0.5 (the computer skill, FD-4355) and M0.11 (Env.close at teardown, FD-4464) folded in. It follows the reviewed design, CUA Env M0.7: Deploying a Computer Env on Local Docker, with its 15 choices confirmed and the changes below decided in review. It builds on #358 (M0.6), now merged, and is rebased onto main.

What's in it

  • The ubuntu-24.04 base's user has a desktop's standard folders (Documents, Downloads, ... from xdg-user-dirs), so the driver's default data paths exist and a task can name them.
  • Providers say what they run natively, and containers can have no network.
    • native_platforms(): linux/amd64 by default, the host's for local Docker. A computer boots only on a provider that runs its arch natively; create_container takes no platform (decided in review), since that choice is made before it's called.
    • NetworkPolicy.closed is an allowlist of nothing. Local Docker enforces it for a container: it runs on an internal network of its own, with a relay container (providers/sandbox_providers/local_docker/relay/, built here from its sources) publishing its port to the computer's address there. A VM given a restricting policy is refused.
    • The local Docker provider moves into providers/sandbox_providers/local_docker/ with its relay (local_sandbox.py is local_docker/provider.py; decided in review); the package still exports LocalSandbox and LocalSandboxProvider, and the plugin-API check reports no break.
    • reset_container(sandbox, ...) resets a sandbox's container to a fresh one of the image, on the same sandbox and port; local Docker replaces the relay too. A computer env's reset uses it, since a computer's state is its whole filesystem and running session, with no seed to reload in place as an MCP server does.
  • The computer env provider (providers/env_providers/env_computer_provider.py) deploys a computer env with no gateway in front:
    • it boots the first ready build, in the base's order of forms and arches (or env_params.form's), on a sandbox provider that runs its arch natively;
    • the driver's card is the env card, served under the env's environment_name;
    • it checks the driver reports the env's display;
    • the record's metadata.computer keeps the form, arch, provider, image, computer, display, network, computer_settings (a secret's or a generated one's withheld) and env_params.
  • Gate 3 (composer.py): after a build, the composer boots it at the env's settings and display, as a deploy does, on a configured provider that runs its arch natively, and probes it at full. The build becomes ready with the driver's card, or failed at the probe with the report stored as a FileArtifact. A build no configured provider runs natively stays unverified, saying why, and env build probes it once one does. A probe's sandbox, and a boot that fails (a closed-network one whose setup fails, or one that fails its name or display check, too), go with their local work folders.
  • deploy_env env_params (M0.8), one table per layer: a computer env takes form, computer_settings (deploy-phase values of the base's settings, checked as the env's are; a secret one, here or on the env, only as a bare secret:/env: reference, since the env, the task and the deploy record keep what's given) and driver_settings (the driver's ComputerSettings, such as its default coordinate space, passed in AGENTENV_COMPUTER_SETTINGS). Preflight now asks every env type's deploy_refusal, so another type, or an option a type's deploy doesn't name, is refused before anything deploys.
  • Reset returns the computer to boot state: the driver ends its recordings, then a fresh container of the same image boots in the old one's place, readied as a deploy readies it. A sandbox provider that can't replace a container (Modal today) fails the reset step, naming itself, rather than skipping it. The computer keeps its address, so the agent's registered MCP URL stays valid, but an agent's MCP session ends with the old driver: the fresh one answers it with 404, after which an MCP client starts a new session (decided in review; Claude Code opens a new one every turn). Redeploying into a new sandbox instead was ruled out: a run's stored context can add a deployed env but not replace one, so the new address wouldn't be saved.
  • Env.close at teardown (M0.11): teardown_run and the teardown_sandboxes step share one core (task.teardown.tear_down). First the recordings the run left open end, each through its driver with a fresh grant, whatever env serves it; then each env still up closes under the per-sandbox timeout (a plugin's own env class through its own close); a recording still open after that is registered from its namespace; then every sandbox is terminated by id as before and a local one's folder removed (the step now does both too). Env.close and Env.reset keep their signatures, so out-of-tree overrides are unaffected.
  • A computer env ends its own recordings. computer-recording/v1 gains end_all, which ends every recording not yet ended under the grant each started with, and every end uploads the manifest beside the segments (<recording_id>/manifest.json). A computer env's close and reset call it before the computer goes, so a recording open at a reset, or at a close outside a run's teardown, is saved too. Teardown, and end_computer_recording when the driver no longer knows a recording (as after a reset), register it from what its namespace holds, reading that manifest.
  • Env skills, and the computer's (M0.5): any env built on the protocol SDK can serve agents a skill. skill/v1 (SKILL_EXTENSION_URI) answers get {name} with {name, description, skill_md}, written under the name the caller gives, and an env serves it by marking the method that writes it with @agent_skill (description and body). The computer driver's base class serves one written from the computer as it booted, ending with the driver class's new notes; computer/v1 now only declares the seven tools and the driver's features, and the conformance probe checks the skill. add_skills takes env_ids: for each env the run deployed and bound to the agent, it installs the env's skill under its environment name (the agent's MCP alias for it, with a digest of the env id when the name had to be normalized or shortened), or, for an env whose own card serves none, as an MCP server behind its gateway, each child env's under that child's name, and records each SKILL.md in the run's context (env_skills, by skill name).
  • data/get takes paths (decided in feat(computer): the computer env type and the composer (container forms) #358's review): a computer returns the files under the paths it's given, or under the default_data_paths its card declares (Desktop, Documents, Downloads). A get hook that doesn't take paths refuses them; one that does gets None when the call names none. ComputerSettings.data_paths is gone.
  • A recording on a computer with no network is refused at start, since its segments couldn't reach the store.
  • The desktop example (src/agent_env/examples/desktop/, the eighth shipped bundle): a computer env of ubuntu-24.04 and reference, a probe task (deploy, probe at full) and an agent task (Claude Code, given the computer skill, makes a folder through the file manager under a recording; the check reads it back through the driver).
  • The M0.3 scaffold is gone. Its probe and agent tasks are the example's; its scripted drive under a recording runs on the example env (tst/integration/computer/recording/); the recording chaos tests run on the example's composed image, with the conformance fixture started through computer-exec as the probe starts it.

Where this differs from the design

  1. A computer env ends its own recordings at close and reset (decided in review), through the driver's new end_all, instead of Env.close(context) and Env.reset(deployed, context) ending them from the run's context, which would have broken out-of-tree overrides of both. Teardown still ends the run's open recordings first, each with a fresh grant (decided in review of Greptile's finding that a recording served by another env type would lose its last segment). What remains: an end at reset uses the grant the recording started with, so on a store whose grants expire before a long recording is reset, the segments recorded after expiry are lost.
  2. Teardown terminates an env's sandboxes by id even after its close, instead of marking them torn down. A built-in close logs a failed terminate rather than raising, so trusting it could leak a sandbox; terminate_sandbox is idempotent, so the second terminate costs one lookup.
  3. A close that fails or times out is logged, and its sandboxes go into the report by what their terminate by id did, so failed keeps meaning "may still be running".
  4. env_params takes computer_settings and driver_settings (decided in review), one table per layer, instead of settings by layer and spaces.
  5. A deploy hides no tools (decided in feat(computer): the computer env type and the composer (container forms) #358's review): a task that wants fewer tools uses modify_env_tool_access, which works through the driver's disable-tool/v1.
  6. The skill is any env's, not the computer's (decided in review): skill/v1 and @agent_skill replace a skill method on computer/v1, and add_skills takes env_ids instead of computer_env_ids, so other env types can hand agents a skill the same way. get takes the name to write into the SKILL.md's frontmatter, so add_skills names it per env.
  7. A DeployedAgent records the env_ids its deploy_agent registered, since nothing in a run's context said which envs an agent is bound to.
  8. data/get paths and the driver's default replace data_paths (decided in feat(computer): the computer env type and the composer (container forms) #358's review; snapshot_env gains computer_file_paths in M1.8, FD-4382).
  9. The recording refusal on a computer with no network is new: local Docker's closed network relays only inbound, so a recording there could never upload.
  10. create_container takes no platform (decided in review). The design passed it so a provider would refuse a platform it would emulate, but both callers, the deploy and gate 3, choose a provider by native_platforms() first, so that check could never fire, and the new parameter broke out-of-tree overrides of create_container (the plugin-API check).

Review

Greptile's review of 9e775d5 raised seven threads. Six are fixed in 7655132, as the bullets above now say: teardown ends the run's open recordings first; gate 3 probes at the env's settings; a reset a provider can't carry out fails; skill names that come out alike get an env-id digest; a get hook that takes paths gets None; a failed closed-network boot removes its folder. The seventh, a secret setting given as its value reaching the deploy record, is fixed in 77cbffb (decided in review): a secret setting takes only a bare secret:KEY or env:NAME reference. The plugin-API check's break, create_container's new platform, is gone (difference 10); the check now reports no break. #358's fix for a driver file named outside the build folder (98e139a) applies here too. Greptile's review of 3abc1fa raised four more, fixed in 83e9837: skills of child envs behind a gateway, a plugin env class's own close at teardown, a boot that fails its checks leaving its folder, and a secret setting with a non-string default refusing its reference.

Testing

  • Unit. Rebased onto main, and again with the secrets change, 11,341 passed; the one failure, the known test_deep_nesting timing flake, passes alone. On the review round before the rebase, 11,288 of 11,292 passed. Three failures were in the round's own new tests, which were fixed and rerun with their files (1,983 passed); the fourth is the known test_deep_nesting timing flake, which passes alone.
  • After the review rounds, at 837d495 (laptop arm64): tst/integration/computer 19 passed and 1 skipped (the agent task, which needs a model endpoint), including reset with and without network, recordings open at a reset and at teardown, and the base's standard folders. The agent run passed in 25.3 s: Claude Code, given the computer's skill as desktop through skill/v1, made /home/user/Documents/Reports through Thunar in 8 tool calls; the recording ended with 2 segments and none missing, and nothing was left. At 83e9837 the same run scored 0 because the base had no Documents folder and the agent asked rather than create one (the run before the review created it unasked), which 837d495 fixes in the base. The bullets below are from before the review rounds.
  • Integration (tst/integration/computer, laptop arm64, real Docker and the local registry), before the review round: 18 passed and 1 skipped (the agent task, which needs a model endpoint). The scripted-drive recording test failed that run: its pixel check compared against the recording's first frame, which can predate the Fixture Desk now that the drive starts it. Fixed to compare against the frame before the click, it passed twice on its own. CI's integration jobs run the same tier on Linux amd64.
  • Chaos on the laptop (arm64), 8/8, with deploy_chaos.py (scenarios from the design's chaos row; each also checks that no container, relay, network or work folder is left):
    • the driver killed mid-deploy: supervisord restarts it and the deploy goes on;
    • the computer killed mid-deploy: the deploy fails, naming the last thing it saw, and nothing is left. It waits out the 180 s ready timeout first, since readiness doesn't watch the container;
    • the computer killed mid-task: the call fails, and teardown still reports the sandbox terminated;
    • the probe's computer killed during gate 3: the pair fails at the probe, and env build resumes it to ready. This found a hang: the probe had no deadline, and on Docker Desktop a dead computer's connection stays open, so the put waited indefinitely. The probe now has 120 s;
    • a boot past its timeout: the deploy fails naming what it last saw;
    • a close with an open recording whose driver is gone: teardown goes on and registers the segment already uploaded;
    • two computer envs at once: separate sandboxes and ports, both pass the basic probe, deployed in 2.0 s;
    • teardown cancelled part-way: it returns what it reached, and a second teardown finishes the rest.
  • Chaos on EC2 (amd64, c6i.2xlarge), at 4ba6146: the same 8/8, and gate 3 again with Docker itself restarted mid-probe: the pair fails at the probe, and env build resumes it to ready once Docker is back. There the probe's computer dying fails fast, since the port closes with the container. The box had no arm64 emulation, so the arm64 pair fails at build, as gate 1 promises.
  • The agent run (agent-env run desktop --task agent, laptop only, the model key held in-process): passed in 52.7 s. Claude Code, given the computer's skill (then named computer-desktop; it is desktop since the review), made the folder through the file manager in 36.4 s, the check confirmed it through the driver, and the recording ended with 4 segments and none missing. Nothing was left.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; the latest change fixes the remaining cleanup finding.

Summary

Computer envs can now deploy on local Docker, reset in place, serve agent skills, and save recordings before teardown.

  • Computer environments build, pass a probe, and deploy on a native sandbox.
  • Local Docker runs computer containers on closed networks and reports native architectures.
  • Computer recordings save their manifests and can end before reset or close.
  • Run teardown closes deployed environments before it terminates their sandboxes.
  • Agents can receive named skills from computer and other environments.
  • Computer data reads can return requested folders or the desktop defaults.
  • Supporting documentation and example scaffolding move with the new computer workflows.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Compose image] --> B[Boot and probe]
  B --> C[Ready build]
  C --> D[Deploy computer]
  D --> E[Agent uses tools and skills]
  E --> F[Reset or close]
  F --> G[End recordings]
  G --> H[Replace container or terminate sandbox]
Loading

Reviews (14) · Last reviewed commit: "fix(sandbox): a closed container whose m..." · Reviewed by Greptile

Comment thread src/agent_env/task/teardown.py Outdated
Comment thread src/agent_env/task_step/task_steps/add_skills.py Outdated
Comment thread packages/agentenv-protocol/src/agentenv_protocol/agent_env_environment.py Outdated
@earakely-scale
earakely-scale force-pushed the edgararakelyan/fd-4358-m07-computer-envs-deploy-on-local-docker-the-computer-env branch from 496213f to 4ba6146 Compare October 28, 2026 16:42
@earakely-scale
earakely-scale force-pushed the edgararakelyan/fd-4356-m06-computer-env-type-and-the-composer-container-forms branch from 8b42cbb to f9cda77 Compare October 28, 2026 16:55
@earakely-scale
earakely-scale force-pushed the edgararakelyan/fd-4358-m07-computer-envs-deploy-on-local-docker-the-computer-env branch from 4ba6146 to d79d4ed Compare October 28, 2026 16:59
Comment thread src/agent_env/providers/env_providers/env_computer_provider.py Outdated
Comment thread src/agent_env/providers/sandbox_providers/local_docker/provider.py
@earakely-scale
earakely-scale force-pushed the edgararakelyan/fd-4358-m07-computer-envs-deploy-on-local-docker-the-computer-env branch from d79d4ed to 9e775d5 Compare October 28, 2026 17:22
Comment thread src/agent_env/providers/env_providers/env_computer_provider.py Outdated
Comment thread src/agent_env/env/envs/computer/composer.py Outdated
@earakely-scale
earakely-scale force-pushed the edgararakelyan/fd-4356-m06-computer-env-type-and-the-composer-container-forms branch from 22348da to 572960c Compare October 28, 2026 17:32
Base automatically changed from edgararakelyan/fd-4356-m06-computer-env-type-and-the-composer-container-forms to main October 28, 2026 18:20
earakely-scale added a commit that referenced this pull request Oct 28, 2026
…e probe boots at the env's settings, no platform on create_container

From the review of #369:
- teardown ends the run's open recordings, each with a fresh grant whatever env serves it, before
  any env closes, so a recording on an env whose close doesn't end it keeps its last segment
- gate 3 boots a build at the env's computer_settings and display, as a deploy does
- a reset the sandbox provider can't carry out fails the step instead of being skipped
- a computer skill whose name had to be normalized or shortened takes a digest of the env id
- a data/get hook that takes paths gets None when the call names none
- a closed-network boot that fails removes its work folder
- create_container takes no platform: the deploy and gate 3 choose a provider by
  native_platforms() before calling it, so the refusal it carried never fired, and the new
  parameter broke out-of-tree overrides (the plugin-API check)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale force-pushed the edgararakelyan/fd-4358-m07-computer-envs-deploy-on-local-docker-the-computer-env branch from 9e775d5 to f6e26fe Compare October 28, 2026 18:29
earakely-scale added a commit that referenced this pull request Oct 28, 2026
…e probe boots at the env's settings, no platform on create_container

From the review of #369:
- teardown ends the run's open recordings, each with a fresh grant whatever env serves it, before
  any env closes, so a recording on an env whose close doesn't end it keeps its last segment
- gate 3 boots a build at the env's computer_settings and display, as a deploy does
- a reset the sandbox provider can't carry out fails the step instead of being skipped
- a computer skill whose name had to be normalized or shortened takes a digest of the env id
- a data/get hook that takes paths gets None when the call names none
- a closed-network boot that fails removes its work folder
- create_container takes no platform: the deploy and gate 3 choose a provider by
  native_platforms() before calling it, so the refusal it carried never fired, and the new
  parameter broke out-of-tree overrides (the plugin-API check)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale force-pushed the edgararakelyan/fd-4358-m07-computer-envs-deploy-on-local-docker-the-computer-env branch from f6e26fe to 7655132 Compare October 28, 2026 18:35
Comment thread src/agent_env/task/teardown.py
Comment thread src/agent_env/providers/env_providers/env_computer_provider.py Outdated
Comment thread src/agent_env/env/envs/computer/gate.py Outdated
Comment thread src/agent_env/task_step/task_steps/add_skills.py Outdated
earakely-scale added a commit that referenced this pull request Oct 28, 2026
… boot's folder, secret references

From the review of #369:
- add_skills installs each child env's skill when the env's own card serves none, as an MCP server
  behind its gateway's card does, under that child's name; env_skills is keyed by skill name
- teardown calls a plugin env class's own close: close_deployed read env._env_provider, which only
  agent-env's envs set
- a computer that boots but fails its name or display check goes with its local work folder
- a secret setting takes its reference whatever its default's type, since a reference is a string

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/agent_env/task_step/task_steps/add_skills.py
Comment thread src/agent_env/task_step/task_steps/add_skills.py
earakely-scale and others added 9 commits October 28, 2026 15:23
…iner's network away

create_container takes the platform its image must run as and refuses one the
provider doesn't run natively (native_platforms: this machine's for local,
linux/amd64 elsewhere). Local Docker enforces an allowlist of nothing for a
container: it runs on an internal network of its own, and a relay on that
network and the bridge publishes its port.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…each build, and deploy_env takes env_params

The computer env provider boots the env's first ready build that the sandbox
provider runs natively, with its deploy-phase settings and the driver's own,
waits for computer-ready, checks the display, hides the env's tools for every
role and records the driver's card as the env's. Gate 3 boots each build a
configured provider runs natively and probes it at full: ready with its card,
or failed at the probe; a build nothing here runs natively stays unverified.
deploy_env passes env_params to the env type's deploy() and checks them at save
for every env type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…top folders

data/get passes `paths` to a get hook that takes them and refuses them otherwise; the client's
get_data sends them. A computer returns the files under the paths it's given, or under
DEFAULT_DATA_PATHS (Desktop, Documents, Downloads), which its card declares as
default_data_paths. ComputerSettings drops data_paths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dboxes go

Env.close(context) joins the base contract; built-ins take the context and ignore it. teardown_run
and the teardown_sandboxes step share one core (task.teardown.tear_down): each env still up closes
through close_deployed under the per-sandbox timeout, then every sandbox is terminated by id as
before (terminate_sandbox is idempotent, so a close that swallowed a failed terminate is still
covered) and a local one's folder removed, which the step now does too. A computer env's close ends
its open recordings; before_teardown keeps only the changelog drain. The shared helpers move from
the step module to task.teardown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…omputer test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Env.reset takes the run's context, which reset_env passes. ComputerEnv.reset ends the env's open
recordings, then the computer provider replaces its container with a fresh one of the image it
booted, its settings applied as the deploy applied them, on the same sandbox and host port, and
readies it as a deploy does (ready, display, hidden tools). SandboxProvider.recreate_container
removes and starts the container on a VM-backed sandbox; local Docker also replaces the relay of a
closed network, since the fresh container's address there may differ.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… refused at start

Its driver couldn't reach the store the segments upload to, so the start fails, recorded as any
failed start is, rather than recording segments that never arrive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed by add_skills

computer/v1 is served with a skill method: the driver base class writes a SKILL.md under the name
it's given from the computer as it booted (platform, session user and home, the live screen size,
what its input takes, a per-OS shortcut template, Linux for now, and the driver's new notes). Its
params are the driver's features, as before; the declaration keeps recording only those.

add_skills takes computer_env_ids: for each, an env this run deployed and bound to the agent (a
DeployedAgent now records the env_ids deploy_agent registered), it asks the driver for its skill
under computer-<environment name>, installs it, and records the SKILL.md in the run's context.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rk folders

Gate 3's probe and a boot that fails partway tear down a sandbox no run records, so no run's teardown
removes its local work folder; they now discard it as teardown would.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
earakely-scale and others added 13 commits October 28, 2026 15:23
The eighth shipped bundle: a computer env of ubuntu-24.04 and reference, a probe task (deploy,
probe at full) and an agent task (Claude Code, given the computer skill, makes a folder under a
recording; the check reads it back through the driver). The scaffold's probe and agent tasks are the
example's; its scripted drive under a recording runs on the example env; the recording chaos tests
run on the example's composed image, with the conformance fixture started through computer-exec.
The integration tests compose the example env once per module, and one deploys it with no network:
reached, reaching nothing, fresh after a reset, gone after teardown. Docs say a driver deploys only
as a computer env's driver, and how a computer env deploys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and reset take no context

The env, not the run, ends what runs on its computer: computer-recording/v1 gains end_all, which
ends every recording not yet ended under the grant each started with, and every end uploads the
manifest beside the segments. A computer env's close and reset call it before the computer goes.
Teardown then registers the recordings the run left open from their namespaces, reading the manifest
the driver uploaded (register_open_recordings), and end_computer_recording does the same when the
driver no longer knows a recording, as after a reset. So Env.close and Env.reset keep their
signatures, and an out-of-tree override of either is unaffected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y its computer and registered whole

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ings, one table per layer

A deploy sets the base's deploy-phase values in computer_settings, checked as the env's are, and the
driver's in driver_settings, checked by the protocol's ComputerSettings and passed in
AGENTENV_COMPUTER_SETTINGS; driver_settings replaces spaces, which set two of them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l_access

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e probe boots at the env's settings, no platform on create_container

From the review of #369:
- teardown ends the run's open recordings, each with a fresh grant whatever env serves it, before
  any env closes, so a recording on an env whose close doesn't end it keeps its last segment
- gate 3 boots a build at the env's computer_settings and display, as a deploy does
- a reset the sandbox provider can't carry out fails the step instead of being skipped
- a computer skill whose name had to be normalized or shortened takes a digest of the env id
- a data/get hook that takes paths gets None when the call names none
- a closed-network boot that fails removes its work folder
- create_container takes no platform: the deploy and gate 3 choose a provider by
  native_platforms() before calling it, so the refusal it carried never fired, and the new
  parameter broke out-of-tree overrides (the plugin-API check)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erence

A secret setting given as its value, on the env or in deploy_env's env_params, was kept wherever
what's given is kept: the env, the task, the composed computer's defaults and the deploy record's
env_params, which reset reads back. check_computer_settings now refuses anything but a bare
reference, the form a stored context keeps, so only names are stored and every boot resolves them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It resets the container create_container ran to a fresh one of the image, on the same sandbox and
port, which is what a computer env's reset uses it for; the provider guide now lists it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…MCP session

The fresh driver doesn't know the old one's MCP sessions and answers one with 404, after which an
MCP client starts a new session; Claude Code opens a new one every turn anyway.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s env_ids

skill/v1 (SKILL_EXTENSION_URI) answers get {name} with {name, description, skill_md}: the env's
SKILL.md for agents under the name the caller gives. An env built on the SDK serves one by marking
the method that writes it with @agent_skill, which returns its description and body. The computer
driver's skill moves there from computer/v1, which is now declared with the driver's features, and
the conformance probe checks it. add_skills's computer_env_ids becomes env_ids: each env's skill is
installed under its environment name (the agent's MCP alias for it) and recorded in env_skills.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… boot's folder, secret references

From the review of #369:
- add_skills installs each child env's skill when the env's own card serves none, as an MCP server
  behind its gateway's card does, under that child's name; env_skills is keyed by skill name
- teardown calls a plugin env class's own close: close_deployed read env._env_provider, which only
  agent-env's envs set
- a computer that boots but fails its name or display check goes with its local work folder
- a secret setting takes its reference whatever its default's type, since a reference is a string

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…folders

The base created its user with only a home, so the desktop made Desktop alone: Documents and
Downloads, two of the driver's default data paths, didn't exist, and the desktop example's agent
had to create Documents before it could make its folder there. The base now installs
xdg-user-dirs and creates the session user's standard folders at build, as a real Ubuntu desktop
has them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cal_docker/

local_sandbox.py is local_docker/provider.py, and the relay that publishes a container closed off
from every network moves beside it (local_docker/relay/), since only the local provider uses it;
it isn't a provider of its own. local_docker exports LocalSandbox and LocalSandboxProvider as
e2b/ does its classes, the package keeps exporting them, and the "local" provider is registered
by its new path. The relay's image tag hashes its files, not their place, so it isn't rebuilt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale force-pushed the edgararakelyan/fd-4358-m07-computer-envs-deploy-on-local-docker-the-computer-env branch from e891637 to faeaac6 Compare October 28, 2026 22:27
Comment thread src/agent_env/providers/sandbox_providers/local_docker/provider.py
…its relay and network down

create_container's marker-write failure path removed only the container; for a container with no
network the relay, which holds the published host port, and the internal network stayed, with no
record for teardown to reclaim them. It now also removes what the sandbox's label names, as
teardown does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale merged commit 55e4e6b into main Oct 28, 2026
25 checks passed
@earakely-scale
earakely-scale deleted the edgararakelyan/fd-4358-m07-computer-envs-deploy-on-local-docker-the-computer-env branch October 28, 2026 22:49
earakely-scale added a commit that referenced this pull request Oct 29, 2026
…l names its cause

- A secret app setting is checked only as a reference (or null, where it's optional), never against the
  constraints on its value, which its value then never reaches; a required one left out is named.
- A data/add, data/get or run whose connection to the driver breaks fails naming the env, the call and
  the cause, which httpx often leaves empty (found by the chaos run on EC2: a bare "ReadError: ").
- test_artifact_staging imports LocalSandbox from local_docker, where #369 moved it; main's unit tier has
  failed on it since #374.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant