Skip to content

refactor: split constant agent compose entries into sandcat/compose-agent.yml - #99

Open
shejnowicz wants to merge 6 commits into
masterfrom
refactor/22-split-compose-constants
Open

refactor: split constant agent compose entries into sandcat/compose-agent.yml#99
shejnowicz wants to merge 6 commits into
masterfrom
refactor/22-split-compose-constants

Conversation

@shejnowicz

Copy link
Copy Markdown
Collaborator

Closes #22.

Summary

Moves the agent service's constant (non-user-editable) entries out of the user-facing `compose-all.yml` template into a new included `sandcat/compose-agent.yml`: `build`, `security_opt: no-new-privileges`, `network_mode: "service:wg-client"`, the three constant mounts (`agent-home`, `mitmproxy-config:ro`, `wg-runtime:ro`), `command`, `depends_on`, and the `agent-home` volume declaration.

`compose-all.yml` now contains only the include list and the user-customizable `services.agent` section (workspace mounts, agent-config mounts, commented `.git`/`.idea` knobs, shared caches, environment) — the parts users are told to edit. Generated file shrinks and the security-critical constants can no longer be accidentally deleted while uncommenting a mount.

Mechanism

Docker Compose's include-override merge — the including file's partial `services.agent` merges over the full definition in the included file. This is the same mechanism every generated sandcat project already exercises: `compose-all.yml` has long partial-overridden `services.mitmproxy` (the `.sandcat:/config/project:ro` mount) over `compose-proxy.yml`. No new Compose version requirement.

`build.context` changes `.` → `..` because included-file paths resolve relative to the included file's directory (`sandcat/`) — same convention `compose-proxy.yml` already uses.

What does NOT change

  • Entry point stays `-f compose-all.yml` everywhere (CLI, VS Code `dockerComposeFile`, JetBrains).
  • Zero changes to `cli/lib/.bash` / `cli/libexec/` — all yq helpers keep targeting `compose-all.yml` and create keys on demand.
  • Existing generated projects keep working unchanged; the new layout arrives on re-init (verified: re-init on an old project produces a clean new layout with no duplicate constants).

Test plan

  • Full bats surface green (14 suites, 361 tests), including `regression.bats` — which asserts on `docker compose config` (merged effective output) and passes byte-for-byte untouched
  • New regression assertions added for the moved constants (`security_opt`, `depends_on`, `command`, `wg-runtime` ro mount) so a silently-dropped include merge can't pass CI
  • Effective-config identity verified: projects generated with pre-split and post-split CLI across 4 combos (claude/jetbrains, claude/vscode+java caches, cursor/vscode, claude/none) produce byte-identical `docker compose config` output
  • Hands-on integration on a real stack: `up -d --build` succeeds (proves the re-based `build.context: ..` — Dockerfile.app COPY paths resolve), `NoNewPrivs: 1` in the agent, `sudo` blocked, `curl https://github.com\` → 200 through the proxy, clean teardown
  • One environmental finding during testing: `sandcat restart-proxy` orphans the agent — that is pre-existing sandcat restart-proxy orphans the running agent, breaking all networking #69 (fix in still-open fix(cli): restart the agent after restart-proxy so its netns re-links to wg-client #93), reproduced identically on master; confirmed orthogonal by manual `docker compose restart agent` → networking restored

🤖 Generated with Claude Code

https://claude.ai/code/session_01DFCiFbv1Cpr7yzCU8ftvzZ

shejnowicz and others added 6 commits August 17, 2026 11:15
Move the agent service's constant entries (build, security_opt,
network_mode, constant mounts, command, depends_on, agent-home volume)
from the user-facing compose-all.yml template into a new included
sandcat/compose-agent.yml, using the include-override merge mechanism
that generated projects already exercise for the mitmproxy settings
mount. compose-all.yml shrinks to the include list + a services.agent
stub that sandcat init populates with user-customizable entries.

Zero CLI bash-logic changes; regression tests assert on docker compose
config (merged output) and prove behavior identity.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFCiFbv1Cpr7yzCU8ftvzZ
…e-agent.yml (#22)

Move the agent service's constant (non-user-editable) entries — build
context/dockerfile, security_opt, network_mode, the three base volume
mounts, command, and depends_on — out of compose-all.yml into a new
included sandcat/compose-agent.yml. compose-all.yml now only includes
it and leaves services.agent: {} for the CLI's user-customizable
volumes/environment to merge over, mirroring the existing
compose-proxy.yml include-override pattern used for mitmproxy.

Re-point dns_conf_contract.bats's wg-runtime/agent assertion at the
new sandcat/compose-agent.yml, since compose-all.yml's services.agent
section no longer carries that mount directly.
- Added sandcat/compose-agent.yml to template file enumeration (line 23)
- Updated security-architecture bullet to reference sandcat/compose-agent.yml
  where constant build/network/mount settings now live
- Clarified that compose-all.yml contains only user-customizable entries merged
  over the constant base

Closes #22

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFCiFbv1Cpr7yzCU8ftvzZ
The security-architecture section attributed compose-all.yml's
user-editable agent config bind-mounts to compose-agent.yml, and the
file enumeration listed compose-agent.yml under the wrong directory
with a "fine-tune per project" caveat that contradicts its purpose as
the constant, non-user-editable agent base.
security_opt, depends_on, command, and the wg-runtime ro mount now reach
the container only via the compose-agent.yml include merge; a silently
dropped merge would previously pass CI since only working_dir and
network_mode were checked on the effective config.
These are working documents for the split-compose-constants task, not
project documentation, and shouldn't ship as part of the branch.
@adamw

adamw commented Aug 25, 2026

Copy link
Copy Markdown
Member

When the user re-generates sandcat's config, is the compose-all.yml preserved or overwritten?

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.

refactor: Move all "constant" compose entries to separate file

2 participants