Gas Town Architecture
Technical architecture for Gas Town multi-agent workspace management.
Two-Level Beads Architecture
Gas Town uses a two-level beads architecture to separate organizational coordination from project implementation work.
| Level | Location | Prefix | Purpose |
|---|---|---|---|
| Town | ~/gt/.beads/ | hq-* | Cross-rig coordination, Mayor mail, agent identity |
| Rig | <rig>/mayor/rig/.beads/ | project prefix | Implementation work, MRs, project issues |
Town-Level Beads (~/gt/.beads/)
Organizational chain for cross-rig coordination:
- Mayor mail and messages
- Convoy coordination (batch work across rigs)
- Strategic issues and decisions
- Town-level agent beads (Mayor, Deacon)
- Role definition beads (global templates)
Rig-Level Beads (<rig>/mayor/rig/.beads/)
Project chain for implementation work:
- Bugs, features, tasks for the project
- Merge requests and code reviews
- Project-specific molecules
- Rig-level agent beads (Witness, Refinery, Polecats)
Agent Bead Storage
Agent beads track lifecycle state for each agent. Storage location depends on the agent's scope.
| Agent Type | Scope | Bead Location | Bead ID Format |
|---|---|---|---|
| Mayor | Town | ~/gt/.beads/ | hq-mayor |
| Deacon | Town | ~/gt/.beads/ | hq-deacon |
| Boot | Town | ~/gt/.beads/ | hq-boot |
| Dogs | Town | ~/gt/.beads/ | hq-dog-<name> |
| Witness | Rig | <rig>/.beads/ | <prefix>-<rig>-witness |
| Refinery | Rig | <rig>/.beads/ | <prefix>-<rig>-refinery |
| Polecats | Rig | <rig>/.beads/ | <prefix>-<rig>-polecat-<name> |
| Crew | Rig | <rig>/.beads/ | <prefix>-<rig>-crew-<name> |
Role Beads
Role beads are global templates stored in town beads with hq- prefix:
hq-mayor-role- Mayor role definitionhq-deacon-role- Deacon role definitionhq-boot-role- Boot role definitionhq-witness-role- Witness role definitionhq-refinery-role- Refinery role definitionhq-polecat-role- Polecat role definitionhq-crew-role- Crew role definitionhq-dog-role- Dog role definition
Each agent bead references its role bead via the role_bead field.
Agent Taxonomy
Town-Level Agents (Cross-Rig)
| Agent | Role | Persistence |
|---|---|---|
| Mayor | Global coordinator, handles cross-rig communication and escalations | Persistent |
| Deacon | Daemon beacon — receives heartbeats, runs plugins and monitoring | Persistent |
| Boot | Deacon watchdog — spawned by daemon for triage decisions when Deacon is down | Ephemeral |
| Dogs | Long-running workers for cross-rig batch work | Variable |
Rig-Level Agents (Per-Project)
| Agent | Role | Persistence |
|---|---|---|
| Witness | Monitors polecat health, handles nudging and cleanup | Persistent |
| Refinery | Processes merge queue, runs verification | Persistent |
| Polecats | Workers with persistent identity, assigned to specific issues | Persistent identity, ephemeral sessions |
| Crew | Human workspaces — full git clones, user-managed lifecycle | Persistent |
Directory Structure
~/gt/ Town root
├── .beads/ Town-level beads (hq-* prefix)
│ ├── metadata.json Beads config (dolt_mode, dolt_database)
│ └── routes.jsonl Prefix → rig routing table
├── .dolt-data/ Centralized Dolt data directory
│ ├── hq/ Town beads database (hq-* prefix)
│ ├── gastown/ Gastown rig database (gt-* prefix)
│ ├── beads/ Beads rig database (bd-* prefix)
│ └── <other rigs>/ Per-rig databases
├── daemon/ Daemon runtime state
│ ├── dolt-state.json Dolt server state (pid, port, databases)
│ ├── dolt-server.log Server log
│ └── dolt.pid Server PID file
├── deacon/ Deacon workspace
│ └── dogs/<name>/ Dog worker directories
├── mayor/ Mayor agent home
│ ├── town.json Town configuration
│ ├── rigs.json Rig registry
│ ├── daemon.json Daemon patrol config
│ └── accounts.json Claude Code account management
├── settings/ Town-level settings
│ ├── config.json Town settings (agents, themes)
│ └── escalation.json Escalation routes and contacts
├── config/
│ └── messaging.json Mail lists, queues, channels
└── <rig>/ Project container (NOT a git clone)
├── config.json Rig identity and beads prefix
├── mayor/rig/ Canonical clone (beads live here, NOT an agent)
│ └── .beads/ Rig-level beads (redirected to Dolt)
├── refinery/ Refinery agent home
│ └── rig/ Worktree from mayor/rig
├── witness/ Witness agent home (no clone)
├── crew/ Crew parent
│ └── <name>/ Human workspaces (full clones)
└── polecats/ Polecats parent
└── <name>/<rigname>/ Worker worktrees from mayor/rig
Note: No per-directory CLAUDE.md or AGENTS.md is created. Only ~/gt/CLAUDE.md
(town-root identity anchor) exists on disk. Full context is injected by gt prime
via SessionStart hook.
Worktree Architecture
Polecats and refinery are git worktrees, not full clones. This enables fast spawning
and shared object storage. The worktree base is mayor/rig:
// From polecat/manager.go - worktrees are based on mayor/rig
git worktree add -b polecat/<name>-<timestamp> polecats/<name>
Crew workspaces (crew/<name>/) are full git clones for human developers who need
independent repos. Polecat sessions are ephemeral and benefit from worktree efficiency.
Storage Layer: Dolt SQL Server
All beads data is stored in a single Dolt SQL Server process per town. There is
no embedded Dolt fallback — if the server is down, bd fails fast with a clear
error pointing to gt dolt start.
┌─────────────────────────────────┐
│ Dolt SQL Server (per town) │
│ Port 3307, managed by daemon │
│ Data: ~/gt/.dolt-data/ │
└──────────┬──────────────────────┘
│ MySQL protocol
┌──────┼──────┬──────────┐
│ │ │ │
USE hq USE gastown USE beads ...
Each rig database is a subdirectory under .dolt-data/. The daemon monitors
the server on every heartbeat and auto-restarts on crash.
For write concurrency, all agents write directly to main using transaction
discipline (BEGIN / DOLT_COMMIT / COMMIT atomically). This eliminates
branch proliferation and ensures immediate cross-agent visibility.
See dolt-storage.md for full details.
Beads Routing
The routes.jsonl file maps issue ID prefixes to rig locations (relative to town root):
{"prefix":"hq-","path":"."}
{"prefix":"gt-","path":"gastown/mayor/rig"}
{"prefix":"bd-","path":"beads/mayor/rig"}
Routes point to mayor/rig because that's where the canonical .beads/ lives.
This enables transparent cross-rig beads operations:
bd show hq-mayor # Routes to town beads (~/.gt/.beads)
bd show gt-xyz # Routes to gastown/mayor/rig/.beads
Beads Redirects
Worktrees (polecats, refinery, crew) don't have their own beads databases. Instead,
they use a .beads/redirect file that points to the canonical beads location:
polecats/alpha/.beads/redirect → ../../mayor/rig/.beads
refinery/rig/.beads/redirect → ../../mayor/rig/.beads
ResolveBeadsDir() follows redirect chains (max depth 3) with circular detection.
This ensures all agents in a rig share a single beads database via the Dolt server.
Merge Queue: Batch-then-Bisect
The refinery processes MRs through a batch-then-bisect merge queue (Bors-style). This is a core capability, not a pluggable strategy.
How It Works
MRs waiting: [A, B, C, D]
↓
Batch: Rebase A..D as a stack on main
↓
Test tip: Run tests on D (tip of stack)
↓
If PASS: Fast-forward merge all 4 → done
If FAIL: Binary bisect → test B (midpoint)
↓
If B passes: C or D broke it → bisect [C,D]
If B fails: A or B broke it → bisect [A,B]
Implementation Phases
| Phase | Bead | What | Status |
|---|---|---|---|
| 1: GatesParallel | gt-8b2i | Run test + lint concurrently per MR | In progress |
| 2: Batch-then-bisect | gt-i2vm | Bors-style batching with binary bisect | Blocked by Phase 1 |
| 3: Pre-verification | gt-lu84 | Polecats run tests before MR submission | Blocked by Phase 2 |
Gates (test command, lint, etc.) are pluggable. The batching strategy is core.
Design doc: produced by gt-yxx0 review.
Polecat Lifecycle: Self-Managed Completion
Polecats manage their own lifecycle end-to-end. The Witness observes but does NOT gate completion. This prevents the Witness from becoming a bottleneck.
Polecat Completion Flow
Polecat finishes work
→ Push branch to remote
→ Submit MR (bd update --mr-ready)
→ Update bead status
→ Tear down worktree
→ Go idle (available for next assignment)
The Witness monitors for stuck/zombie polecats (no activity for extended period) and nudges or escalates. It does NOT process completion — that's the polecat's job.
Design bead: gt-0wkk.
Data Plane Lifecycle
All beads data flows through a six-stage lifecycle managed by Dogs:
CREATE → LIVE → CLOSE → DECAY → COMPACT → FLATTEN
│ │ │ │ │ │
Dolt active done DELETE REBASE SQUASH
commit work bead rows commits all history
>7-30d together to 1 commit
Stages 1-3 are automated today. Stages 4-6 are being shipped via Dog automation (gt-at0i Reaper DELETE, gt-l8dc Compactor REBASE, gt-emm4 Doctor gc).
See dolt-storage.md for full details.
Deployment Artifacts
Gas Town and Beads are distributed through multiple channels. Tag pushes (v*)
trigger GitHub Actions release workflows that build and publish everything.
Gas Town (gt)
| Channel | Artifact | Trigger |
|---|---|---|
| GitHub Releases | Platform binaries (darwin/linux/windows, amd64/arm64) + checksums | GoReleaser on tag push |
| Homebrew | brew install steveyegge/gastown/gt — formula auto-updated on release | update-homebrew job pushes to steveyegge/homebrew-gastown |
| npm | npx @gastown/gt — wrapper that downloads the correct binary | OIDC trusted publishing (no token) |
| Local build | go build -o $(go env GOPATH)/bin/gt ./cmd/gt | Manual |
Beads (bd)
| Channel | Artifact | Trigger |
|---|---|---|
| GitHub Releases | Platform binaries + checksums | GoReleaser on tag push |
| Homebrew | brew install steveyegge/beads/bd | update-homebrew job |
| npm | npx @beads/bd — wrapper that downloads the correct binary | OIDC trusted publishing (no token) |
| PyPI | beads-mcp — MCP server integration | publish-pypi job with PYPI_API_TOKEN secret |
| Local build | go build -o $(go env GOPATH)/bin/bd ./cmd/bd | Manual |
npm Authentication
Both repos use OIDC trusted publishing — no NPM_TOKEN secret needed.
Authentication is handled by GitHub's OIDC provider. The workflow needs:
permissions:
id-token: write # Required for npm trusted publishing
Configure on npmjs.com: Package Settings → Trusted Publishers → link to the
GitHub repo and release.yml workflow file.
What the binary embeds
The Go binary is the primary distribution vehicle. It embeds:
- Role templates — Agent priming context, served by
gt prime - Formula definitions — Workflow molecules, served by
bd mol - Doctor checks — Health diagnostics, including migration checks
- Default configs —
daemon.jsonlifecycle defaults, operational thresholds
This means upgrading the binary automatically propagates most fixes. Files that
are NOT embedded (and require gt doctor or gt upgrade to update):
- Town-root
CLAUDE.md(created atgt installtime) daemon.jsonpatrol entries (created at install, extended byEnsureLifecycleDefaults)- Claude Code hooks (
.claude/settings.jsonmanaged sections) - Dolt schema (migrations run on first
bdcommand after upgrade)
See Also
- dolt-storage.md - Dolt storage architecture
- reference.md - Command reference
- molecules.md - Workflow molecules
- identity.md - Agent identity and BD_ACTOR