Commit Graph

19 Commits

Author SHA1 Message Date
didericis 3f4708f970 docs(demo): add end-to-end demo with recorded GIF
test / unit (push) Successful in 22s
test / integration (push) Successful in 31s
Squashes the demo-build arc: initial GIF + scripts, refactor to drive
recording through real cli.py, theme/timing tweaks, and the switch to
prompt-driven probes.
2026-05-13 15:33:28 -04:00
didericis 30d92bef48 docs: drop ssh from README/example, supersede PRD 0007 (PRD 0009)
test / unit (pull_request) Successful in 13s
test / integration (pull_request) Successful in 21s
- README architecture diagram drops the socat/ssh image box and
  the agent's ~/.ssh/config; the prose-bullets section drops the
  ssh image; the manifest example swaps `ssh:` for `git:` so
  someone copy-pasting it picks up the new shape.
- claude-bottle.example.json: `default` bottle's `"ssh": []` is
  gone (now just an empty bottle); the gitea-dev example already
  uses `git:` since the ExtraHosts work.
- PRD 0007 carries a "Superseded by PRD 0009" header at the top
  with a one-paragraph block explaining why; the file stays so
  the rationale of the prior design is still in-tree.
- git_gate.py: drop the now-stale shadow-route mention from a
  docstring (the validator went away in the manifest layer).
2026-05-12 23:57:50 -04:00
didericis 9b7bcc0149 docs(git-gate): document ExtraHosts on bottle.git entries
test / unit (pull_request) Successful in 12s
test / integration (pull_request) Successful in 19s
- example manifest swaps the gitea-dev bottle from ssh: to git:
  and shows ExtraHosts pinning gitea.dideric.is to its Tailscale IP
- README's git-gate paragraph names the field and the case it
  solves (upstream resolvable on the host but not from the gate
  container's default DNS)
- PRD 0008's manifest-field bullet mentions the field for parity
2026-05-12 23:18:46 -04:00
didericis 76a56c0700 docs(readme): git-gate is now a bidirectional mirror
test / unit (pull_request) Successful in 11s
test / integration (pull_request) Successful in 21s
Architecture diagram + bullet now reflect that the gate fronts
every git operation, not just push: pre-receive gitleaks-gates
the push path; an access-hook refreshes from upstream before each
upload-pack so fetch / clone / pull / ls-remote see whatever the
upstream has at that moment (fail-closed if unreachable).
2026-05-12 22:36:16 -04:00
didericis bea433015f docs(readme): add git-gate to architecture diagram
test / unit (pull_request) Successful in 13s
test / integration (pull_request) Successful in 17s
Bumps the sidecar count from two to up to three; the diagram and
bullet list now cover the git-gate alongside pipelock and ssh-gate,
including the ~/.gitconfig pushInsteadOf wiring that fires the
agent's git push through the gate.
2026-05-12 21:19:20 -04:00
didericis 4790f8bcc1 docs(readme): add architecture diagram for agent/pipelock/ssh-gate
test / unit (push) Successful in 12s
test / integration (push) Successful in 13s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 18:01:43 -04:00
didericis d75cc9325f feat(bottles): implement bottle factory abstraction per PRD 0003
test / run tests/run_tests.py (pull_request) Successful in 16s
Introduce claude_bottle/bottles/ with a Bottle Protocol and a
get_bottle_factory() that dispatches on CLAUDE_BOTTLE_PLATFORM
(default "docker"). Move every Docker-specific subprocess.run call
from cli/start.py, plus the orchestration of build, networks, the
pipelock sidecar, container launch, and per-container provisioning
(prompt, skills, ssh, .git), into create_docker_bottle.

Drop bottles[].runtime from the manifest schema. Auto-detect whether
gVisor is registered with the daemon and pass --runtime=runsc when it
is; the preflight shows the resolved runtime so the choice is visible.
Manifests still carrying 'runtime' get a clear error pointing at the
auto-detect behavior, rather than silent ignore.

Out of scope: cli/cleanup.py and cli/list.py still call docker
directly. They enumerate active bottles across the host, which is a
separate concern from "create a bottle" and is left for a follow-up
that introduces a list_active/cleanup primitive on the factory.
2026-05-10 22:15:05 -04:00
didericis 79604fded7 docs: reposition README around scoped-agent wedge and note DoH
test / run tests/run_tests.py (push) Successful in 21s
Lead with what the project does for the user — scoped Claude Code
agents on self-hosted infrastructure with per-agent secret and egress
limits — instead of the 2024-coded "isolated container" framing.
Tagline, "Why claude-bottle?" intro, and goals list now name secret
minimization, egress allowlisting, and self-hosted operation as the
load-bearing properties.

Also adds a sentence to the security model noting that DoH is
blocked structurally by the existing egress allowlist, since the
bottle has no L3 path off-box except through pipelock's hostname-
allowlisted CONNECT proxy.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 03:00:19 -04:00
didericis fe232744a6 docs: reframe security model around secret exposure and exfiltration
test / run tests/run_tests.py (push) Successful in 20s
Soften the "container is the boundary against reaching the host"
framing in favor of what the design actually leans on: granting each
bottle only the secrets it needs, and constraining where those
secrets can travel via pipelock. The container is one layer rather
than the load-bearing one.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 02:42:12 -04:00
didericis acbaffb98e docs: add Apache 2.0 LICENSE and link it from the README
test / run tests/run_tests.py (push) Successful in 15s
Drops the canonical Apache 2.0 text at repo root and adds a License
section to the README with the copyright line. Apache 2.0 picked over
MIT for the patent grant and contributor language, both of which
matter for a security-adjacent tool aiming at corporate-evaluable
adoption. Also tidies the manifest example's GIT_AUTHOR_NAME to use
the project's online handle.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 02:02:42 -04:00
didericis e7cfc91ca5 docs: consolidate egress + gVisor docs into a worked Manifest section
test / run tests/run_tests.py (push) Successful in 17s
Replaces the standalone Egress section with a Manifest section that
shows a complete bottle + agent example, with the egress and gVisor
explanations folded into JSONC comments above the relevant keys. The
gVisor paragraph in Security model is trimmed to a one-line pointer
at the manifest example.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 01:47:52 -04:00
didericis c8a35beb12 docs: add project logo and trademark disclaimer to README
test / run tests/run_tests.py (push) Successful in 15s
A short apothecary-bottle SVG with a cream cartoon robot inside —
sized roughly to the robot so it works as a favicon-shaped icon.
README gains a centered logo above the title and a Trademarks
section disclaiming affiliation with Anthropic and framing the
"claude" in the project name as descriptive use.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 01:40:05 -04:00
didericis e3f5a5907a feat(bottle): opt-in gVisor runtime per bottle
test / run tests/run_tests.py (push) Successful in 19s
Bottles can now set "runtime": "runsc" to launch the agent container
under gVisor instead of runc, adding a userspace syscall barrier
between the agent and the host kernel. Default is runc (Docker
default). Pipelock stays on the default runtime per the research doc's
minimum-diff prescription.

The launcher verifies runsc is registered with the daemon before
launch, surfaces the runtime in the preflight plan, and dies with an
install pointer (and a macOS-not-supported note) when runsc is
requested but unavailable.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 00:48:11 -04:00
didericis 3eff1e0b6e docs: replace non-goals with a security model section in README
test / run tests/run_tests.py (push) Successful in 18s
Frames the per-agent isolation story (each bottle gets only the env,
skills, ssh, and egress hosts its manifest grants) and is honest about
the limits of the container boundary, pointing at the new research doc
for the stronger-isolation v2 question.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 00:41:14 -04:00
didericis cc5e772519 docs: replace stale .sh paths with claude_bottle/*.py equivalents
test / run tests/run_tests.py (push) Successful in 13s
Cleans up references to the pre-refactor bash layout (cli.sh,
lib/*.sh, scripts/*.sh) across README, Dockerfile, the pipelock PRD,
and research notes. Refreshes line numbers in the oauth-token note
against the current cli/start.py.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 00:27:25 -04:00
didericis 91b1683306 docs: fix post-Python-refactor drift in README and Dockerfile
test / run tests/run_tests.py (push) Successful in 25s
Update the quickstart command to ./cli.py and drop a stale Dockerfile
comment that referenced scripts/lib/auth.sh, which no longer exists
after the bash->Python refactor.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 23:51:11 -04:00
didericis 4694db1201 PRD 0002: Test pipeline on Gitea Actions (#3)
test / run tests/run_tests.py (push) Successful in 20s
2026-05-09 02:48:03 -04:00
didericis ba7616a4ae PRD 0001: Per-agent egress proxy via pipelock (#1) 2026-05-08 01:56:43 -04:00
didericis c45f384fb8 Initial commit 2026-05-07 22:45:36 -04:00