From f9977c60dda261ccf97e21adfdb2cdb2afca9be8 Mon Sep 17 00:00:00 2001 From: Sam & Claude Date: Sat, 13 Jun 2026 21:33:41 +0200 Subject: [PATCH] docs: salvage agent-harness consolidation ADR + correct pi guidance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the canonical ADR referenced by build.cfg and the consolidation work (from docs/adr-agent-harness-consolidation, which merges clean). Prepends a dated Update note: the ADR's "remove Pi" guidance is superseded — Pi is DEMOTED to a spawnable backend (kept on-image, Node stays), zot is the primary harness, per docs/COLIBRI-JAILED-AGENT-SPAWN-DESIGN.md. Original record preserved. Co-authored-by: Sam & Claude (original ADR) Co-Authored-By: Claude Opus 4.8 --- docs/ADR-agent-harness-consolidation.md | 116 ++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 docs/ADR-agent-harness-consolidation.md diff --git a/docs/ADR-agent-harness-consolidation.md b/docs/ADR-agent-harness-consolidation.md new file mode 100644 index 0000000..8f37515 --- /dev/null +++ b/docs/ADR-agent-harness-consolidation.md @@ -0,0 +1,116 @@ +# ADR: Consolidate agent harnesses on zot + Colibri + +**Status:** Proposed · **Date:** 13.jun.2026 · **Owner:** Sam & Claude + +> **Update (13.jun.2026):** The "remove Pi" / "stage-deprecate Pi" guidance below +> is **superseded**. Decision refined: **Pi is demoted, not removed** — it stays +> on the image as a _spawnable agent backend_ that zot (the primary harness) can +> launch (e.g. a jailed Pi via the Colibri spawner). The Node runtime therefore +> **stays**. zot becomes the default/primary harness; the Rust `clawdie` relay and +> mini-binary are still retired (done — the `clawdie` crate was removed). See +> `docs/COLIBRI-JAILED-AGENT-SPAWN-DESIGN.md`. + +## Context + +We have accumulated overlapping pieces that all do "agent" or "supervision": + +| Piece | What it is | Layer | +| ------------------------------------------------------ | ------------------------------------------------------------------- | ---------------------- | +| **Pi** (`@earendil-works/pi-coding-agent`) | Node coding-agent CLI; `--mode json` JSONL | harness | +| **zot** (`clawdie/zot`, mirror of `patriceckhart/zot`) | Go coding-agent, one static binary; TUI/print/json modes | harness | +| **codex** | OpenAI Codex CLI | harness | +| **clawdie** (Rust crate in this repo) | single binary: glasspane + Herdr socket + a Telegram→DeepSeek relay | mixed | +| **clawdie-ai** (TypeScript) | legacy control plane + Telegram + media features | mixed | +| **Colibri** | FreeBSD-native supervision (glasspane) + coordination + cost | control plane | +| **Herdr** | Linux-only supervision/pane UI | supervision (optional) | + +Two redundancies are now concrete, not theoretical: + +1. **zot already provides what the Rust `clawdie` binary reimplements** — a single + binary with a built-in Telegram bot, DeepSeek (and ~25 other providers), a JSON + run mode, `SKILL.md` skills, and subprocess JSON-RPC extensions. `clawdie`'s + `telegram.rs` + `deepseek.rs` are a single-provider subset of that. +2. **Pi and zot are interchangeable harnesses.** `colibri-glasspane` already models + both (`AgentRuntime { Pi, Zot }`) and `apply_zot_event` **delegates to + `apply_pi_event`** — identical event taxonomy. zot also covers Pi's lanes: + `openai_codex.go` (the gpt-5.5/codex lane), Anthropic/Gemini/Copilot/DeepSeek, + and OAuth (`auth/oauth.go`). zot is one static Go binary; Pi drags the Node + runtime into the ISO. + +Credentials are the same story: zot has a full credential manager +(`--api-key` → provider env var → `$ZOT_HOME/auth.json` [API key or OAuth, 0600], +plus interactive OAuth/api-key login). `clawdie`'s `resolve()` (env → build-flag +baked) is a strict subset. + +## Decision + +Converge on **two components**: + +- **Agent / front door = zot** — providers (incl. DeepSeek), Telegram, tools, + JSON mode, skills, extensions, and credential management (`$ZOT_HOME/auth.json`). +- **Control plane = Colibri** — supervision (glasspane consumes zot JSON), + coordination (task board), skills catalog, cost discipline. + +Consequences for the other pieces: + +- **Rust `clawdie` binary:** stop reimplementing the agent. Either (a) slim it to a + thin supervisor that launches zot and wires it to Colibri, or (b) retire the + binary and let **"clawdie" be the product name** for _zot + Colibri_. Drop + `telegram.rs` / `deepseek.rs` / credential `resolve()` — zot owns those. +- **Pi:** stage-deprecate in favor of zot once the gates below pass. Keep it until + then — it is the currently-documented Colibri JSONL contract. +- **Herdr:** unchanged — optional Linux UI; Colibri glasspane is the FreeBSD core. +- **clawdie-ai (TS):** continue pruning; route surviving capabilities to **zot + extensions / `SKILL.md`** (the mechanism already exists upstream), the rest to + Colibri; retire over time. + +Net: three "agents" (Pi, the Rust clawdie relay, clawdie-ai TS) collapse toward +**one agent (zot) + one control plane (Colibri)**, and the Node runtime leaves the +agent path. + +## Credentials on the operator image + +The ISO should populate zot's own credential surface instead of baking keys into a +bespoke binary: + +- set `ZOT_HOME` for the operator (e.g. `/var/db/clawdie` or the operator home), +- export `DEEPSEEK_API_KEY` (+ the Telegram token zot reads) via the rc.d env file, + **or** stage a mode-0600 `$ZOT_HOME/auth.json`, +- the existing `clawdie.env` becomes the place those land. + +This replaces `clawdie`'s build-flag baking and keeps secrets out of the binary. + +## Migration gates (do not break Pi mid-flight) + +1. Validate `colibri-glasspane`'s zot parser against **real** `zot --mode json` + output (capture a live JSONL sample; confirm state transitions match Pi's). +2. Confirm zot covers the required provider lanes on FreeBSD — DeepSeek, and the + codex/gpt-5.5 **OAuth** subscription lane (`auth.json`) — with a smoke per lane. +3. Pilot zot as the operator-USB agent behind a build flag; Pi stays default. +4. Once green: flip default to zot, retire the Rust `clawdie` relay, drop the + Node-for-agent bundling, and remove Pi from the live CLI set. + +## Risks + +- Real migration, not a rename; Pi is the documented contract today. +- zot is third-party upstream (`patriceckhart/zot`, MIT) — we must track/sync it + (wire an `upstream` remote; pin a tag for the ISO). MIT lets us fork if needed. +- codex/gpt-5.5 OAuth must be proven in zot before dropping Pi. +- FreeBSD: zot is Go (static binary, easy); confirm `x86_64-freebsd` builds + the + Telegram/long-poll path on the live USB. + +## Consequences + +- **Positive:** one harness + one control plane; no Node in the agent path; smaller + ISO; one credential model (`auth.json`); zot's skills/extensions absorb clawdie-ai + features; less surface to maintain. +- **Negative:** migration effort; temporary dual-run (Pi + zot) during gates; + dependency on an external upstream we must keep synced. + +## References + +- `crates/colibri-glasspane/src/lib.rs` — `AgentRuntime { Pi, Zot }`, `apply_zot_event` +- `clawdie/zot` — `packages/agent/config.go` (credential order), `packages/agent/botcmd.go` + (Telegram), `packages/provider/openai_codex.go`, `packages/provider/auth/oauth.go` +- `docs/HERDR-VS-COLIBRI-GRAPH.md` — supervision boundary (Herdr vs Colibri) +- `docs/CLAWDIE-AGENT-WIKI.md` — the (now-superseded) Rust clawdie bundle -- 2.45.3