refactor!: rename project to bot-bottle
Assisted-by: Codex
This commit is contained in:
@@ -15,7 +15,7 @@ down`. Logs come from `docker compose logs` and land in a single file
|
||||
per instance, so reading what happened in a session is one `less`
|
||||
away.
|
||||
|
||||
State for each instance (`~/.claude-bottle/state/<slug>/`) becomes a
|
||||
State for each instance (`~/.bot-bottle/state/<slug>/`) becomes a
|
||||
self-describing folder:
|
||||
|
||||
```
|
||||
@@ -34,7 +34,7 @@ together fully describe the container topology.
|
||||
|
||||
Today `start` builds each sidecar (`pipelock`, `egress`, `git-gate`,
|
||||
`supervise`) and the agent container with a chain of individual SDK
|
||||
calls in `claude_bottle/backend/docker/launch.py`:
|
||||
calls in `bot_bottle/backend/docker/launch.py`:
|
||||
|
||||
- A per-sidecar `Docker{Sidecar}.start()` method does
|
||||
`docker create` → `docker cp` (stage files) → `docker network
|
||||
@@ -50,7 +50,7 @@ This is fine, but it has three rough edges:
|
||||
|
||||
2. **Logs are scattered.** Each container's logs sit in Docker's per-
|
||||
container journal. To debug a session post-mortem you have to
|
||||
remember to run `docker logs claude-bottle-pipelock-<slug>` etc.
|
||||
remember to run `docker logs bot-bottle-pipelock-<slug>` etc.
|
||||
before the containers age out, and there's no merged view.
|
||||
|
||||
3. **Teardown is bespoke.** Each sidecar's `stop()` is its own
|
||||
@@ -62,14 +62,14 @@ project name per environment, merged logs, atomic up/down.
|
||||
|
||||
## Goals / Success Criteria
|
||||
|
||||
1. `claude-bottle start <agent>` writes
|
||||
`~/.claude-bottle/state/<slug>/docker-compose.yml` and brings the
|
||||
1. `bot-bottle start <agent>` writes
|
||||
`~/.bot-bottle/state/<slug>/docker-compose.yml` and brings the
|
||||
project up with `docker compose -p <project> up`.
|
||||
2. The compose file is the source of truth for the container
|
||||
topology — every sidecar that runs is declared as a `services:`
|
||||
entry, every network is a `networks:` entry, every bind mount is
|
||||
a `volumes:` entry.
|
||||
3. `~/.claude-bottle/state/<slug>/compose.log` contains the full
|
||||
3. `~/.bot-bottle/state/<slug>/compose.log` contains the full
|
||||
merged stdout/stderr of every service for the session, in
|
||||
`docker compose logs --no-color` format.
|
||||
4. `metadata.json` records the compose project name alongside the
|
||||
@@ -79,7 +79,7 @@ project name per environment, merged logs, atomic up/down.
|
||||
5. Session teardown is `docker compose -p <project> down`. The
|
||||
existing per-sidecar `stop()` lifecycle methods come out.
|
||||
6. The `cleanup` CLI uses `docker compose ls` (filtered to
|
||||
`claude-bottle-*` projects) instead of name-prefix scans across
|
||||
`bot-bottle-*` projects) instead of name-prefix scans across
|
||||
`docker ps -a` and `docker network ls`.
|
||||
7. The existing remediation flows (`pipelock-block`,
|
||||
`egress-block`, `capability-block`) keep working without
|
||||
@@ -95,7 +95,7 @@ project name per environment, merged logs, atomic up/down.
|
||||
implementation detail of the Docker backend.
|
||||
- **Replacing the backend abstraction (PRD 0003).** `Backend` stays
|
||||
abstract; only the Docker implementation changes.
|
||||
- **A long-lived "claude-bottle daemon."** Each `start` invocation
|
||||
- **A long-lived "bot-bottle daemon."** Each `start` invocation
|
||||
still owns a single compose project for the lifetime of the
|
||||
session. No persistent service.
|
||||
- **Image pre-building.** Compose's `build:` directive triggers
|
||||
@@ -109,7 +109,7 @@ project name per environment, merged logs, atomic up/down.
|
||||
|
||||
### In scope
|
||||
|
||||
- New module `claude_bottle/backend/docker/compose.py` that renders a
|
||||
- New module `bot_bottle/backend/docker/compose.py` that renders a
|
||||
compose dict from a `BottlePlan` and writes it to
|
||||
`state/<slug>/docker-compose.yml`.
|
||||
- `DockerBackend.start` rewritten to:
|
||||
@@ -118,7 +118,7 @@ project name per environment, merged logs, atomic up/down.
|
||||
into host paths under `state/<slug>/`.
|
||||
3. Render + write the compose file.
|
||||
4. Exec `docker compose -p <project> up -d`.
|
||||
5. `docker attach claude-bottle-<slug>` for the agent's TTY.
|
||||
5. `docker attach bot-bottle-<slug>` for the agent's TTY.
|
||||
6. On exit: `docker compose -p <project> logs --no-color`
|
||||
→ `state/<slug>/compose.log`, then `docker compose -p
|
||||
<project> down --volumes`.
|
||||
@@ -134,12 +134,12 @@ project name per environment, merged logs, atomic up/down.
|
||||
|
||||
### Out of scope
|
||||
|
||||
- Changing the manifest layer (`claude_bottle/manifest.py`,
|
||||
- Changing the manifest layer (`bot_bottle/manifest.py`,
|
||||
`egress.py`'s plan dataclasses, `pipelock.py`'s plan dataclasses).
|
||||
- Changing the agent's runtime contract (proxy env vars, CA bundle
|
||||
paths, current-config mount path).
|
||||
- Changing audit-log shape or location (
|
||||
`~/.claude-bottle/audit/<component>-<slug>.log` stays).
|
||||
`~/.bot-bottle/audit/<component>-<slug>.log` stays).
|
||||
- Changing the MCP server's tool list or wire format.
|
||||
- Dropping the `--rm` semantics for the agent: the agent container
|
||||
is still ephemeral; compose's `down --volumes` handles cleanup.
|
||||
@@ -148,7 +148,7 @@ project name per environment, merged logs, atomic up/down.
|
||||
|
||||
### Project name
|
||||
|
||||
`compose_project = f"claude-bottle-{slug}"`. The slug stays the
|
||||
`compose_project = f"bot-bottle-{slug}"`. The slug stays the
|
||||
existing `slugify(agent_name)-<5-char-random-base36>` from
|
||||
`bottle_state.py`. Compose adds its own prefix to networks
|
||||
(`<project>_<network>`) and to default container names — which is
|
||||
@@ -163,29 +163,29 @@ an explicit `container_name:` matching today's pattern:
|
||||
```yaml
|
||||
services:
|
||||
pipelock:
|
||||
container_name: claude-bottle-pipelock-<slug>
|
||||
container_name: bot-bottle-pipelock-<slug>
|
||||
egress:
|
||||
container_name: claude-bottle-egress-<slug>
|
||||
container_name: bot-bottle-egress-<slug>
|
||||
# ...
|
||||
```
|
||||
|
||||
This keeps the dashboard's container-discovery output stable for
|
||||
operators who've memorized the names. The compose project name
|
||||
(`claude-bottle-<slug>`) is the only new identifier.
|
||||
(`bot-bottle-<slug>`) is the only new identifier.
|
||||
|
||||
### Networks
|
||||
|
||||
The two existing networks (`claude-bottle-net-<slug>` internal +
|
||||
`claude-bottle-egress-<slug>` upstream-bridge) become compose
|
||||
The two existing networks (`bot-bottle-net-<slug>` internal +
|
||||
`bot-bottle-egress-<slug>` upstream-bridge) become compose
|
||||
networks:
|
||||
|
||||
```yaml
|
||||
networks:
|
||||
internal:
|
||||
name: claude-bottle-net-<slug>
|
||||
name: bot-bottle-net-<slug>
|
||||
internal: true
|
||||
egress:
|
||||
name: claude-bottle-egress-<slug>
|
||||
name: bot-bottle-egress-<slug>
|
||||
```
|
||||
|
||||
Each service's `networks:` list mirrors today's wiring.
|
||||
@@ -238,7 +238,7 @@ sidecars that exist.
|
||||
### Logging
|
||||
|
||||
`docker compose up -d` starts everything detached. The agent is
|
||||
attached for the user's TTY via `docker attach claude-bottle-
|
||||
attached for the user's TTY via `docker attach bot-bottle-
|
||||
<slug>`. Sidecars stream into Docker's per-container journals
|
||||
during the session, exactly as today, and `docker compose logs -f`
|
||||
gives a merged tail if the user wants it (the dashboard can shell
|
||||
@@ -265,7 +265,7 @@ Add one field; everything else is unchanged.
|
||||
"agent_name": "implementer",
|
||||
"cwd": "/Users/.../some-project",
|
||||
"started_at": "2026-05-25T20:13:04Z",
|
||||
"compose_project": "claude-bottle-implementer-a7k3f"
|
||||
"compose_project": "bot-bottle-implementer-a7k3f"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -291,13 +291,13 @@ After this PRD:
|
||||
### Cleanup CLI
|
||||
|
||||
`./cli.py cleanup` switches from "list every container with prefix
|
||||
`claude-bottle-` and every network with prefix `claude-bottle-net-`
|
||||
or `claude-bottle-egress-`" to:
|
||||
`bot-bottle-` and every network with prefix `bot-bottle-net-`
|
||||
or `bot-bottle-egress-`" to:
|
||||
|
||||
1. `docker compose ls --all --format json` → filter to projects
|
||||
whose name starts with `claude-bottle-`.
|
||||
whose name starts with `bot-bottle-`.
|
||||
2. For each: `docker compose -p <project> down --volumes`.
|
||||
3. Reap any state dirs under `~/.claude-bottle/state/` whose
|
||||
3. Reap any state dirs under `~/.bot-bottle/state/` whose
|
||||
`compose_project` no longer appears in `compose ls`.
|
||||
|
||||
Strays from pre-compose code-paths can be mopped up by keeping the
|
||||
@@ -313,7 +313,7 @@ existing prefix scan as a fallback for one release.
|
||||
2. **How does `claude` reach the agent's TTY?** Decided: keep
|
||||
today's `docker exec -it` model. Agent runs `sleep infinity`
|
||||
under compose; `DockerBottle.exec_claude` runs
|
||||
`docker exec -it claude-bottle-<slug> claude ...` exactly like
|
||||
`docker exec -it bot-bottle-<slug> claude ...` exactly like
|
||||
today. Compose owns the lifecycle (so `compose logs` includes
|
||||
the agent's stdout, `compose down` tears it down), but the
|
||||
user-facing exec model is unchanged. Rejected `docker attach`
|
||||
@@ -332,8 +332,8 @@ existing prefix scan as a fallback for one release.
|
||||
|
||||
5. **Image build caching.** `build:` in compose rebuilds on first
|
||||
`up` unless the image is already tagged. The per-sidecar images
|
||||
(`claude-bottle-pipelock`, `claude-bottle-egress`,
|
||||
`claude-bottle-git-gate`, `claude-bottle-supervise`) should
|
||||
(`bot-bottle-pipelock`, `bot-bottle-egress`,
|
||||
`bot-bottle-git-gate`, `bot-bottle-supervise`) should
|
||||
stay tagged on the daemon between runs so we don't rebuild on
|
||||
every start. Verify compose's behavior matches.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user