Write down what agent chats are and what will bite you

CLAUDE.md gets the entries worth having been told: that the mode is
enforced in the loop rather than the prompt and why that distinction is
load-bearing; that an approved call has to be told it was approved, or the
runners' own backstop refuses the very thing somebody just allowed; that
`registry` must know the agent tools or the harness cannot name the machine
-- the same omission that cost custom tools their guidance once already;
that each command is a fresh shell and `apt-get install` needs an update
first, which are the two likeliest sources of "the agent seems stupid";
that asyncssh's four defaults are all wrong when one unix account is
shared; and that rewind rewinds the transcript and not the machine.

"Not built yet" loses agentic execution and gains the reason nothing runs
on this host -- with the two consequences stated plainly, since they are
the ones somebody has to weigh: the security of an agent chat is the
security of the host behind its profile, and there is no "no network"
switch, because the network belongs to the far side.

README gets a section that starts with the container, because that is the
intended shape and the thing a reader has to build before any of it means
anything.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jaroslav Beneš
2026-08-02 00:29:30 +02:00
parent 16e59feab2
commit 246be1fa8e
3 changed files with 204 additions and 29 deletions
+36 -13
View File
@@ -5,8 +5,9 @@ that would be expensive to revisit. Kept current as work lands; the detail of
*how* things work lives in [`CLAUDE.md`](CLAUDE.md).
**Status:** usable daily. Streaming chat, attachments, reasoning, tool calling
with web search, a knowledge library, notes, memory and skills, speech in and
out, users and groups, model administration, installable as an app. 437 tests,
with web search, custom HTTP tools and MCP servers, agent chats that work on a
machine over SSH, a knowledge library, notes, memory and skills, speech in and
out, users and groups, model administration, installable as an app. 837 tests,
`ruff` clean.
---
@@ -66,6 +67,9 @@ be a different project, not a refactor.
the next turn, for the same reasons reasoning is not
- [x] A round's calls run together, and the reply says which tool is running —
a remote tool taking seconds with nothing streaming looks like a hang
- [x] **A reply can stop and ask you something** — one or more questions on one
card, with answers to pick from and a box to write your own, answered
together. The same mechanism carries command approvals
- [x] **Custom HTTP tools** — an administrator describes one call: a JSON Schema,
a URL template, headers, an encrypted secret and how to read the answer.
Arguments may fill a hole but never move the target: the scheme and host
@@ -78,8 +82,36 @@ be a different project, not a refactor.
a model as instructions
- [x] Both gated like the built-ins — a model capability, a permission — and
restrictable to groups, with guidance of their own on `/admin/prompts`
- [x] Local MCP over stdio is deliberately absent: spawning a subprocess is the
agentic-execution feature and wants a confirmation model first
- [x] Local MCP over stdio is deliberately absent: spawning a subprocess would
run on this machine, which nothing here does
### Agent chats
- [x] A chat is a **Chat** or an **Agent**, chosen when it starts and fixed
thereafter — a transcript whose earlier turns ran somewhere else is not
one conversation. Knowledge, memories and skills are shared across both
- [x] **Nothing runs on the LLeMbas host.** Commands go to a machine reached
over SSH, so containment is somebody's considered choice of host — a
container built for the job — rather than a sandbox built here. A local
one was designed in detail and dropped; see CLAUDE.md for why
- [x] **SSH connections are user-owned**, like notes. An administrator decides
only whether the feature exists at all
- [x] Trust on first use, made explicit: adding a host does not connect to it,
**Check** shows its fingerprint with nothing sent, and only accepting
pins it. A host that later answers with a different key is refused
- [x] Four modes as a table over what each tool does to the world —
**Manual** asks about everything, **Edit** writes freely but asks before
commands, **Auto** asks about nothing, **Plan** reads freely and changes
nothing. Switchable at any time; read once per reply
- [x] Enforced in the generation loop, not in the prompt: a rule a model is
merely told is one a poisoned file can argue with
- [x] A deny list beats **Auto**; an allow list cannot be matched by a command
containing anything that joins two commands together
- [x] `shell_run`, `file_read`, `file_write`, `file_list` — files over SFTP,
never through a shell, because the SSH exec protocol has no argv form
- [x] **Plan mode ends with a plan** you can carry out with one button, which
switches to Edit and sends it back quoted rather than as an instruction
- [x] Per-reply budgets on steps, wall clock and output, with time spent
waiting for you subtracted
### The library
- [x] **Knowledge bases** — documents, images and saved web pages, grouped into
@@ -171,15 +203,6 @@ be a different project, not a refactor.
In the order they are likely to be worth doing.
### Agentic execution
Two modes, as originally specified:
- **local** — subprocess on the machine LLeMbas runs on
- **remote** — SSH connection profiles, with `shell.run` / `fs.read` / `fs.write`
Needs a confirmation model before it does anything. Note that the systemd unit
is deliberately only `ProtectSystem=full` rather than `strict` **because** of
this — revisit the hardening when the real filesystem needs are known.
### Image generation
Left until last from the start, as it needs heavy customisation. ComfyUI is
already running on this machine and is the obvious first target.