Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,10 @@ Adapters should stay thin. A new or changed adapter should:
4. update the provider matrix and adapter-control-plane docs

See [workflows/adapter-porting.md](workflows/adapter-porting.md) for the
porting checklist.
porting checklist and
[docs/extending-adapters.md](docs/extending-adapters.md) for worked examples
(adding a credential type, extending an adapter) annotated with the invariants
each step touches.

## Package naming

Expand Down
39 changes: 33 additions & 6 deletions adapters/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,37 @@
Each adapter maps the shared Workcell runtime into one provider's native
control plane.

Current adapters:
Current adapters (each README covers auth methods, managed control-plane files,
and behavior):

- `codex/`
- `claude/`
- `copilot/`
- `gemini/`
- [`codex/`](codex/README.md)
- [`claude/`](claude/README.md)
- [`copilot/`](copilot/README.md)
- [`gemini/`](gemini/README.md)

Planned fail-closed scaffolds:

- `antigravity/`
- [`antigravity/`](antigravity/README.md)

## Common adapter contract

Every supported adapter follows the same shape:

- one shared runtime VM-plus-container boundary; the adapter is thin and its
provider config is defense in depth, not the boundary
- a session-local provider home rebuilt each launch from immutable baselines
under `adapters/<name>/`, explicit injection-policy inputs, and masked
workspace imports (`runtime/container/home-control-plane.sh`)
- explicit credential keys only — no host home, keychain, socket, or ambient CLI
auth passthrough (see [`../docs/injection-policy.md`](../docs/injection-policy.md)
and [`../docs/invariants.md`](../docs/invariants.md))
- provider-native unsafe-flag rejection in the wrapper
(`runtime/container/provider-policy.sh`), enforced in **every** mode — the
wrapper re-checks arguments (`WORKCELL_WRAPPER_CONTEXT=1`) so even `breakglass`
cannot pass them; breakglass raises the sandbox floor, not the unsafe-flag policy

The cross-adapter mapping tables live in
[`../docs/adapter-control-planes.md`](../docs/adapter-control-planes.md).

Adapter rules:

Expand All @@ -30,3 +51,9 @@ under `adapters/<name>/`. There is no longer a per-provider Go sub-package; see
`internal/adapters/adapters.go` for the public API that the injection, policy,
and runtime paths consume. A provider directory without a registry row is only a
fail-closed scaffold.

For step-by-step worked examples — adding a credential type and extending or
adding an adapter, each annotated with the invariants and threat-model items it
touches — see [`../docs/extending-adapters.md`](../docs/extending-adapters.md).
The porting checklist is in
[`../workflows/adapter-porting.md`](../workflows/adapter-porting.md).
41 changes: 36 additions & 5 deletions adapters/antigravity/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,49 @@
# Google Antigravity CLI Adapter

This adapter directory is a fail-closed planning scaffold. Workcell recognizes
`antigravity` as a planned Google Antigravity CLI provider id, but it does not
install, prepare, authenticate, or launch Antigravity yet.
`antigravity` as a planned Google Antigravity CLI provider id
(`internal/providerid/providerid.go`), but it does not install, prepare,
authenticate, or launch Antigravity yet. It is not in the supported-provider
registry (`internal/adapters/data.go`) and `providerid.IsValid("antigravity")`
returns false.

Support promotion requires the same review unit to add:
## Auth methods

None today. A future path must first pin official install and auth provenance,
then stage only reviewed Google auth material into session-local provider state.
Host Google account caches, browser profiles, keychains, host homes, and
provider caches are not acceptable implicit safe-path inputs
(`docs/injection-policy.md`, `docs/invariants.md` §1). No Antigravity credential
keys exist in current releases; they must not appear in operator policy until
the matching adapter, validation, and docs land.

## Managed control-plane files

None today. Before support is claimed the adapter must own session-local
provider home/cache/settings state under `/state/agent-home` and explicitly map
or block Antigravity's subagent, plugin, MCP, sandbox, permission, hook, and
instruction surfaces (`docs/adapter-control-planes.md`).

## Adapter behavior

`workcell --agent antigravity` exits before runtime preparation with a
"planned Workcell provider adapter, but it is not supported yet" diagnostic and
a non-zero status (`scripts/workcell`). Support promotion requires the same
review unit to add:

- an official pinned Antigravity CLI install path with provenance evidence
- explicit Antigravity home and cache-state handling under `/state/agent-home`
- a staged Google auth handoff that does not mount host Google account state,
browser profiles, keychains, host homes, or provider caches
- provider-native unsafe-flag rejection in the Workcell wrapper
(`runtime/container/provider-policy.sh`)
- deterministic dry-run and scenario coverage
- a live provider certification run before any supported Tier 1 matrix claim

Until those gates land, `workcell --agent antigravity` exits before runtime
preparation with an unsupported-provider diagnostic.
## See also

- [../README.md](../README.md) — adapter index and common contract
- [../../docs/adapter-control-planes.md](../../docs/adapter-control-planes.md)
- [../../docs/invariants.md](../../docs/invariants.md)
- [../../docs/extending-adapters.md](../../docs/extending-adapters.md) — worked
contributor examples (including adding a new adapter)
92 changes: 78 additions & 14 deletions adapters/claude/README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,85 @@
# Claude Adapter

The Claude adapter maps the shared Workcell runtime into Claude Code's native
files and guardrails.
files and guardrails. Hooks and settings are defense in depth; the runtime
VM-plus-container boundary stays primary.

Managed surfaces:
## Auth methods

- `~/.claude/settings.json`
- rendered `~/.claude/CLAUDE.md`
- `~/.mcp.json`
- Claude auth compatibility files when injected
- a reviewed `PreToolUse` Bash hook as defense in depth
- `claude_auth` credential key — a direct staged auth file mirrored into the
Claude auth locations under `~/.claude/`, `~/.claude.json`, and
`~/.config/claude-code/` (`internal/adapters/data.go`,
`runtime/container/home-control-plane.sh`).
- `claude_api_key` credential key — wired through an `apiKeyHelper` script at
`~/.claude/workcell/api-key-helper.sh` that reads the mounted key file, so a
second plaintext key copy is not seeded into the session
(`runtime/container/home-control-plane.sh`).
- `claude_mcp` credential key — reviewed Claude MCP config seeded to `~/.mcp.json`.
- `claude-macos-keychain` resolver — a fail-closed scaffold: it records the
intended host-side auth source in policy but Workcell still aborts launch
until a supported export path exists
(`internal/authresolve/resolve_credential_sources.go`,
`docs/injection-policy.md`).
- Shared GitHub CLI (`github_hosts`, `github_config`) and SSH inputs apply
(`sharedCredentialsEnabled: true` in `internal/adapters/data.go`).

Key points:
See [../../docs/injection-policy.md](../../docs/injection-policy.md).

- hooks are guardrails, not the security boundary
- the default MCP template is empty
- `claude_api_key`, `claude_auth`, and `claude_mcp` are the supported
credential/injection paths
- GUI or IDE use is lower assurance unless it is only a client to the same
bounded runtime
## Managed control-plane files

Repo baselines under `adapters/claude/`:

- `.claude/settings.json`: reviewed session settings seeded to
`~/.claude/settings.json` by `workcell_render_claude_settings` — this is the
file to edit for session-home settings changes.
- `managed-settings.json`: the separate enterprise managed-policy file, installed
and verified at `/etc/claude-code/managed-settings.json` (it is **not** the
session-home `~/.claude/settings.json`).
- `CLAUDE.md`: managed baseline rendered into `~/.claude/CLAUDE.md`.
- `mcp-template.json`: MCP template seeded to `~/.mcp.json`. The default template
is empty — no live MCP servers ship in the baseline.
- `hooks/guard-bash.sh`: the reviewed `PreToolUse` Bash hook.

In-container reserved session targets include `~/.claude`,
`~/.claude/settings.json`, `~/.claude/CLAUDE.md`, the auth mirrors
(`~/.claude/.credentials.json`, `~/.claude.json`,
`~/.config/claude-code/auth.json`), the API-key helper dir `~/.claude/workcell`,
and `~/.mcp.json` (`ReservedTargets` in `internal/adapters/data.go`).

## Adapter behavior

- Each launch rebuilds the provider home from the immutable baseline plus
explicit injection inputs; repo-local `.claude/` and `CLAUDE.md` are masked and
imported only as reviewed layers
(`runtime/container/home-control-plane.sh`, `docs/invariants.md` §3).
- The reviewed `PreToolUse` Bash hook blocks common trust-widening shell
patterns. It is defense in depth: it does not replace the runtime boundary and
does not cover non-Bash Claude tools
(`docs/adapter-control-planes.md#claude-hook-coverage`).
- Autonomy is set host-side via `workcell --agent-autonomy` (mapped to
`--permission-mode`); the wrapper does not honor provider-native overrides.
- Unsafe-argument policy (`reject_unsafe_claude_args` in
`runtime/container/provider-policy.sh`): the wrapper blocks
`--dangerously-skip-permissions`, `--add-dir`, `--allowedTools`,
`--mcp-config`, `--plugin-dir`, `--settings`, `--setting-sources`,
`--system-prompt`, `--append-system-prompt`, in-session `--permission-mode`
overrides, and the `install`/`update` lifecycle commands. These are rejected in
**every** mode including `breakglass`: `provider-wrapper.sh` re-checks arguments
(it sets `WORKCELL_WRAPPER_CONTEXT=1`, which makes the breakglass exemption
inapplicable), so `container-smoke.sh` confirms breakglass overrides still fail.
Breakglass raises the container sandbox floor, not the provider unsafe-flag
policy.
- The wrapper scrubs provider env such as `CLAUDE_CONFIG_DIR`, `GH_TOKEN`,
`GITHUB_TOKEN`, and the OpenTelemetry variables before launch
(`runtime/container/provider-wrapper.sh`).

GUI or IDE use is lower assurance unless it is only a client to the same bounded
runtime.

## See also

- [../README.md](../README.md) — adapter index and common contract
- [../../docs/adapter-control-planes.md](../../docs/adapter-control-planes.md)
- [../../docs/invariants.md](../../docs/invariants.md)
- [../../docs/extending-adapters.md](../../docs/extending-adapters.md) — worked
contributor examples
108 changes: 75 additions & 33 deletions adapters/codex/README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,80 @@
# Codex Adapter

The Codex adapter maps the shared Workcell boundary into Codex-native controls.
Adapter layout (paths relative to `adapters/codex/`):
It re-seeds a session-local Codex home from reviewed baselines on every launch;
the runtime VM-plus-container boundary stays primary and Codex config is defense
in depth, not the boundary.

- `.codex/config.toml`: managed Codex base configuration template seeded into
the session-local Codex home as `~/.codex/config.toml`
## Auth methods

- `codex_auth` credential key — a direct staged `auth.json` seeded to
`~/.codex/auth.json` (`internal/adapters/data.go`).
- `codex-home-auth-file` resolver — a reviewed host-side Codex auth-file reuse
path; still host-side preprocessing only, not Keychain passthrough
(`internal/authresolve/resolve_credential_sources.go`).
- Shared GitHub CLI (`github_hosts`, `github_config`) and SSH inputs apply
because Codex opts into shared credentials
(`sharedCredentialsEnabled: true` in `internal/adapters/data.go`).

See [../../docs/injection-policy.md](../../docs/injection-policy.md) and
[../../docs/provider-bootstrap-matrix.md](../../docs/provider-bootstrap-matrix.md).

## Managed control-plane files

Repo baselines under `adapters/codex/` (paths relative to this directory):

- `.codex/config.toml`: managed base configuration seeded into the session-local
Codex home as `~/.codex/config.toml`. The base sets no `sandbox_mode`, so every
sandbox decision is profile-scoped.
- `.codex/{strict,development,build,breakglass}.config.toml`: Codex 0.134+
profile-v2 layer files. The launcher selects one with `--profile <name>`,
and Codex layers it on top of the base `config.toml`. Each layer carries the
per-profile `sandbox_mode`/`approval_policy`; the base config sets no sandbox
mode so every sandbox decision is profile-scoped.
- `.codex/AGENTS.md`: managed agent guidance seeded into the session-local
Codex home
- `.codex/rules/default.rules`: managed Codex execpolicy ruleset seeded
into the session-local Codex home. Workcell currently ships one
ruleset; the directory shape exists so future overlays can drop in
alongside `default.rules`.
- `.codex/agents/`: managed sub-agent guidance
- `managed_config.toml`: workcell-side managed-mode TOML consumed by the
launcher
- `requirements.toml`: workcell-side adapter requirements contract
- `mcp/config.toml`: MCP server config

Workcell re-seeds this state into the session-local Codex home on launch.
Repo-local control files stay masked on the safe path and are imported only as
reviewed layers.

Codex's own Linux `workspace-write` sandbox is pinned off on the managed
Workcell path. Workcell already provides the outer VM-plus-container boundary,
and the current Codex Linux sandbox depends on unprivileged user namespaces
that are unavailable inside the Tier 1 container.

Final branch publication stays on the host through `workcell publish-pr`, not
from inside the container session.

Codex CLI is Tier 1 when it runs fully inside the bounded runtime. App support
is only valid once it becomes a client of the same bounded executor.
profile-v2 layer files. The launcher selects one with `--profile <name>`;
Codex layers it on top of the base config. Each layer carries the per-profile
`sandbox_mode`/`approval_policy`.
- `.codex/AGENTS.md`: managed agent guidance.
- `.codex/rules/default.rules`: managed Codex execpolicy ruleset. One ruleset
ships today; the directory shape lets future overlays drop in alongside it.
- `.codex/agents/`: managed sub-agent guidance.
- `managed_config.toml`: workcell-side managed-mode TOML consumed by the launcher.
- `requirements.toml`: workcell-side adapter requirements contract.
- `mcp/config.toml`: MCP server config (no live MCP defaults ship in the baseline).

In-container reserved session targets: `~/.codex/{config.toml,auth.json,`
`AGENTS.md,managed_config.toml,requirements.toml,agents,rules,mcp}`
(`ReservedTargets` in `internal/adapters/data.go`).

## Adapter behavior

- The provider wrapper sets `CODEX_HOME=~/.codex`, re-seeds the baselines into the
session-local Codex home, and imports repo-local control-plane files only as
masked, reviewed layers (`runtime/container/provider-wrapper.sh`,
`runtime/container/home-control-plane.sh`).
- Codex's own Linux `workspace-write` sandbox is pinned off on the managed path:
the current Codex Linux sandbox needs unprivileged user namespaces that are
unavailable inside the Tier 1 container.
Comment thread
omkhar marked this conversation as resolved.
- `~/.codex/rules/` is read-only by default; it becomes a session-local writable
copy only in explicit lower-assurance cases (see
[../../docs/adapter-control-planes.md](../../docs/adapter-control-planes.md#codex-rules-mutability)).
- Unsafe-argument policy (`reject_unsafe_codex_args` in
`runtime/container/provider-policy.sh`): the wrapper blocks
`--dangerously-bypass-approvals-and-sandbox`, `--full-auto`, `-a`/
`--ask-for-approval`, `--add-dir`, `--search`, `--remote`, `--enable`/
`--disable`, `--cd`, `--sandbox danger-full-access`, reserved `--config`
overrides, off-mode `--profile` values, and `app`/`app-server`/`cloud`/`mcp`/
`sandbox` subcommands outside the managed GUI path. These are rejected in
**every** mode including `breakglass`: `provider-wrapper.sh` re-checks arguments
(`WORKCELL_WRAPPER_CONTEXT=1`), so `container-smoke.sh` confirms breakglass
overrides still fail. Breakglass raises the sandbox floor, not the unsafe-flag
policy.
- Final branch publication stays on the host through `workcell publish-pr`, not
from inside the container session.

Codex CLI is Tier 1 when it runs fully inside the bounded runtime. App support is
only valid once it becomes a client of the same bounded executor.

## See also

- [../README.md](../README.md) — adapter index and common contract
- [../../docs/adapter-control-planes.md](../../docs/adapter-control-planes.md)
- [../../docs/invariants.md](../../docs/invariants.md)
- [../../docs/extending-adapters.md](../../docs/extending-adapters.md) — worked
contributor examples
Loading