feat(config,compose): sdk agents with vault prompt granules and skill plugins, ro vault with rw sub-mounts, beaver-runner

This commit is contained in:
hh
2026-08-28 01:56:40 +02:00
parent 856c5234fb
commit f2dc07a5fd
5 changed files with 104 additions and 277 deletions
+10 -4
View File
@@ -58,6 +58,13 @@ On your mac run `claude setup-token` and put the result into `.env` as
container, no dialogs. The token draws from your subscription limits like
regular Claude Code; rotate it by running `claude setup-token` again.
Claude agents run on the Claude Agent SDK. Prompts are granules under
`мета/бобер/промпты/` in the vault, skills are the folders under
`мета/бобер/скиллы/` (each becomes a plugin), so the vault must be synced
before the gateway can start. The model process runs as `beaver-runner`
with a whitelisted environment; the vault is read-only for it except
`мета/бобер` and `💬 чаты`.
### 4. Mint a token
Open admin at `http://localhost:62992` (or `https://<DOMAIN>/admin/` if Caddy), sign in with `ADMIN_USER` / `ADMIN_PASS`, go to **Tokens → Create**, scope `*` for first run.
@@ -121,7 +128,6 @@ docker compose restart gateway
## Gotchas
- **claude in the container doesn't see the vault** - `cwd=VAULT` in `config.py` resolves to `/vault` *inside* the container, not on the host. Don't change it.
- **a claude turn fails immediately** - check `docker logs beaver-gateway` for the claude stderr it now quotes back. Usually auth: re-run step 3's `claude /login`.
- **the admin terminal viewer is read-only** - claude agents run headless (`transport="stream_json"` in `config.py`), so what the viewer shows is the JSON event stream, not a TUI you can type into. Flip that agent to `transport="pty"` if you genuinely need a keyboard on a live session.
The claude agents used to hang on `JSONL file did not appear within 30s` when the TUI's onboarding hadn't been clicked through. That path is gone with the headless transport — prompts go into a pipe, not a terminal.
- **a claude turn fails immediately** - check `docker logs beaver-gateway` for the `claude[<agent>]:` stderr lines. Usually auth: redo step 3.
- **gateway restarts in a loop right after first `up`** - `config.py` reads prompt granules from `/vault/мета/бобер/промпты`; until Obsidian Sync has pulled the vault they are missing. Finish step 2, it settles.
- **the model cannot write into `мета/бобер`** - the entrypoint grants `beaver-runner` an ACL on the two rw sub-mounts once at start; files that Sync creates later inherit it through the default ACL. If `setfacl` is unsupported on the volume it falls back to `chown`, and then files Sync writes afterwards as root stay read-only for the model until the next restart.