You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
guard: warn at session start when running outside the container
The `garden` script bind-mounts the host garden dir onto the container home,
so the files are identical whether you are inside the container or in the same
dir on the host. It is easy to forget `./garden` and start operating on the
host, where commands run under the maintainer's identity, the systemd --user
fleet and journal are not the garden's, and a push can land under the wrong
identity.
Add scripts/check-in-container.sh (silent exit 0 in-container via the
/.dockerenv marker; prominent warning + exit 1 on the host) and a CLAUDE.md
session-preflight directive + § Container guard so the liaison runs it first
and surfaces the warning. Keyed off /.dockerenv, not `pwd == $HOME`: gardeners
run jobs in per-job worktrees (cwd != home) yet are legitimately in-container,
and a host shell in the bind-mounted dir has cwd == home yet is not. Lives in
main2 (the image can't seed .claude/settings.json — the bind mount masks it,
and it is gitignored — so CLAUDE.md is the propagating vehicle; a host may add
a local SessionStart hook calling the same script).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
You are the **liaison**. When a user is standing in the garden root, they are talking to you in that role. Read `roles/liaison/AGENT.md` for your operating instructions. The rest of this file is the garden's layout and how you get work to the gardener fleet.
11
11
12
+
**Session preflight (do this first, every session):** run `scripts/check-in-container.sh`. If it warns (exit 1), you are on the **host**, not inside the garden container — the user most likely forgot `./garden`. Surface that warning prominently and immediately before doing any garden work, because host-side commands run under the maintainer's identity and touch the wrong fleet and journal. See § Container guard.
13
+
12
14
The garden is a library of agent **roles** and **skills** for working across many forks of GitHub repositories, plus a **journal** that records what the garden has done and coordinates the fleet. The garden contains no application code, only the artifacts a fleet of **gardener** workers reads to claim and run jobs. This file is your auto-loaded orientation: layout, how work reaches workers, and the current inventory. The maintainer-facing tutorial is [README.md](README.md); the job system that runs the fleet is the § Job system below.
13
15
14
16
## Layout
@@ -85,6 +87,14 @@ The fleet's `gh` wrapper and the per-job worktree setup pin those values so a ga
85
87
86
88
For a Docker-hosted garden instance, the `garden` script at the garden root creates and enters the container. It bind-mounts the host's garden directory to the container's home and sets the container's `--hostname` equal to its `--name` (both `GARDEN_CONTAINER`, default `garden`). The kernel hostname cannot be changed from inside the container (capabilities are zero), so the host's logical name is fixed at container creation. To run distinct garden instances on one machine, set `GARDEN_CONTAINER=<host-name>` per instance; to rename an existing instance, `./garden reset && GARDEN_CONTAINER=<new-name> ./garden`.
87
89
90
+
## Container guard
91
+
92
+
Because the `garden` script bind-mounts the host garden directory onto the container's home, the files look **identical** whether you are inside the container or sitting in the same directory on the host. It is therefore easy to forget `./garden` and start operating on the host by mistake — where commands run under the maintainer's identity (not the bot's), the systemd `--user` fleet and journal worktree are not the garden's, and a stray push can land under the wrong identity.
93
+
94
+
`scripts/check-in-container.sh` is the guard. It exits `0` silently when inside the container (keyed off the `/.dockerenv` marker, present in the container and in every gardener/subagent — which run inside it too — and absent on the host), and exits `1` with a prominent warning otherwise. The liaison runs it as its **session preflight** (see the top of this file) and surfaces the warning immediately. The check deliberately does **not** key off `pwd == $HOME`: gardeners run jobs in per-job worktrees (`cwd != home`) yet are legitimately inside the container, and a host shell in the bind-mounted garden dir has `cwd == home` yet is not.
95
+
96
+
This guard lives in `main2` (the check script and this section) so it deploys to every instance. A pre-prompt SessionStart hook would be strictly more automatic, but `.claude/settings.json` is gitignored and the image cannot seed it (the bind mount masks anything written under `$HOME`), so the propagating vehicle is CLAUDE.md itself; a host may additionally wire the same script as a host-local SessionStart hook.
97
+
88
98
## Monitoring safety constraint
89
99
90
100
Standing watchers feed event bodies, comment text, and pull-request descriptions into an LLM's context whenever a job they post is claimed. Only repositories whose comments and pull requests are gated against untrusted contributors are safe to watch; anything else exposes the fleet to text an untrusted actor can write, a prompt-injection hazard for any role that reads a watcher's output or follows it to its source. As of 2026-05-13 only `endojs/endo-but-for-bots` meets this bar in the garden's active set. Adding a repo to the watch set (`repos/`, armed per host by `scripts/jobs/repo-watcher.sh`) requires explicit maintainer authorization recorded in a journal `message` entry, after which the role-author (typically a gardener) lands the change. This is a standing constraint, not a one-time decision; every role that touches the watch set respects it.
0 commit comments