docs(wiki): LLM-Wiki pilot — decisions/architecture knowledge base #162

Merged
clawdie merged 2 commits from wiki-pilot into main 2026-06-24 10:16:01 +02:00
4 changed files with 192 additions and 0 deletions

View file

@ -0,0 +1,51 @@
# Agent harness: zot + Colibri
← [index](./index.md)
## Decision
Two binaries, not one (Sam rejected merging them, 2026-06-13):
- **zot**_the agent_ (front door to the model). Go binary; acts.
- **Colibri**_the control plane_ (supervisor). Rust; watches agents via
glasspane, runs the task board, owns cost. It **observes** zot/pi; it does not
contain them.
Canonical statement: `AGENTS.md` (lines ~1832). `clawdie-ai` (TS) is being
pruned; surviving features move to zot/Colibri.
> There is **no** `ADR-agent-harness-consolidation.md` despite references to it
> in `clawdie-iso/scripts/stage-colibri-iso.sh`. Treat `AGENTS.md` as the ADR.
## Runtimes
Glasspane normalizes events from both harnesses into one taxonomy via
`AgentRuntime { Pi, Zot, Local }``crates/colibri-glasspane/src/lib.rs`
(`zot_event_type()` maps zot's events onto the pi-style names).
## Autospawn + the RPC driver (colibri#143)
The spawner's contract: spawn the agent, read stdout JSONL.
- **pi** self-drives (`pi --mode json`) with `stdin` null — fits directly.
- **zot**'s only structured persistent mode is `zot rpc`, a request/response
peer that **reads stdin**. So the spawner pipes stdin for RPC agents and the
daemon sends the prompt over an `RpcSender`.
Where it lives:
- spawn contract + `rpc_stdin` + `RpcSender`: `crates/colibri-daemon/src/spawner.rs`
- autospawn binary-aware argv (`zot → rpc`, pi → `--mode json`):
`crates/colibri-daemon/src/socket.rs` (`default_agent_args`,
`autospawn_agent_if_configured`)
- wire format (verified against real zot): [ZOT-RPC-TRANSCRIPT](../ZOT-RPC-TRANSCRIPT.md)
- end-to-end proof: `crates/colibri-daemon/tests/zot_rpc_smoke.rs`
(`#[ignore]`, `ZOT_BIN`-gated)
OOTB default harness is **zot**; pi remains a supported fallback
(`COLIBRI_AUTOSPAWN_BINARY=pi`).
## See also
- [naming-decisions](./naming-decisions.md) — the `pi → zot` neutral-naming work
- [quality-gates](./quality-gates.md) — how a half-finished rename reached `main`

56
docs/wiki/index.md Normal file
View file

@ -0,0 +1,56 @@
# Colibri Wiki
A small, agent-maintained knowledge base for Colibri's **decisions and
architecture** — based on Andrej Karpathy's
[LLM Wiki pattern](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f).
This is a **pilot**. It deliberately covers a few decision-dense areas, not the
whole repo.
## Why this exists
Stale decisions accumulate faster than anyone hand-audits them: a rename that
was only half-applied, a doc that still describes the old design, a default
left over from a superseded choice. Several recent passes were spent finding
exactly that (`pi → zot`, `usb_nodes → hive_nodes`, `fake → sample`). This wiki
makes the bookkeeping near-zero-cost: one place that records _what was decided_,
links to _where it lives in code_, and can be **linted** for drift.
## Conventions (the schema)
These rules keep the wiki a maintainable artifact, not a second source of truth:
1. **Code is the source of truth.** Pages describe _decisions_ and _where_ they
live; they link to code/docs rather than re-explaining implementation. When a
decision ships, slim its page to "how it works + link."
2. **Link, don't duplicate.** Reference code as `path/to/file.rs:line` and other
wiki pages with relative links (`[label](./page.md)`) — Forge-clickable, the
equivalent of Obsidian `[[wikilinks]]` adapted to a repo.
3. **One decision per page** where practical; cross-link liberally.
4. **Flag, don't silently overwrite.** When new code contradicts a page, note
the contradiction (and resolve it) rather than quietly editing history.
5. **Lint, don't trust.** A page is a claim to be checked against code, not a
guarantee.
## Lint workflow (the point of the pilot)
`lint` = an agent pass that reads each page and checks it against the current
code: stale names, dangling references, contradictions, decisions that shipped
but whose page still says "planned." Output is a **report**, not auto-edits —
advisory first, until the signal is trusted. (Tool TBD — pilot step 2.)
Open drift already noted by hand:
- `stage-colibri-iso.sh` (clawdie-iso) and a guardrail comment reference
`ADR-agent-harness-consolidation.md`, which **does not exist** in either repo.
The real architecture statement is `AGENTS.md`. → see [agent-harness](./agent-harness.md).
## Pages
| Page | What it covers |
| ----------------------------------------- | ------------------------------------------------------------------------ |
| [agent-harness](./agent-harness.md) | The zot (agent) + Colibri (control plane) split; autospawn + RPC driver |
| [naming-decisions](./naming-decisions.md) | Ledger of harness-neutral / architecture renames — shipped and in-flight |
| [quality-gates](./quality-gates.md) | `ci-checks.sh` as the pre-merge gate; why drift reached `main` before |
_Pending: a `mother-hive` page once the mother MCP infra lands (colibri #161)._

View file

@ -0,0 +1,43 @@
# Naming decisions ledger
← [index](./index.md)
A living record of renames driven by superseded assumptions, so future drift is
checkable against one list. "Shipped" means merged to `main`; verify against the
linked code before trusting a row.
## Shipped
| Old → New | Why | Anchor |
| ------------------------------------------------ | -------------------------------------------------------------------- | ---------------------------------------------- |
| `COLIBRI_AUTOSPAWN_PI``COLIBRI_AUTOSPAWN` | Harness-neutral (default agent is zot, not pi) | `crates/colibri-daemon/src/socket.rs` |
| `COLIBRI_PI_BINARY``COLIBRI_AUTOSPAWN_BINARY` | same | `socket.rs` (`autospawn_agent_if_configured`) |
| `pi_session_id``session_id` | zot agents have session ids too; `#[serde(alias)]` keeps back-compat | `crates/colibri-glasspane/src/lib.rs` (`Pane`) |
| `fake-pi-agent.py``sample-pi-agent.py` | "fake" too loaded; it emits a canned _sample_ | `scripts/sample-pi-agent.py` |
| non-local spawn default `hermes-agent``zot` | `hermes-agent` was a nonexistent leftover binary | `socket.rs` (`default_agent_args`) |
## In-flight
| Old → New | Status | Anchor |
| -------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------ |
| `usb_nodes``hive_nodes` | colibri #161 (a node is any host that joined the hive, not only a USB boot; `+node_type` column) | `packaging/mother/mother_schema.sql` |
## Known residue (not yet actioned)
| Item | Note |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `pi_type` | pi-era name for "normalized event type"; **internal only**, not serialized. Optional rename → `event_type`. `crates/colibri-glasspane/src/lib.rs` |
| `FEATURE_COLIBRI` | `AGENTS.md`/README imply "no separate feature flag," but the build keeps it (default YES, "internal escape hatch"). Reconcile wording or flag. (clawdie-iso) |
| `clawdie-startx` | README teaches `clawdie-gui`; `startx` kept as the internal wrapper — documented transition, verify the user-facing launcher leads with `gui`. (clawdie-iso) |
| `ADR-agent-harness-consolidation.md` | Referenced but does not exist; `AGENTS.md` is the real anchor. See [agent-harness](./agent-harness.md). |
## Structural decisions
| Decision | Why / lesson | Anchor |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| Single home for mother infra = colibri | The mother MCP scripts were copied into both colibri and clawdie-iso; the iso copy drifted to an **SQL-injectable** `node-register-mcp` on `main`. Same script in two repos drifts — a lint pass should flag cross-repo duplicates. | colibri `packaging/mother/`; iso removal in iso PR #129 |
## See also
- [agent-harness](./agent-harness.md)
- [quality-gates](./quality-gates.md) — the gate that should catch these at PR time

View file

@ -0,0 +1,42 @@
# Quality gates
← [index](./index.md)
## Decision
A change is not "done" until the gate passes locally:
```sh
./scripts/ci-checks.sh # cargo fmt --check, clippy -D warnings, cargo test, markdown gate
```
`.forgejo/workflows/ci.yml` encodes the same checks, but **no Forgejo Actions
runner is registered**, so nothing enforces them server-side. Until a runner is
active, `ci-checks.sh` passing locally is the only gate. Stated as mandatory in
`AGENTS.md`.
## Why this page exists
A compile break (`pi_binary` undefined, from a half-finished rename) reached
`main` because the gate was skipped _and_ unenforced. The same audit found both
gates were effectively red on `main` at the time:
- `clippy -D warnings` failed on a pre-existing lint → the Rust gate would have
failed for anyone who ran it.
- the markdown gate failed on prettier-dirty docs.
Both were brought green, so the gate is now actually runnable. The lesson: a
gate nobody runs (and that's red anyway) is the root cause of drift reaching
`main` — more than any individual naming slip.
## Relationship to this wiki
The [naming-decisions](./naming-decisions.md) ledger + a future `lint` pass are
the _semantic_ counterpart to `ci-checks.sh`: the compiler/clippy catch broken
_code_, but not a doc that still describes the old design or a name that drifted.
The wiki lint is meant to cover that gap (advisory first).
## See also
- [agent-harness](./agent-harness.md)
- [naming-decisions](./naming-decisions.md)