From a49db39b5432485e1b950edaa4fea6732fb105bf Mon Sep 17 00:00:00 2001 From: "K. Isom" Date: Thu, 17 Sep 2026 13:00:21 -0700 Subject: [PATCH] Brief: add a one-sentence purpose for every role and crate Requested by the owner so that future readers, agents included, learn what each piece is for first. No behaviour changes. Co-Authored-By: Claude Fable 5.1 --- docs/decisions.md | 6 ++++++ docs/design.md | 24 +++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/docs/decisions.md b/docs/decisions.md index 8ddcdc9..ae4b109 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -53,6 +53,12 @@ Approved by the owner on 2026-09-17. One commit each. | P11 | Inference contract 10: the serving flags live in `~/src/nixos`, not here. This repo records the expected values (template hash, per-slot `n_ctx`, slot count, KV type, sampling) and the startup self-test compares them with `/props` and `/slots`. KV type is recorded as q8_0. | Shared router decision. | | P12 | Network isolation 2: `inferproxy` is kept. Remove the conditional about dropping it. Its upstream is the router's TCP listener on the host. | Shared router decision; M0 (g). | +Later changes to the brief: + +| Date | Change | Reason | +|---|---|---| +| 2026-09-17 | The roles table gained a one-sentence Purpose column, and the crates that are not roles got a purpose table under Code constraints. No behaviour changed. | Owner's request: a reader, human or agent, should learn what each piece is for before what it holds. | + ## Proposed changes to the design brief None pending. diff --git a/docs/design.md b/docs/design.md index acf8d4b..bbdd0a5 100644 --- a/docs/design.md +++ b/docs/design.md @@ -44,13 +44,13 @@ cloud-led orchestration as the default, in-process third-party code of any kind. ## Roles (separate binaries, narrow interfaces) -| Role | Holds | Can reach | Never holds | -|---|---|---|---| -| `gatewayd` | Mattermost bot token, allowlist, message queue | Mattermost server (outbound only), `loopd` socket | Tool secrets, grants | -| `loopd` | Session logs, prompt assembly, memory files | Three Unix sockets: `gatewayd`, `brokerd`, `inferproxy` | Any credential, any network interface | -| `inferproxy` | The `llama-server` address | `llama-server` only | Anything else; it forwards bytes and logs nothing | -| `brokerd` | Grants (read-only), secrets, audit log | Container runtime, `gatewayd` socket (for approvals) | Conversation history | -| tool containers | Only what one call was granted | Only what one call was granted | Anything persistent | +| Role | Purpose | Holds | Can reach | Never holds | +|---|---|---|---|---| +| `gatewayd` | Carries messages between the owner's Mattermost and the harness. | Mattermost bot token, allowlist, message queue | Mattermost server (outbound only), `loopd` socket | Tool secrets, grants | +| `loopd` | Runs the conversation: builds each prompt, calls the model, and asks `brokerd` for every tool call. | Session logs, prompt assembly, memory files | Three Unix sockets: `gatewayd`, `brokerd`, `inferproxy` | Any credential, any network interface | +| `inferproxy` | Lets `loopd` reach the model without having a network. | The `llama-server` address | `llama-server` only | Anything else; it forwards bytes and logs nothing | +| `brokerd` | Decides whether each tool call may run, runs it in a fresh container, and records the decision. | Grants (read-only), secrets, audit log | Container runtime, `gatewayd` socket (for approvals) | Conversation history | +| tool containers | Do one approved tool call and then cease to exist. | Only what one call was granted | Only what one call was granted | Anything persistent | v0 runs all roles on one host. The interfaces must not assume co-location with `llama-server`. @@ -211,8 +211,14 @@ Files are the source of truth. SQLite is allowed only for rebuildable indexes an ## Code constraints -- Rust stable, Cargo workspace. Crates: `proto` (shared types), `loopd`, `brokerd`, `gatewayd`, - `inferproxy`, `toolkit` (tool container entrypoints), `bxctl` (owner CLI). +- Rust stable, Cargo workspace. One crate per role in the table above (`loopd`, `brokerd`, + `gatewayd`, `inferproxy`), plus three that are not roles: + + | Crate | Purpose | + |---|---| + | `proto` | Defines the data every role shares and the frame format they exchange it in. | + | `toolkit` | Holds the programs that run inside tool containers. | + | `bxctl` | Is the owner's command line: chat, local approvals, checks and maintenance. | - No source file over 500 lines. No crate depends on another role's crate, only on `proto`. - Authority is encoded in types: a tool cannot execute without a `Decision` value that only `brokerd`'s policy module can construct. `Decision` is defined in `brokerd`, has a private