Verified 2026-08-05
Runtime · 8 rules

What does my skill's shell see?

The shell your skill runs commands in is sealed: environment variables you set on the host do not reach it, and neither do exports written by hooks. The inline shell-execution syntax some skills use in their instructions is disabled in Cowork entirely. The shell tool is also not the same tool as the CLI's, so branching on tool names is a reliable signal where branching on environment variables is not.

Do not treat the home directory as a private place that outlives the session.

SILENTMeasured Local sandbox

In the local sandbox the home directory is the session directory itself, not a separate per-user home, and it goes away with the session. Writing there is fine for scratch, but nothing put there is delivered, carried to the next session, or visible to anyone. Deliverables belong in the outputs location.

Do not use the inline shell-execution syntax in skill instructions and expect it to run.

The syntax that lets a skill embed a command in its own instructions and have the result substituted is disabled in Cowork. It fails quietly rather than erroring, so a skill that relies on it to gather context gets an empty result and carries on with wrong assumptions.

Caveat: Controlled by a setting rather than hardcoded, so the behaviour is configuration-dependent.

Do not rely on arbitrary outbound network access from shell commands.

Outbound access from the shell is filtered by destination rather than absent: some hosts answer and others do not, and the session carries a URL allowlist. Fetching is also available as a dedicated capability with its own routing. Write skills that use the fetch capability when it exists and state a clear limitation when it does not, rather than shelling out to a network client and assuming any host is reachable.

Caveat: Routing for fetching has changed across releases and is configuration-dependent.
Caveat: Which destinations are permitted was sampled, not enumerated.

Prefer what is preinstalled, and never install globally. A user-scoped or project-local install works, but treat it as a fallback.

Check what is already there first: the sandbox ships Python 3.10.12 with roughly 149 packages, including pandas, numpy, PIL and openpyxl. If you do need something else, a user-scoped Python install (pip install --user) and a project-local Node install (npm install) both succeed, and the package imports normally afterwards. A global install does not take effect — npm install -g in particular leaves nothing behind. Which package sources are reachable is session configuration that has changed between releases, so put any install on a path that degrades gracefully rather than making it a prerequisite.

Caveat: Which package sources are reachable is configuration-dependent and can change between releases.
Caveat: Whether these installs fetched from a public registry or a local cache was not distinguished; only that the install step succeeded.

Do not assume the sandbox has no third-party libraries. It ships a large preinstalled stack.

FRICTIONMeasured Local sandbox

The environment your shell commands run in ships Python 3.10.12 with roughly 149 packages already installed — pandas, numpy, PIL and openpyxl among them, alongside other data, document and imaging libraries. Skills have shipped workarounds and portability warnings for a scarcity that is not there. Check for what you need at runtime before vendoring it or degrading: the exact set belongs to the shipped image and can change with it, so test rather than rely on this list.

Caveat: Read from the shipped guest image; the exact package set is a property of that image and can change with it.
Caveat: The two sandboxes ship different images. The remote one was seen once with a newer Python plus OCR, PDF-rendering, PDF-parsing and office-conversion tools preinstalled; treat the specific versions as per-sandbox and check at use.

Do not expect to read or write anything outside your own session, and do not rely on the identity your shell runs as.

LOUDMeasured Both sandboxes

In the local sandbox each session runs as its own operating-system user: sibling sessions are visible by name but their contents are refused, and the session namespace holds hundreds of entries. In the remote sandbox there is no per-session user at all and commands run as root. Either way, anything your skill needs must be inside the session or fetched into it — but identity itself is not a stable thing to branch on.

Caveat: Verified by attempting cross-session reads in the local sandbox, which were refused.
Caveat: The two sandboxes differ: per-session user locally, root remotely. Directory listings show scale, not how many sessions are running at once.
Caveat: The remote half — the shell runs as root — was confirmed from inside a live cloud session on 2026-09-21.

Do not pass configuration to your skill's shell commands through the environment.

SILENTMeasured Local sandbox

The shell your commands run in does not inherit the host environment: variables set in user or managed settings do not appear there, and neither do exports written by a hook. Only a couple of CLAUDE_* variables are present. Pass configuration one of three ways instead — put the value literally in the command string, write it to a file and have the command read that file, or pass it as an argument to a script your skill invokes.

Caveat: Established by a live probe rather than from the binary; the symbol that once documented the boundary has since disappeared from the shipped application.

Do not assume the shell tool has the same name it has in the CLI.

The tool your skill uses to run commands in Cowork is a different tool from the CLI's, with a different name. This matters if your skill's instructions name tools explicitly, and it is also useful: the tool surface is a more reliable indicator of where you are running than the environment is.

What is not established

  • Network egress is allowed through a fetch capability rather than arbitrary outbound sockets, and the routing has changed across releases. Assume fetch works and arbitrary sockets do not, and degrade gracefully rather than probing.