Files
simonandClaude Opus 5.5 0e21730b9f Document coding agents and give them a sandbox image
Agents work on this repository in the agent-envs sandbox: a container
whose only way out is an egress proxy with an allowlist, which also adds
the Gitea bot token. docs/contributing/agents.md covers setting it up
for Politrack (1Password item, .env, commit identity), what it can reach
and its limits; AGENTS.md tells agents how to recognise the sandbox and
behave in it.

backend/tests/Dockerfile.debian gains a `sandbox` target: the agent-envs
agent image plus the backend's dependencies from Debian packages, the
same list as the PyPI-free test image (still the default target). The
sandbox runs `pytest` without PyPI, which the owner's PC can't reach. A
new invariant in AGENTS.md keeps that list in step with pyproject.toml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 23:59:01 +01:00

72 lines
4.1 KiB
Markdown

# Coding agents
Coding agents (Claude Code) work on this repository in a sandbox from
[agent-envs](https://git.disi.dev/AICode/agent-envs): a Linux container whose only way out is an
egress proxy with an allowlist. The proxy also adds the Gitea token to requests, so the agent never
holds it. This page covers setting that up for Politrack; [AGENTS.md](../../AGENTS.md) is what the
agent itself reads.
## Setup
1. Prepare the computer once, as described in agent-envs'
[docs/setup.md](https://git.disi.dev/AICode/agent-envs/src/branch/main/docs/setup.md): Docker, the
registry login, the 1Password CLI and, for VS Code, the Dev Containers settings.
2. In 1Password's `Agents` vault, create an API Credential item `gitea-politics-tracking` with the
`username` and an access token (`credential`) of a Gitea bot user. Make that user a collaborator
on `AIPlayground/politics-tracking` only, with write access. Protect `main` so the agent works
through pull requests.
3. In agent-envs, `cp projects/politics-tracking/.env.example projects/politics-tracking/.env` and set
`WORKSPACE` to this checkout.
4. Set the commit identity in this checkout, once. The sandbox uses the same `.git`, so its commits
get it too:
```bash
git config user.name "Simon Diesenreiter"
git config user.email simon@disi.dev
```
5. Start a session from anywhere: `agent politics-tracking` (Claude in the terminal) or
`agent politics-tracking code` (VS Code attached to the sandbox).
## What the sandbox can reach
| What | Hosts | For |
|---|---|---|
| Claude Code | `api.anthropic.com`, `claude.ai`, `platform.claude.com`, `console.anthropic.com` | the agent itself |
| Gitea | `git.disi.dev` (DELETE requests blocked) | push, pull requests through the API, as the bot user |
| Packages | `pypi.org`, `files.pythonhosted.org`, `registry.npmjs.org` | dependencies (see the limits below) |
| Sources | Parlament, data.gv.at, RTR, Rechnungshof, Justiz, Bundeskanzleramt, OTS, the European Parliament, data.europa.eu, Wikidata, German Wikipedia | capturing fixtures, short test runs |
| VS Code | the extension marketplace | installing the Claude Code extension in the sandbox |
The exact list is in agent-envs, `projects/politics-tracking/egress.yaml`. Media sites and social
networks are not included; add a host there when a task needs it, and only one that the source's
legal checklist ([adapters.md](adapters.md#0-before-writing-code-the-legal-checklist)) allows.
Everything else, and anything that isn't HTTP(S) (SSH, database connections), is blocked.
## The sandbox image
Politrack runs in its own sandbox image: the agent-envs agent image plus the backend's dependencies
as Debian packages. It is the `sandbox` target of
[backend/tests/Dockerfile.debian](../../backend/tests/Dockerfile.debian), the same package list as the
[PyPI-free test image](testing.md#without-pypi-access), so `cd backend && python3 -m pytest` works in
the sandbox without downloading anything. agent-envs builds it from this checkout at every start;
unchanged, that takes seconds from the cache.
Keep the list in step with `backend/pyproject.toml` (AGENTS.md says so too). Debian doesn't package
`procrastinate`, `mcp` and `ruff`, so the workers, the MCP server and linting don't run in the
sandbox.
## Limits
- **No Docker** in the sandbox: no compose stack.
- **No database:** the compose `db` on the host isn't reachable from the sandbox, so adapter runs that
write claims and [the database checks](testing.md#against-a-real-database) have to run outside it.
- **On the owner's PC**, PyPI and npm downloads fail inside the sandbox too (the same network filter;
see AGENTS.md): no `pip install` of new packages and no `npm install` for the frontend there.
- Claude's memory in the sandbox is separate from the one on the host. Rules that must always hold
belong in AGENTS.md, not in memory.
## Changing what the agent can reach or knows
All of it lives in agent-envs, not in this repository: hosts in `projects/politics-tracking/egress.yaml`,
kits (Gitea, Python, Node, VS Code) in `projects/politics-tracking/compose.yaml`, the token in
1Password. Instructions for the agent stay in this repository's AGENTS.md.