docs: rename CLAUDE.md to AGENTS.md and rebrand provider-agnostic
test / unit (pull_request) Successful in 28s
test / integration (pull_request) Successful in 40s
test / unit (push) Successful in 31s
test / integration (push) Successful in 44s

Delete CLAUDE.md in favor of AGENTS.md as the orientation doc, rebrand
the project from Codex-bottle to provider-agnostic bot-bottle, and
repoint every CLAUDE.md reference across PRDs, research notes, the
implementer agent example, and the yaml_subset comment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit was merged in pull request #93.
This commit is contained in:
2026-05-28 20:32:35 -04:00
parent e641bacf2d
commit 18e3b62b72
13 changed files with 21 additions and 72 deletions
+6 -6
View File
@@ -1,16 +1,16 @@
# Codex-bottle # bot-bottle
## What this is ## What this is
Codex-bottle spins up an isolated container for running Codex with a bot-bottle spins up an isolated container for running AI coding agents with a
curated set of skills and env vars. The point is to run Codex with broad curated set of skills and env vars. The point is to run agents with broad
permissions inside a sandbox, so a misbehaving agent cannot reach the host. permissions inside a sandbox, so a misbehaving agent cannot reach the host.
A Python CLI (entry point `cli.py`, package `bot_bottle/`) orchestrates A Python CLI (entry point `cli.py`, package `bot_bottle/`) orchestrates
the container lifecycle and the copying of skills and env vars into it. the container lifecycle and the copying of skills and env vars into it.
## Goals ## Goals
- Minimize risk of running Codex with full permissions - Minimize risk of running agents with full permissions
- Allow me to easily spin up agent tasks in parallel - Allow me to easily spin up agent tasks in parallel
- Create isolated, well defined, easily updated, shareable agents - Create isolated, well defined, easily updated, shareable agents
@@ -23,9 +23,9 @@ the container lifecycle and the copying of skills and env vars into it.
## Repository layout ## Repository layout
- `README.md` — short public-facing description. - `README.md` — short public-facing description.
- `AGENTS.md` — this file, orientation for future Codex sessions. - `AGENTS.md` — this file, orientation for future agent sessions.
- `.gitignore` — OS junk. - `.gitignore` — OS junk.
- `Codex-bottle.json` — manifest of named agents (env / skills / prompt - `bot-bottle.json` legacy manifest of named agents (env / skills / prompt
per agent), consumed by `cli.py`. See "Manifest" under per agent), consumed by `cli.py`. See "Manifest" under
"Intended design". "Intended design".
- `docs/INDEX.md` — pointer to the research notes. - `docs/INDEX.md` — pointer to the research notes.
-51
View File
@@ -1,51 +0,0 @@
# bot-bottle
## What this is
bot-bottle spins up an isolated container for running Claude Code with a
curated set of skills and env vars. The point is to run Claude with broad
permissions inside a sandbox, so a misbehaving agent cannot reach the host.
A Python CLI (entry point `cli.py`, package `bot_bottle/`) orchestrates
the container lifecycle and the copying of skills and env vars into it.
## Goals
- Minimize risk of running claude with full permissions
- Allow me to easily spin up agent tasks in parallel
- Create isolated, well defined, easily updated, shareable agents
## Non-goals
- Communicating between agents directly
- Self hosted VMs (v1 uses local Docker containers, not VMs)
- Advanced agent auditing (lean on git history for auditing)
## Repository layout
- `README.md` — short public-facing description.
- `CLAUDE.md` — this file, orientation for future Claude sessions.
- `.gitignore` — OS junk.
- `bot-bottle.json` — manifest of named agents (env / skills / prompt
per agent), consumed by `cli.py`. See "Manifest" under
"Intended design".
- `docs/INDEX.md` — pointer to the research notes.
- `docs/prds/` — product requirement docs.
- `docs/research/` — research notes (empty for now, kept tracked via `.gitkeep`).
## Conventions
- Product requirement docs live in `docs/prds/`.
- Research notes live in `docs/research/`.
- Low dependencies by default. The project is Python, stdlib-first (no
runtime pip dependencies in the package itself; the only language
runtime is the Python 3.13 used by the CLI + sidecars). Ask before
adding new tools, runtimes, or package managers.
- Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/):
`<type>[(scope)][!]: <description>`, where `<type>` is one of `feat`, `fix`,
`docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`.
A `commit-msg` hook in `.githooks/` enforces this. Activate it once per clone
with `git config core.hooksPath .githooks`.
## When you're unsure
Ask. Default to drafting in chat over editing files when the request is ambiguous.
+1 -1
View File
@@ -6,7 +6,7 @@ top-level keys; values are strings / ints / bools / null / lists /
nested dicts; no anchors, no multi-line block scalars, no tags, no nested dicts; no anchors, no multi-line block scalars, no tags, no
implicit type coercion gotchas). A real YAML library is a much implicit type coercion gotchas). A real YAML library is a much
larger dependency surface than we need. The project's stdlib-only larger dependency surface than we need. The project's stdlib-only
stance (CLAUDE.md) is the load-bearing reason; the safety stance (AGENTS.md) is the load-bearing reason; the safety
properties — no Norway problem, no surprise date/octal coercion — properties — no Norway problem, no surprise date/octal coercion —
are the bonus. are the bonus.
+1 -1
View File
@@ -415,7 +415,7 @@ cannot smuggle a stolen token through this path.
The proxy binary. Two real options: The proxy binary. Two real options:
- **Python (stdlib)** — `http.server` + `urllib`/`http.client`, - **Python (stdlib)** — `http.server` + `urllib`/`http.client`,
no new pip packages. Matches CLAUDE.md's "Python, stdlib-first, no new pip packages. Matches AGENTS.md's "Python, stdlib-first,
low-deps" posture. SSE pass-through is fiddly but doable. low-deps" posture. SSE pass-through is fiddly but doable.
- **Go single binary** — cleaner SSE story, smaller runtime, - **Go single binary** — cleaner SSE story, smaller runtime,
one static binary in a scratch/distroless image. New build one static binary in a scratch/distroless image. New build
+1 -1
View File
@@ -24,7 +24,7 @@ no `bottles/` subdirectory, period.
The YAML we accept is bounded (flat keys → strings, lists, simple The YAML we accept is bounded (flat keys → strings, lists, simple
nested dicts), so the parser is hand-rolled and stdlib-only — no nested dicts), so the parser is hand-rolled and stdlib-only — no
PyYAML dependency. The project's "low deps by default" stance PyYAML dependency. The project's "low deps by default" stance
(CLAUDE.md) stays intact. (AGENTS.md) stays intact.
## Problem ## Problem
+1 -1
View File
@@ -70,4 +70,4 @@ It's still the wrong placement for five reasons:
- PRD 0014 — cred-proxy block remediation. - PRD 0014 — cred-proxy block remediation.
- PRD 0015 — pipelock block remediation. - PRD 0015 — pipelock block remediation.
- PRD 0016 — capability block remediation. - PRD 0016 — capability block remediation.
- `CLAUDE.md` — project non-goal on agent-to-agent communication; this PRD stays on the human→agent side of that line. - `AGENTS.md` — project non-goal on agent-to-agent communication; this PRD stays on the human→agent side of that line.
+1 -1
View File
@@ -201,7 +201,7 @@ The feature is **done** when all of the following ship:
smolmachines-capable host. The suite is updated to skip cleanly smolmachines-capable host. The suite is updated to skip cleanly
on hosts that can't reach smolmachines (same shape as the on hosts that can't reach smolmachines (same shape as the
existing `GITEA_ACTIONS == "true"` skip), not to fail. existing `GITEA_ACTIONS == "true"` skip), not to fail.
- README + `CLAUDE.md` updated to document the env-var selection, - README + `AGENTS.md` updated to document the env-var selection,
the macOS-only scope for v1, and the `smolvm` install the macOS-only scope for v1, and the `smolvm` install
prerequisite. prerequisite.
+3 -3
View File
@@ -123,7 +123,7 @@ The feature is **done** when all of the following ship:
- Integration: existing PRD 0001 / 0008 / 0013 / 0017 - Integration: existing PRD 0001 / 0008 / 0013 / 0017
integration tests run against the bundle and pass. integration tests run against the bundle and pass.
- Integration: PRD 0022 sandbox-escape suite stays green. - Integration: PRD 0022 sandbox-escape suite stays green.
- `CLAUDE.md` updated to describe the bundle and the - `AGENTS.md` updated to describe the bundle and the
daemons-inside layout. daemons-inside layout.
## Non-goals ## Non-goals
@@ -173,7 +173,7 @@ The feature is **done** when all of the following ship:
- Test updates: unit and integration tests that probe the - Test updates: unit and integration tests that probe the
four-container shape get rewritten against the one-container four-container shape get rewritten against the one-container
shape. shape.
- README + CLAUDE.md doc updates. - README + AGENTS.md doc updates.
### Out of scope ### Out of scope
@@ -399,7 +399,7 @@ rewrite.
PRD 0022 stays green. PRD 0022 stays green.
5. **Docs + flag removal.** Flip the default, remove the 5. **Docs + flag removal.** Flip the default, remove the
feature flag, delete `Dockerfile.{egress,git-gate,supervise}`, feature flag, delete `Dockerfile.{egress,git-gate,supervise}`,
update README + CLAUDE.md. update README + AGENTS.md.
## Open questions ## Open questions
@@ -130,7 +130,7 @@ preserves this format.
**Pros** **Pros**
- Zero migration cost. - Zero migration cost.
- Stdlib parser; no new dependency. The project's CLAUDE.md sets - Stdlib parser; no new dependency. The project's AGENTS.md sets
"low dependencies by default" as a guideline. "low dependencies by default" as a guideline.
- Stable, predictable parse semantics. No type-coercion gotchas. - Stable, predictable parse semantics. No type-coercion gotchas.
- Tooling everywhere — IDE support, linters, jq. - Tooling everywhere — IDE support, linters, jq.
@@ -162,7 +162,7 @@ ruamel.yaml).
- **New runtime dependency.** The project today uses zero - **New runtime dependency.** The project today uses zero
third-party Python packages for production code; YAML parsing third-party Python packages for production code; YAML parsing
pulls in PyYAML. (CLAUDE.md: "Python, stdlib-first; low-deps by default.") pulls in PyYAML. (AGENTS.md: "Python, stdlib-first; low-deps by default.")
- YAML's footguns: indentation sensitivity, the Norway problem - YAML's footguns: indentation sensitivity, the Norway problem
(`country: NO` → boolean False), implicit type coercion that's (`country: NO` → boolean False), implicit type coercion that's
surprised non-trivial production projects. surprised non-trivial production projects.
+1 -1
View File
@@ -734,7 +734,7 @@ Key PRD scope for this work:
- Add a dnsmasq configuration step: install dnsmasq in the Dockerfile, configure - Add a dnsmasq configuration step: install dnsmasq in the Dockerfile, configure
it to serve only allowlisted names, and set `--dns 127.0.0.1` in `docker run`. it to serve only allowlisted names, and set `--dns 127.0.0.1` in `docker run`.
- Block outbound UDP port 53 to non-dnsmasq resolvers in the iptables rules. - Block outbound UDP port 53 to non-dnsmasq resolvers in the iptables rules.
- Document the `--cap-add` changes in `CLAUDE.md` under security. - Document the `--cap-add` changes in `AGENTS.md` under security.
### Tier 2 (v2, higher isolation): smokescreen sidecar ### Tier 2 (v2, higher isolation): smokescreen sidecar
+2 -2
View File
@@ -486,7 +486,7 @@ plausibly run pipelock on the host and skip Docker entirely.
### Where bot-bottle does work pipelock does not ### Where bot-bottle does work pipelock does not
The redundancy argument breaks down once the actual goals from The redundancy argument breaks down once the actual goals from
`CLAUDE.md` are enumerated: `AGENTS.md` are enumerated:
1. **Filesystem isolation that survives a misbehaving agent.** Docker 1. **Filesystem isolation that survives a misbehaving agent.** Docker
containers give an entire kernel-mediated mount namespace and a separate containers give an entire kernel-mediated mount namespace and a separate
@@ -584,7 +584,7 @@ some other way. That is not the use case the project was built for.
2. **Does the pipelock Docker image introduce supply-chain risk?** 2. **Does the pipelock Docker image introduce supply-chain risk?**
Pulling `ghcr.io/luckypipewrench/pipelock:latest` brings in a binary Pulling `ghcr.io/luckypipewrench/pipelock:latest` brings in a binary
from an unvetted source. Pinning by digest (as the CLAUDE.md recommends from an unvetted source. Pinning by digest (as the AGENTS.md recommends
for supply-chain hygiene) and building from source are both options. for supply-chain hygiene) and building from source are both options.
3. **What is the actual DLP false-positive rate for the secrets bot-bottle 3. **What is the actual DLP false-positive rate for the secrets bot-bottle
@@ -223,7 +223,7 @@ scope and the manifest example carries `/Users/didericis` paths:
right v2. right v2.
3. **Firecracker only if** bot-bottle's deployment target settles on 3. **Firecracker only if** bot-bottle's deployment target settles on
self-hosted Linux, not laptops — at which point the "non-goal: self-hosted Linux, not laptops — at which point the "non-goal:
self-hosted VMs" line in `CLAUDE.md` flips and the project's self-hosted VMs" line in `AGENTS.md` flips and the project's
identity changes. identity changes.
The pipelock egress design ports across all of these, so none of this The pipelock egress design ports across all of these, so none of this
+1 -1
View File
@@ -8,7 +8,7 @@ skills:
--- ---
You are a feature-implementation agent running inside an ephemeral You are a feature-implementation agent running inside an ephemeral
bot-bottle sandbox. Treat the workspace's CLAUDE.md as bot-bottle sandbox. Treat the workspace's AGENTS.md as
authoritative for coding standards, test commands, and project authoritative for coding standards, test commands, and project
conventions. Implement only what your task prompt asks for — do not conventions. Implement only what your task prompt asks for — do not
refactor adjacent code, invent follow-ups, or relax the PRD's refactor adjacent code, invent follow-ups, or relax the PRD's