Agent Harness Migration (Planned)
Planned change, under development. Nothing described below the “Where it stands” section has been built yet. The source of truth isThe agent workflow (configs, rules, skills, review gates, Pi delegation and UI bridges) grew insideSPEC-HARNESS-MIGRATION.mdin this repo, and the executable spec (20 acceptance criteria, each with averify:command) lives on theworktree-feat+harness-orchestratorbranch of~/repos/agent-harness, status draft. This page is a simplified presentation; when the two disagree, the spec wins.
~/dotfiles, with more pieces in llm-wiki/claude-setup, several sibling repos, and live config files that no repo tracks. The plan moves it into a dedicated agent-harness repo, then grows that repo into a multi-machine orchestrator: one hub on the homelab that dispatches agents to other machines over Tailscale.
Related guides: Architecture (how the harness fits together today) and Standard workflow (the spec loop the migration must not break).
Why
- Sprawl. The workflow spans four agents (Claude Code, Codex, Pi, OpenCode), the spec loop and review gates, Pi delegation through pueue, and UI bridges in Neovim, sketchybar, herdr and claude-tui. Nobody can hold it in their head any more.
- Coupling. About 50 hardcoded
~/dotfiles/scripts/...paths, many inside agent rule text, and a symlink loop between three repos. - No clean install. A second machine cannot run the workflow, because part of it is untracked live state. That blocks the orchestrator, which needs remote nodes to install the harness on their own.
The layers
The harness is made of six layers. The names match thelayer column of links.tsv.
- Agent config. Settings, hooks, agent definitions and extensions for Claude Code, Codex, Pi and OpenCode, today under
dotfiles/{claude,codex,pi,opencode}plus the Codex guardrails plugin. Pi settings and routing and the Codex config exist only as untracked live files. - Rules and skills. The shared
AGENTS.md, research-tool routing and skills such asdelegate-pi,grill-meandpele, split betweendotfiles/sharedandllm-wiki/claude-setup(12 rules, 17 skills). Dotfiles links into llm-wiki, which is the source of the symlink loop. - Workflow CLIs. The commands that run the spec loop and review gates:
ac-run,floor-guard,commit-funnel,agent-review, plus session and hook helpers, all indotfiles/scripts. - Claude mods. Plugins that change Claude Code’s own interface, mainly the
session-bandmod, which reads pueue, Pi sessions and~/.claude/stateto show gates and running tasks. - UI bridges. Neovim review gates and boards, the sketchybar agents item, and the herdr-to-sketchybar bridge. They show agent state on screen and do not hold workflow logic.
- Sibling repos. Projects with their own repo that the workflow consumes:
claude-tui,agent-events,pi-live-status(not under git),DiffViewerandcode-preview.nvim.
.agents/, .pi/, ~/.claude/state/) is deliberately never versioned.
Where it stands
Step 1 is done (2026-10-22): a link-view repo.~/repos/agent-harness exists locally with no remote. Nothing has moved; dotfiles is still the live source.
Every component is
linked today. The migration flips rows to owned, one layer at a time.
Chart 1 — Who owns what, before and after Phase A
Question: after Phase A, which repo owns each layer? Today ownership is split across three repos plus untracked files, with a loop between dotfiles and llm-wiki. After Phase A the harness owns everything a node needs; the UI bridges stay in dotfiles for now.Chart 2 — How agent status reaches the menu bar and statusline
Question: which pieces carry “what are my agents doing” from the agents to the UI? The migration changes where these pieces live, not how they talk; this flow must still work after every step.Chart 3 — Where review and hook state is read
Question: who consumes the files the agents write? Claude hooks write session state; the Piagent-review extension writes review state; four different readers depend on those paths, which is why the paths must keep working during the move.
Chart 4 — Roadmap
Question: what lands in what order, from the link-view repo to the first orchestrator scenarios? No dates are set yet; the order comes from the spec’s inversion order.Chart 5 — Phase A migration order
Question: how does each Phase A step stay safe? Each step is gated by the same baseline. A0 records today’s state as passing; every later step reruns it, and any regression blocks that step. Old~/dotfiles/... paths keep working through symlinks into the harness until every consumer is updated.
Chart 6 — Phase B: the orchestrator
Question: what runs where once a node can install the harness by itself? The same Go binary,harness, runs in two roles. The hub on the homelab keeps a node registry (declared tags plus probed facts), a SQLite store of tickets and messages, an MCP server so one Claude Code session can see every agent’s context, and a kanban WebUI. Nodes are machines the hub reaches over SSH on the tailnet; the hub places an agent on the node whose tags match the job, for example a monitoring agent on the machine with the monitoring stack. The tag names below are examples.
Design boundaries:
- Control plane only. The hub relays agent and orchestrator messages. Agents may set up data links, such as shipping gateway logs to the monitoring machine, but the harness never carries that traffic.
- No provider keys on nodes. Nodes call the AI gateway with per-node virtual keys the hub can revoke.
- Tailnet only. The WebUI is single-user and not exposed publicly.
- No auto-rescheduling. If a node fails mid-task, the ticket is parked and you are notified. Infrastructure work has side effects, so it is never silently re-run elsewhere.
- Privileged steps need a human. Agents run as an unprivileged user, and
--dangerously-skipis refused on the hub and on any node without its guards.
Chart 7 — Ticket lifecycle
Question: what states can a ticket be in, and what moves it? The spec names only the Blocked column and the approval step; the other state names are working labels for the lifecycle it describes, to be checked against the WebUI once it exists.Chart 8 — MVP-1: message relay between two nodes
Question: what happens, in order, in the first end-to-end proof? Two Pi agents on two different nodes exchange messages only through the hub, and the result lands on the ticket. The hub dials the nodes over SSH; nothing listens on a node. MVP-2, the monitoring scenario, gets its own spec.How “done” will be checked
The agent-harness spec has 20 acceptance criteria. Grouped:Risks and open items
- Hidden consumers of old paths. Rule text and one test assert
~/dotfiles/scripts/ac-run. The compatibility symlinks must stay until a search shows zero consumers. - Relative symlinks inside dotfiles depend on directory depth and can break when a package moves.
- Untracked state.
pi-live-statusis not under git, and Pi, Codex, judge and herdr files exist only as snapshots. - Stale pieces to delete during the move:
claude-setup/settings.json,install-claude-symlink.sh, a dangling~/.local/bin/ao. - Likely bug found during the inventory:
pi-status.luareads~/.pi/statuswhile the writer uses<cwd>/.pi/status. - Open: the spec is still a draft awaiting approval; the agent-harness repo has no remote yet; the UI-bridge move is unscheduled.