docs: replace stale bash-first framing with Python-stdlib-first
The project started life as bash scripts and got rewritten to Python (documented in docs/research/bash-vs-python-vs-go.md). Several docs still carried the old "bash-first" framing — misleading for anyone reading them now (8.7k lines of Python vs. ~130 lines of bash, all in scripts/demo*.sh). - CLAUDE.md "What this is" + "Conventions": orchestrator is Python, posture is stdlib-first. - docs/prds/0010-cred-proxy.md, docs/research/manifest-format-and- grouping.md: quoted CLAUDE.md's old wording — re-quote. - docs/research/built-in-supervisor-design.md, landscape-containerized- claude.md, agent-sandbox-landscape.md, pipelock-assessment.md, network-egress-guard.md: drop "bash-first" claims about the project, keep accurate descriptions of external tools' bash usage. Leaves untouched: bash code-fence syntax in examples, README's literal `bash scripts/demo.sh` invocation (the demo IS bash), Claude Code's "Bash tool" references, IVIJL/devbox bash description (that project actually is bash), and the bash-vs-python-vs-go research note that records the rewrite decision. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -407,8 +407,8 @@ cannot smuggle a stolen token through this path.
|
||||
The proxy binary. Two real options:
|
||||
|
||||
- **Python (stdlib)** — `http.server` + `urllib`/`http.client`,
|
||||
no new pip packages. Matches CLAUDE.md's "bash-first, low-deps"
|
||||
posture. SSE pass-through is fiddly but doable.
|
||||
no new pip packages. Matches CLAUDE.md's "Python, stdlib-first,
|
||||
low-deps" posture. SSE pass-through is fiddly but doable.
|
||||
- **Go single binary** — cleaner SSE story, smaller runtime,
|
||||
one static binary in a scratch/distroless image. New build
|
||||
dependency.
|
||||
|
||||
@@ -197,7 +197,7 @@ differentiators:
|
||||
- Bottle / agent split (manifest layer above the isolation primitive).
|
||||
- gVisor auto-detection on Linux.
|
||||
|
||||
Ideas worth considering, without abandoning the bash-first / local-Docker
|
||||
Ideas worth considering, without abandoning the Python-stdlib-first / local-Docker
|
||||
stance:
|
||||
|
||||
1. **Per-use SSH key confirmation** (from litterbox). Even with
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Question
|
||||
|
||||
Can claude-bottle grow a built-in supervisor — TUI inventory plus PR-feedback routing — without breaking the per-bottle isolation model, and without departing from the bash-first, low-dependency posture?
|
||||
Can claude-bottle grow a built-in supervisor — TUI inventory plus PR-feedback routing — without breaking the per-bottle isolation model, and without departing from the Python-stdlib-first, low-dependency posture?
|
||||
|
||||
## Context
|
||||
|
||||
@@ -35,7 +35,7 @@ No new daemons. No new ports. No new credentials. ~100 lines.
|
||||
|
||||
Same data as `status`, rendered with auto-refresh and keyboard shortcuts that shell out to the existing `cli.py attach / stop / start` commands.
|
||||
|
||||
Library choice: prefer the stdlib `curses` module to stay bash-first-adjacent; fall back to `rich` or `textual` only if the curses path proves painful. Both `rich` and `textual` are single-purpose, pure-Python deps with no transitive bloat, but they are still new deps and per the project conventions warrant a deliberate decision.
|
||||
Library choice: prefer the stdlib `curses` module to stay stdlib-first; fall back to `rich` or `textual` only if the curses path proves painful. Both `rich` and `textual` are single-purpose, pure-Python deps with no transitive bloat, but they are still new deps and per the project conventions warrant a deliberate decision.
|
||||
|
||||
This is the Claude Squad / tmux-agent-status pattern, applied to bottles instead of tmux sessions. The whole category exists *because* a TUI is the lightweight shape that doesn't require what the SPA tier requires.
|
||||
|
||||
@@ -85,7 +85,7 @@ A few design defaults worth holding:
|
||||
|
||||
## Scope estimate
|
||||
|
||||
The full `status` / `watch` / `supervise` trio is plausibly ~500 lines of Python on top of the existing CLI, no new runtimes, no new daemons, no new ports, and (with `curses`) no new deps. That fits "Low dependencies by default. The project is bash-first; ask before adding new tools, runtimes, or package managers" without requiring an exception.
|
||||
The full `status` / `watch` / `supervise` trio is plausibly ~500 lines of Python on top of the existing CLI, no new runtimes, no new daemons, no new ports, and (with `curses`) no new deps. That fits "Low dependencies by default. The project is Python, stdlib-first; ask before adding new tools, runtimes, or package managers" without requiring an exception.
|
||||
|
||||
Phased: `status` first (purely additive, no design decisions), then `watch` (the design decisions are mostly UX, not architecture), then `supervise` (the only layer that introduces a new behavioral default and warrants a PRD of its own).
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ manifest merge.
|
||||
## Other surveyed projects
|
||||
|
||||
- **textcortex/claude-code-sandbox → spritz** — evolved toward
|
||||
Kubernetes-native multi-agent infra; not bash-first or local-Docker.
|
||||
Kubernetes-native multi-agent infra; not stdlib-first or local-Docker.
|
||||
Original sandbox repo is archived.
|
||||
- **trailofbits/claude-code-devcontainer** — devcontainer config for security
|
||||
audits; not a general agent launcher.
|
||||
@@ -58,7 +58,7 @@ None combine:
|
||||
Worth publishing. Differentiators that matter to the target audience (power
|
||||
users running parallel Claude Code sessions with distinct personas/tooling):
|
||||
|
||||
- The bash-first, low-dependency design — competitors are npm-based or
|
||||
- The Python-stdlib-first, low-dependency design — competitors are npm-based or
|
||||
Kubernetes-native.
|
||||
- Named agents with distinct skills and system prompts, not just language profiles.
|
||||
- SSH forwarding without key copying.
|
||||
|
||||
@@ -162,7 +162,7 @@ ruamel.yaml).
|
||||
|
||||
- **New runtime dependency.** The project today uses zero
|
||||
third-party Python packages for production code; YAML parsing
|
||||
pulls in PyYAML. (CLAUDE.md: "bash-first, low-deps by default.")
|
||||
pulls in PyYAML. (CLAUDE.md: "Python, stdlib-first; low-deps by default.")
|
||||
- YAML's footguns: indentation sensitivity, the Norway problem
|
||||
(`country: NO` → boolean False), implicit type coercion that's
|
||||
surprised non-trivial production projects.
|
||||
|
||||
@@ -369,7 +369,8 @@ services:
|
||||
- ALL
|
||||
```
|
||||
|
||||
In a bash-first project without Docker Compose, the equivalent is:
|
||||
In a project without Docker Compose, the equivalent (shell or Python orchestrator
|
||||
shelling out to `docker`) is:
|
||||
|
||||
```bash
|
||||
# create isolated network
|
||||
@@ -712,10 +713,11 @@ updates ipset without a container restart.
|
||||
### Tier 1 (v1, implement first): in-container iptables + ipset + dnsmasq
|
||||
|
||||
Adopt approach 2a with the dnsmasq complement from IVIJL/devbox. This is the
|
||||
pattern validated by Anthropic's own devcontainer, is bash-first, adds no new
|
||||
runtime dependencies (iptables and ipset are standard in the base Debian/Ubuntu
|
||||
image used by Claude Code; dnsmasq is a single `apt-get install`), and works
|
||||
on both macOS Docker Desktop and Linux Docker Engine.
|
||||
pattern validated by Anthropic's own devcontainer, configures cleanly from
|
||||
plain shell + standard system packages, adds no new runtime dependencies
|
||||
(iptables and ipset are standard in the base Debian/Ubuntu image used by
|
||||
Claude Code; dnsmasq is a single `apt-get install`), and works on both
|
||||
macOS Docker Desktop and Linux Docker Engine.
|
||||
|
||||
Key PRD scope for this work:
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ its own scanner. This avoids a second container but introduces the
|
||||
the proxy run in the same failure domain.
|
||||
|
||||
The sidecar topology is recommended for claude-bottle because it matches
|
||||
the existing bash-orchestrated multi-container model (the SSH key agent
|
||||
the existing Python-orchestrated multi-container model (the SSH key agent
|
||||
already uses a separate process), keeps pipelock outside the agent's kill
|
||||
reach, and avoids the `--best-effort` issue on macOS Docker Desktop.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user