From 7c723f251c2f684cb88fc16a143d85e58f7b5b6a Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Fri, 19 Dec 2025 12:07:19 -0800 Subject: [PATCH] docs(harness): document harness concept comprehensively MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add docs/harness.md covering: - What a harness (installation directory) is - Directory structure with mayor/ config files - Town-level vs rig-level mayor presence - Beads architecture and resolution via BEADS_DIR - Relationship between harness and rigs - Example configurations and setup workflow 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- docs/harness.md | 239 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 docs/harness.md diff --git a/docs/harness.md b/docs/harness.md new file mode 100644 index 00000000..a2c817f5 --- /dev/null +++ b/docs/harness.md @@ -0,0 +1,239 @@ +# Harness Documentation + +A **harness** is the installation directory for Gas Town - the top-level workspace where your multi-agent system lives. The terms "harness" and "town" are used interchangeably. + +## What is a Harness? + +Think of a harness as: +- **Physical**: A directory on your filesystem (e.g., `~/gt/`) +- **Logical**: The container for all your rigs, agents, and coordination infrastructure +- **Operational**: The root from which the Mayor coordinates work across projects + +A harness is NOT a git repository itself. It's a pure container that holds: +- Town-level configuration in `mayor/` +- Town-level beads database in `.beads/` +- Multiple rigs (each managing a project repository) + +## Creating a Harness + +```bash +gt install ~/gt # Install Gas Town at ~/gt +gt install # Install at current directory +``` + +This creates the harness structure and initializes town-level beads with the `gm-` prefix. + +## Directory Structure + +``` +~/gt/ # Harness root (town) +├── CLAUDE.md # Mayor role prompting +├── .beads/ # Town-level beads (prefix: gm-) +│ ├── beads.db # Mayor mail, coordination, handoffs +│ └── config.yaml +│ +├── mayor/ # Mayor's home directory +│ ├── town.json # Town configuration +│ ├── rigs.json # Registry of managed rigs +│ └── state.json # Mayor agent state +│ +├── gastown/ # A rig (project container) +├── wyvern/ # Another rig +└── rigs/ # Optional: managed rig clones +``` + +## Configuration Files + +### mayor/town.json + +The town configuration identifies this directory as a Gas Town harness: + +```json +{ + "type": "town", + "version": 1, + "name": "stevey-gastown", + "created_at": "2024-01-15T10:30:00Z" +} +``` + +The `type: "town"` field is the primary marker that identifies the harness root during workspace detection. + +### mayor/rigs.json + +Registry of all managed rigs: + +```json +{ + "version": 1, + "rigs": { + "gastown": { + "git_url": "https://github.com/steveyegge/gastown", + "added_at": "2024-01-15T10:30:00Z" + }, + "wyvern": { + "git_url": "https://github.com/steveyegge/wyvern", + "added_at": "2024-01-16T14:20:00Z" + } + } +} +``` + +### mayor/state.json + +Mayor's agent state: + +```json +{ + "role": "mayor", + "last_active": "2025-12-19T10:00:00Z" +} +``` + +## Harness Detection + +Gas Town finds the harness by walking up the directory tree looking for markers: + +1. **Primary marker**: `mayor/town.json` - Definitive proof of harness root +2. **Secondary marker**: `mayor/` directory - Less definitive, continues searching upward + +This two-tier search prevents false matches on rig-level `mayor/` directories. + +```go +// Simplified detection logic +func FindHarness(startDir string) string { + current := startDir + for current != "/" { + if exists(current + "/mayor/town.json") { + return current // Primary match + } + current = parent(current) + } + return "" +} +``` + +## Mayor: Town-Level vs Rig-Level + +Gas Town has two levels of "mayor" presence: + +### Town-Level Mayor (`/mayor/`) + +- **Location**: At the harness root +- **Purpose**: Global coordination across all rigs +- **Configuration**: Contains `town.json`, `rigs.json`, `state.json` +- **Mailbox**: Uses town-level beads (`.beads/` with `gm-*` prefix) +- **Responsibility**: Work dispatch, cross-rig coordination, escalation handling + +### Per-Rig Mayor (`//mayor/rig/`) + +- **Location**: Within each rig's directory +- **Purpose**: Provides the canonical git clone for the rig +- **Contents**: Full git clone of the project repository +- **Beads**: Holds the canonical `.beads/` directory for the rig +- **Special role**: Source of git worktrees for polecats + +``` +~/gt/ # Harness root +├── mayor/ # Town-level mayor home +│ ├── town.json # Town config (not project code) +│ ├── rigs.json +│ └── state.json +│ +└── gastown/ # Rig container + └── mayor/ # Per-rig mayor presence + └── rig/ # CANONICAL git clone + ├── .git/ + ├── .beads/ # Canonical rig beads + └── +``` + +## Beads Architecture + +Gas Town uses a two-tier beads architecture: + +| Level | Location | Prefix | Purpose | +|-------|----------|--------|---------| +| Town | `/.beads/` | `gm-*` | Mayor mail, cross-rig coordination, handoffs | +| Rig | `/mayor/rig/.beads/` | varies | Rig-local work tracking, agent communication | + +### Beads Resolution + +Rather than using a `.beads/redirect` file, Gas Town uses: + +1. **Symlinks**: Rig root symlinks `.beads/` → `mayor/rig/.beads` +2. **Environment variable**: Agents receive `BEADS_DIR` pointing to the rig's beads + +```bash +# When spawning agents +export BEADS_DIR=/path/to/rig/.beads +``` + +This ensures all agents in a rig share the same beads database, separate from any beads the project might have upstream. + +## Relationship to Rigs + +A harness contains multiple rigs. Each rig is: +- A container directory (NOT a git clone itself) +- Added via `gt rig add ` +- Registered in `mayor/rigs.json` +- Has its own agents (witness, refinery, polecats) + +``` +Harness (town) +├── Rig 1 (gastown/) +│ ├── witness/ +│ ├── refinery/ +│ ├── polecats/ +│ └── mayor/rig/ ← canonical clone +│ +├── Rig 2 (wyvern/) +│ ├── witness/ +│ ├── refinery/ +│ ├── polecats/ +│ └── mayor/rig/ ← canonical clone +│ +└── Rig N... +``` + +## Naming Conventions + +Recommended harness naming: +- Short, memorable name: `~/gt/` (gas town) +- Or project-specific: `~/workspace/` +- Or user-specific: `~/ai/` + +Rig names typically match the project: +- `gastown` for the Gas Town project +- `wyvern` for the Wyvern project +- Use lowercase, no spaces + +## Example: Complete Harness Setup + +```bash +# 1. Install harness +gt install ~/gt + +# 2. Add rigs +cd ~/gt +gt rig add gastown https://github.com/steveyegge/gastown +gt rig add wyvern https://github.com/steveyegge/wyvern + +# 3. Verify structure +ls -la ~/gt/ +# CLAUDE.md .beads/ mayor/ gastown/ wyvern/ + +# 4. Check town config +cat ~/gt/mayor/town.json +# {"type":"town","version":1,"name":"..."} + +# 5. Check registered rigs +cat ~/gt/mayor/rigs.json +# {"version":1,"rigs":{"gastown":{...},"wyvern":{...}}} +``` + +## See Also + +- [Architecture Overview](architecture.md) - Full system architecture +- [Federation Design](federation-design.md) - Multi-machine deployment +- `gt doctor` - Health checks for harness and rigs