gt sling to town roles should use Town beads

## Problem

When Mayor starts from ~/gt (town root), `gt mol status` couldn't find beads pinned in rig beads.

## Solution

Added cross-rig scanning for town-level roles (mayor, deacon):
1. First check local beads directory
2. If nothing found AND target is a town-level role, scan all registered rigs
3. Return first pinned bead found

This makes `gt mol status` work correctly regardless of where Mayor is when checking hook status.

## Tested

1. `gt sling gt-552hb mayor` from gastown/mayor/rig/ - pins in rig beads ✓
2. `gt mol status` from ~/gt - finds the pinned bead via cross-rig scan ✓


Digest: mol-deacon-patrol

Patrol 17: All healthy


Digest: mol-deacon-patrol

Patrol #9: nominal


bd create should support molecule type

gt molecule commands expect type=molecule but bd validates against bug|feature|task|epic|chore|merge-request only


Move disk 3: C → A

Move disk 3 from peg C to peg A. (Move 476/1023)


Merge: slit-1767073379145

attached_args: Code review this merge request

branch: polecat/slit-1767073379145
target: main
source_issue: slit-1767073379145
rig: gastown

CODE REVIEW (valkyrie): REQUEST CHANGES

Critical bugs found in internal/swarm/manager.go:
1. JSON field changed from 'dependents' to 'dependencies' but bd outputs 'dependents'
2. 'hooked' status removed from in_progress handling
3. Assignee field removed from task loading

These changes will break swarm coordination. Polecat_spawn.go fix is correct.

Recommendation: Revert swarm/manager.go changes, keep polecat_spawn.go fix.


Digest: mol-deacon-patrol

Patrol cycle 73: All healthy


mol-deacon-patrol

Mayor's daemon patrol loop.

The Deacon is the Mayor's background process that runs continuously, handling callbacks, monitoring rig health, and performing cleanup. Each patrol cycle runs these steps in sequence, then loops or exits.

## Second-Order Monitoring

Witnesses send WITNESS_PING messages to verify the Deacon is alive. This
prevents the "who watches the watchers" problem - if the Deacon dies,
Witnesses detect it and escalate to the Mayor.

The Deacon's agent bead last_activity timestamp is updated during each patrol
cycle. Witnesses check this timestamp to verify health.


Move disk 1: C → A

Move disk 1 from peg C to peg A. (Move 383/1023)


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 43/1023)


Add compaction recovery protocol to role templates

After context compaction (summarization), agents may be disoriented.

Add guidance to recognize and recover:
- 'If you feel you've lost earlier context or are disoriented, run: gt prime'
- 'This re-injects your role, current work, and pending messages'
- 'It's safe to prime multiple times - it just outputs context'

This is the fallback path when self-check is missed and compaction happens.
Compaction isn't catastrophic if priming is robust.


Add gt crew rename command


mol-deacon-patrol


Set GIT_AUTHOR_NAME per agent session

Set GIT_AUTHOR_NAME to actor string (e.g., gastown/crew/joe) in agent session environment. GIT_AUTHOR_EMAIL stays as workspace owner. Enables git log --author queries for agent work.


Move disk 3: C → A

Move disk 3 from peg C to peg A. (Move 1004/1023)


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 931/1023)


Move disk 3: A → B

Move disk 3 from peg A to peg B. (Move 820/1023)


Instrument gt commands to appear in activity feed

## Architecture: Two-tier event system

```
┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│ gt commands │  │ bd mutations│  │ agent output│
└──────┬──────┘  └──────┬──────┘  └──────┬──────┘
       └────────────────┼────────────────┘
                        ▼
              ~/gt/.events.jsonl (raw, audit)
                        │
              ┌─────────────────┐
              │  Feed daemon    │ ← goroutine in gt daemon
              │  - filters      │
              │  - aggregates   │
              │  - AI curates   │
              └────────┬────────┘
                       ▼
              ~/gt/.feed.jsonl (curated, user-facing)
```

## Event format

```json
{
  "ts": "2025-12-28T10:30:15Z",
  "source": "gt",
  "type": "sling",
  "actor": "mayor",
  "payload": {"bead": "gt-xyz", "target": "gastown/Toast"},
  "visibility": "feed"
}
```

Visibility: `audit` | `feed` | `both`

## Implementation phases

1. **Event logging** - gt commands write to ~/gt/.events.jsonl
2. **Feed daemon** - goroutine in gt daemon tails events, writes curated feed
3. **Feed readers** - gt feed, gt dashboard read from .feed.jsonl
4. **AI curation** - future: haiku summarization for complex activity

Part of epic gt-u7dxq


Digest: mol-deacon-patrol

Patrol complete: routine cycle


Implement Boot: daemon entry point dog for Deacon triage

Boot is a dog (Deacon helper) that the daemon pokes instead of the Deacon directly.

Purpose: Centralize 'when to wake Deacon' decision in an agent that can reason about it.

Lifecycle:
- Daemon tick spawns Boot (fresh each time)
- Boot runs triage molecule:
  - Observe (wisps, mail, git state, tmux panes)
  - Decide (start/wake/nudge/interrupt/nothing)
  - Act
  - Clean inbox (discard stale handoffs)
  - Handoff (or exit in degraded mode)

Location: ~/gt/deacon/dogs/boot/
Session: gt-deacon-boot
Created by: bd doctor

Needs:
- Boot formula (mol-boot-triage.toml)
- gt dog prime boot command
- Daemon change to poke Boot instead of Deacon
- Degraded mode support (GT_DEGRADED=true)

See: gastown/mayor/rig/docs/operational-state.md


Digest: mol-deacon-patrol

Patrol 15: Mayor OK, 11 sessions


Merge: slit-1767079899677

branch: polecat/slit-1767079899677
target: main
source_issue: slit-1767079899677
rig: gastown


Draft mol-ready-work protomolecule definition

Draft the actual protomolecule definition in markdown format.

## Molecule Structure

```markdown
## Molecule: ready-work
Autonomous backlog processing patrol for crew workers.

Phase: vapor (wisp) - ephemeral patrol cycles
Squash: after each work item or context threshold

## Step: orient
Load context and check for interrupts:
- Read mail for overseer instructions
- Check for predecessor handoff
- Load current context state

## Step: scan-backlogs
Survey all backlogs in priority order:
1. gh pr list --state open
2. gh issue list --state open --label untriaged (or no label)
3. bd ready
4. gh issue list --state open --label triaged

Capture counts and candidates.

Needs: orient

## Step: select-work
Apply ROI heuristic to select best work item:
- Estimate size (tokens needed)
- Check remaining context capacity
- Weight by impact (priority, type)
- Select highest ROI achievable item
- If empty: exit patrol

Needs: scan-backlogs

## Step: execute-work
Work the selected item:
- For PRs: review, request changes, or merge
- For untriaged: triage and label
- For beads: implement and close
- For triaged GH: implement fix

Commit, push, close/update as appropriate.

Needs: select-work

## Step: check-context
Assess context state:
- Estimate remaining capacity
- If < 20%: goto handoff
- If ok: loop to scan-backlogs

Needs: execute-work

## Step: handoff
Prepare for session transition:
- Summarize work completed this cycle
- Note any in-progress items
- Send handoff mail to self
- Squash wisp to digest
- Exit for fresh session

Needs: check-context
```

## Variables

- `backlog_priority`: Override backlog scan order
- `context_threshold`: Percentage at which to handoff (default: 20)
- `max_items`: Maximum items to process per session

## Notes

- This is a vapor-phase molecule (wisp)
- Each work item should squash to a digest
- The patrol itself squashes at handoff


Digest: mol-deacon-patrol

Patrol #4: All systems nominal


mol-sync-workspace: Fix 'commits ahead' in report for crew on main


Build rig/worker tree view component

Bubbletea component showing hierarchical rig list with workers. Each rig expandable to show workers. Each worker shows: status indicator, current molecule title, step progress (X/Y), time since last activity.


Digest: mol-deacon-patrol

Patrol cycle 6: all healthy


Digest: mol-deacon-patrol

Patrol cycle 5: All healthy


gt rig shutdown: Gracefully stop all rig agents

Add 'gt rig shutdown <rig>' command to gracefully stop all agents in a rig.

Should:
- Stop all polecat sessions
- Stop refinery
- Stop witness
- Optionally wait for graceful shutdown with timeout


Digest: mol-deacon-patrol

Patrol 8: Routine


Add crew auto-start config to gt start

gt start needs a config file to specify:
- Which crew members auto-start per rig
- Which rigs to auto-start (instead of requiring --all or --rigs flags)

Requested defaults:
- beads rig: dave
- gastown rig: max, joe

This would allow 'gt start' to bring up the configured crew without manual flags.


Messaging Channels: Unified list/queue/announce/nudge system

Implement the full messaging channel system for Gas Town.

TWO PARALLEL SYSTEMS:
1. Durable (polling): mail - list, queue, announce
2. Real-time (ephemeral): nudge - channels

ARCHITECTURE:
- Config: ~/gt/config/messaging.json (town-level)
- Messages: beads (.beads/issues.jsonl with type=message)

CHANNEL TYPES:
- list:name - Fan-out, each recipient gets copy (DONE)
- queue:name - Claim-based, exactly-once processing (gt-02431)
- announce:name - Bulletin board, read-only (gt-cqvgt)
- nudge channel:name - Real-time fan-out (gt-3txyh)

PRIORITY ORDER:
1. Queues - solves real polecat cleanup race condition
2. Nudge channels - gt broadcast mostly works but channels add precision
3. Announces - nice-to-have bulletin boards


Digest: mol-deacon-patrol @ 2025-12-24 19:27

Patrol 14


Digest: mol-deacon-patrol

Patrol cycle 16: nominal


Digest: mol-deacon-patrol

Patrol complete: 0 messages, agents healthy, no cleanup needed


Digest: mol-deacon-patrol

Patrol 19: All healthy


Digest: mol-deacon-patrol

Patrol 117: All healthy


Digest: mol-deacon-patrol

Patrol 11: all quiet


Add 'wit' alias for witness command

ref works as alias for refinery, but wit doesn't work for witness. Add Aliases: []string{"wit"} to witnessCmd.


mol-deacon-patrol

Mayor's daemon patrol loop.

The Deacon is the Mayor's background process that runs continuously, handling callbacks, monitoring rig health, and performing cleanup. Each patrol cycle runs these steps in sequence, then loops or exits.

## Second-Order Monitoring

Witnesses send WITNESS_PING messages to verify the Deacon is alive. This
prevents the "who watches the watchers" problem - if the Deacon dies,
Witnesses detect it and escalate to the Mayor.

The Deacon's agent bead last_activity timestamp is updated during each patrol
cycle. Witnesses check this timestamp to verify health.


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 253/1023)


Digest: mol-deacon-patrol @ 2025-12-24 19:47

Patrol 15: All healthy


Digest: mol-deacon-patrol

Patrol 17: 3 rigs healthy


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 921/1023)


Digest: mol-deacon-patrol

Patrol 3: All healthy, no incidents


Witness MVP: Automated Polecat Lifecycle

Implement the Witness agent - per-rig 'pit boss' that manages polecat lifecycles.

The Witness enables hands-free swarming by automating:
- Spawning polecats for ready work
- Monitoring worker health
- Processing shutdown requests
- Cleaning up worktrees when done
- Escalating stuck workers to Mayor

Without Witness, humans must manually spawn, monitor, and kill each polecat.

## Core Loop

```
while True:
  # Handle pending shutdowns
  for polecat in polecats where state == pending_shutdown:
    verify git clean
    kill session
    remove worktree
    delete branch

  # Spawn for ready work
  ready = bd ready --parent=<epic> if epic else bd ready
  for issue in ready:
    if active_workers < max_workers:
      gt spawn --issue <id>

  # Check worker health
  for polecat in active polecats:
    if stuck (no progress for 30 min):
      nudge or escalate

  sleep 60
```

## Blocking Bugs to Fix
- gt-dsfi: handoff deadlock
- gt-n7z7: refinery foreground race condition
- gm-c6b: mail coordination (town vs rig beads)


Merge: gt-h6eq.3

branch: polecat/nux
target: main
source_issue: gt-h6eq.3
rig: gastown


mol-deacon-patrol


bd mol search: Find formulas using GitHub API

Search for formulas across GitHub.

Usage: bd mol search <query>

Should:
- Use GitHub API to search repos with formula.json
- Filter by topics (e.g., beads-formula)
- Display results with descriptions and stars
- Support pagination


Digest: mol-deacon-patrol

Patrol 8: quick pass


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 841/1023)


Port Gas Town to Go

Complete rewrite of Gas Town in Go for improved performance and single-binary distribution.

## Goals
- Single installable binary (gt)
- All Python functionality ported
- Federation support built-in
- Improved performance

## Phases
1. Core infrastructure (config, workspace, git wrapper)
2. Rig & polecat management
3. Session & tmux operations
4. Mail system
5. CLI commands
6. TUI (optional)


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 463/1023)


Witness for gastown - monitors polecat health and progress.

role_type: witness
rig: gastown
agent_state: dead
hook_bead:
role_bead: gt-witness-role

Marked dead by daemon at 2026-01-02T02:35:24-08:00 (was running, last update too old)


Swarm: ephemeral rig support

PGT has ephemeral rigs for swarms - temporary worker groups that are destroyed after landing.

Missing Features:
- gt swarm init [--rig <name>|--git-url <url>] [--num-workers N]
- gt swarm worker add/remove/list <rig-id>
- gt swarm rigs - List ephemeral rigs
- gt swarm destroy <rig-id> - Destroy ephemeral rig

Directory structure:
<workspace>/mayor/workers/<rig-id>/
├── rig.json (metadata)
├── alice/ (git clone)
├── bob/
└── carol/

PGT Reference: gastown-py/src/gastown/ephemeral.py

Note: Beads issue gt-kmn.12 mentions this but implementation is missing.


Add timeouts to convoy panel subprocess calls

convoy.go spawns bd and sqlite3 without timeouts. If these hang, the TUI freezes. Add 5-second context timeouts.


Digest: mol-deacon-patrol

Patrol cycle 4: routine, healthy


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 141/1023)


Polecat: Clean exit after MR submission

Update polecat workflow to be truly ephemeral after MR submission.

## Current Behavior
- Polecat submits MR
- Polecat waits for merge or rebase request
- Session stays alive, sandbox persists

## New Behavior
- Polecat submits MR
- Polecat closes its work bead (status=in_review or similar)
- Polecat signals 'recyclable' to Witness
- Sandbox can be cleaned up after branch is pushed

## Implementation
1. Update mol-polecat-work.formula.toml
2. Add explicit 'submit and exit' step
3. Ensure branch is pushed before sandbox cleanup
4. Signal Witness that polecat is recyclable

## Considerations
- Sandbox cleanup can be deferred (worktrees are cheap)
- Or: Witness runs cleanup patrol for idle polecats

Implemented: Updated mol-polecat-work.formula.toml (v4) for ephemeral polecat model. Polecats now submit via gt done and become recyclable. No longer wait for Witness termination or close their own issues.


Digest: mol-deacon-patrol

Patrol 159: All healthy


Phase 4: Deacon Patrol Loop

$(cat /tmp/phase4.md)


Digest: mol-deacon-patrol

Patrol 2: All healthy, 12 polecats, nudged gastown (active work)


Digest: mol-deacon-patrol

Patrol cycle 9: All healthy


Move disk 2: C → B

Move disk 2 from peg C to peg B. (Move 126/1023)


gt status should show runtime state, not just structure

## Problem
`gt status` shows structural info (which crews exist) but not runtime reality (which sessions are running).

## Current Output
- Shows 'Crews: [dave emma zoey]' but doesn't indicate dave is crashed
- Missing Deacon from output entirely
- Hooks shown but unclear if agents are alive

## Expected
- Show which tmux sessions are actually running
- Indicate crashed/missing sessions with warning
- Include all roles (Mayor, Deacon, Witnesses, Refineries, Crews)
- Distinguish between:
  - Structure: what COULD run
  - Runtime: what IS running

## Example Better Output
```
Agents
   mayor          ✓ running (gt-mayor)
   deacon         ✓ running (gt-deacon)

Rigs
   beads
      witness     ✓ running
      refinery    ✓ running
      crew/dave   ✗ CRASHED (session missing)
      crew/emma   ✓ running
   gastown
      witness     ✓ running
      refinery    ✓ running
      crew/max    ✗ CRASHED (session missing)
```


Move disk 4: B → A

Move disk 4 from peg B to peg A. (Move 1000/1023)


Digest: mol-deacon-patrol

Patrol cycle 1: inbox clear, 8 in-progress issues, sessions healthy, gc not implemented


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 555/1023)


Day 2.6: Define bd agent state command

Add command for agents to write their own state to agent beads.

```bash
bd agent state <agent-id> <state>
# Example: bd agent state gt-mayor running
# States: idle | running | stuck | stopped | dead
```

Implementation:
1. Lookup agent bead by ID
2. Update state field
3. Update last_activity timestamp
4. Trigger bd sync if configured

Also add:
- bd agent heartbeat <agent-id> - just updates last_activity
- bd agent show <agent-id> - show agent bead details

This is the ZFC-compliant way for agents to self-report state.

Delegated to beads repo: bd-uxlb. Assign to beads/crew/dave.


CloudRunOutpost: Basic implementation

## Overview

Basic CloudRunOutpost implementation. Persistent connections and cost tracking are separate tasks.

## Implementation

```go
type CloudRunOutpost struct {
    name        string
    project     string
    region      string
    service     string
    maxWorkers  int
    client      *WorkClient
    workers     map[string]*CloudRunWorker
    mu          sync.RWMutex
}

func NewCloudRunOutpost(cfg OutpostConfig) (*CloudRunOutpost, error) {
    serviceURL := fmt.Sprintf(
        "https://%s-%s.a.run.app",
        cfg.Service, cfg.Region,
    )
    return &CloudRunOutpost{
        name:       cfg.Name,
        project:    cfg.Project,
        region:     cfg.Region,
        service:    cfg.Service,
        maxWorkers: cfg.MaxWorkers,
        client:     NewWorkClient(serviceURL),
        workers:    make(map[string]*CloudRunWorker),
    }, nil
}
```

## Spawn

```go
func (o *CloudRunOutpost) Spawn(issue string, cfg WorkerConfig) (Worker, error) {
    req := WorkRequest{
        IssueID: issue,
        Rig:     RigConfig{URL: cfg.RigURL, Branch: cfg.GitBranch},
        Beads:   BeadsConfig{URL: cfg.BeadsURL, Branch: "beads-sync"},
        Branch:  "polecat/" + issue,
    }

    events, err := o.client.DispatchWork(context.Background(), req)
    if err != nil {
        return nil, err
    }

    worker := &CloudRunWorker{
        id:      uuid.New().String(),
        outpost: o.name,
        issue:   issue,
        events:  events,
        status:  WorkerStatusWorking,
    }

    o.mu.Lock()
    o.workers[worker.id] = worker
    o.mu.Unlock()

    go worker.monitor()
    return worker, nil
}
```

## CloudRunWorker

```go
type CloudRunWorker struct {
    id      string
    outpost string
    issue   string
    status  WorkerStatus
    events  <-chan WorkEvent
    logs    []string
}

func (w *CloudRunWorker) Attach() error {
    return errors.New("Cloud Run workers do not support attach")
}

func (w *CloudRunWorker) Logs() (io.Reader, error) {
    return strings.NewReader(strings.Join(w.logs, "\n")), nil
}
```

## Files

- `internal/outpost/cloudrun.go`

## Dependencies

Depends on: gt-9a2.1 (interfaces), gt-9a2.12 (HTTP client)
Blocks: gt-9a2.13 (persistent connections), gt-9a2.14 (cost tracking)


Move disk 1: C → A

Move disk 1 from peg C to peg A. (Move 461/1023)


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 349/1023)


Digest: mol-deacon-patrol

Patrol 5: Quiet


Digest: mol-deacon-patrol

Patrol complete: beads witness+refinery came online, both rigs healthy


Digest: mol-deacon-patrol

Patrol 13


Remove keepalive file infrastructure

The keepalive mechanism (~/gt/daemon/activity.json) is deprecated in favor of feed-based wake.

TODO:
1. Remove keepalive.TouchTownActivity() calls from gt commands
2. Remove keepalive.ReadTownActivity() from daemon
3. Delete internal/keepalive package
4. Update daemon to use longer base heartbeat (recovery-focused)

Whitelist consideration: Some read-only commands might need to wake (TBD - none identified yet)


gt-gastown-polecat-ace

gt-gastown-polecat-ace

role_type: polecat
rig: gastown
agent_state: done
hook_bead: null
role_bead: gt-polecat-role
cleanup_status: has_uncommitted
active_mr: gt-kwnj1
notification_level: null


Polecat template: remove redundant 'Finding Work' section

The 'Finding Work' section (bd ready, bd list, bd show) is general-purpose guidance that may not apply to polecats who are spawned with specific work. Either remove for polecats or clarify this is for discovering additional work during execution.


Add 'gt account list' command

Show registered accounts from accounts.yaml. Mark default with asterisk. Show handle, email, description.


Execute registered plugins

Execute registered plugins.

Scan ~/gt/plugins/ for plugin directories. Each plugin has a plugin.md with
YAML frontmatter defining its gate (when to run) and instructions (what to do).

See docs/deacon-plugins.md for full documentation.

Gate types:
- cooldown: Time since last run (e.g., 24h)
- cron: Schedule-based (e.g., "0 9 * * *")
- condition: Metric threshold (e.g., wisp count > 50)
- event: Trigger-based (e.g., startup, heartbeat)

For each plugin:
1. Read plugin.md frontmatter to check gate
2. Compare against state.json (last run, etc.)
3. If gate is open, execute the plugin

Plugins marked parallel: true can run concurrently using Task tool subagents.
Sequential plugins run one at a time in directory order.

Skip this step if ~/gt/plugins/ does not exist or is empty.


Refinery patrol: Add sibling-check step

Refinery should check on Witness health as part of patrol (village sibling watch).

## Implementation

1. Add `sibling-check` step to mol-refinery-patrol (early in cycle)
2. Use `gt peek <rig>/witness 20` to check Witness output
3. Look for signs of health:
   - Recent activity (tool calls, log messages)
   - No error stack traces
   - Responsive to pings
4. If Witness seems stuck:
   - Send status request mail
   - Note for potential escalation
   - Don't block Refinery work

## Acceptance
- Refinery checks Witness each patrol cycle
- Anomalies logged
- Non-blocking (Refinery continues even if Witness is down)


Digest: mol-deacon-patrol

Patrol 3: inbox clear, all healthy


Digest: mol-deacon-patrol

Patrol 18: all healthy


Test message

Testing GGT mail integration


mol-deacon-patrol

Mayor's daemon patrol loop.

The Deacon is the Mayor's background process that runs continuously, handling callbacks, monitoring rig health, and performing cleanup. Each patrol cycle runs these steps in sequence, then loops or exits.

## Second-Order Monitoring

Witnesses send WITNESS_PING messages to verify the Deacon is alive. This
prevents the "who watches the watchers" problem - if the Deacon dies,
Witnesses detect it and escalate to the Mayor.

The Deacon's agent bead last_activity timestamp is updated during each patrol
cycle. Witnesses check this timestamp to verify health.


Move disk 2: A → C

Move disk 2 from peg A to peg C. (Move 146/1023)


Digest: mol-deacon-patrol

Patrol 3: OK


Implement gt mol attach-from-mail command

Allow agents to self-pin work from mail.

Usage: gt mol attach-from-mail <mail-id>

Behavior:
1. Read mail body for attached_molecule field
2. Attach molecule to agent's hook
3. Mark mail as read
4. Return control for execution

Handles case where work was sent via mail but not slung to hook.


Aggregate arm results

Collect outcomes from all polecat inspection arms.

This is a **fanout gate** - it cannot proceed until ALL dynamically-bonded
polecat arms have completed their inspection cycles.

Once all arms complete, collect their outcomes:
- Actions taken per polecat (nudge, kill, escalate, none)
- Updated nudge counts
- Any errors or issues discovered

Build the consolidated state for save-state.


Digest: mol-deacon-patrol

Patrol 214: All nominal


Add convoy_test.go tests

convoy.go (525 lines) has no test coverage


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 577/1023)


Move disk 2: C → B

Move disk 2 from peg C to peg B. (Move 750/1023)


Digest: mol-deacon-patrol

Patrol 4 complete. All healthy.


Digest: mol-deacon-patrol

Patrol 8: clear


Witness Plugin System

Patrol extensions via molecule bonding.

## Core Insight

Plugins ARE molecules. No separate format needed.

## How It Works

```
mol-witness-patrol
    │
    ├── survey-workers
    │
    ├── plugin-run ←── bonds registered plugin molecules
    │       │
    │       ├── mol-mood-check (if registered)
    │       ├── mol-security-scan (if registered)
    │       └── mol-custom-X (user-installed)
    │
    └── aggregate (WaitsFor: all-children)
```

## Plugin Molecule Structure

A plugin is just a molecule proto with specific labels:

```json
{
  "id": "mol-mood-check",
  "title": "Polecat Mood Check",
  "description": "Assess polecat emotional state from output. Vars: {{polecat_name}}, {{captured_output}}",
  "labels": ["template", "plugin", "witness", "tier:haiku"],
  "issue_type": "task"
}
```

Labels encode metadata:
- `plugin` - marks as bondable plugin
- `witness` / `deacon` / `refinery` - which patrol can use it
- `tier:haiku` / `tier:sonnet` - model tier hint

## Registration

Plugins registered in rig config or molecules.jsonl:

```bash
# Install from Mol Mall
bd mol install mol-mood-check

# Or add to ~/.beads/molecules.jsonl manually
```

## Execution

The `plugin-run` step in patrol:

```bash
# For each registered plugin molecule matching this patrol:
bd mol bond mol-mood-check $PATROL_WISP \
  --ref mood-{{polecat_name}} \
  --var polecat_name=$POLECAT \
  --var captured_output="$OUTPUT"
```

## CLI

- `bd mol list --label plugin` - List available plugins
- `bd mol install <id>` - Install from Mol Mall
- `gt patrol plugins <role>` - Show plugins for a patrol role

## Benefits

- No YAML schema to maintain
- No separate plugin loading code
- Plugins are versioned, synced, auditable (they are beads)
- Distribution via Mol Mall (molecules.jsonl registry)
- Same {{var}} substitution as all molecules


Witness: Verify MR submission on notification

When Witness receives `LIFECYCLE: mr submitted`, verify the submission was clean.

## Implementation

1. Add handler for "LIFECYCLE: mr submitted" mail
2. Check MR status: `gt mq status <mr-id>`
3. If MR looks good (status=open, no errors): log success, allow polecat to idle
4. If MR has issues:
   - Check polecat git state
   - Nudge polecat to fix if session still alive
   - Log issue for monitoring

## Acceptance
- Witness verifies MR after submission notification
- Can detect problematic submissions
- Provides early intervention opportunity


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 183/1023)


Move disk 1: C → A

Move disk 1 from peg C to peg A. (Move 665/1023)


Digest: mol-deacon-patrol

Patrol cycle 21: All 3 witnesses and refineries healthy, no orphans, no gates, inbox clean


mol-deacon-patrol


Digest: mol-deacon-patrol

Patrol 17: All clear


Refinery: Implement mechanical rebase in-place

Update refinery to handle mechanical rebases without dispatching.

## Current Behavior
- Refinery detects rebase needed
- Sends mail to polecat asking for rebase
- Waits for polecat response

## New Behavior
- Refinery attempts `git rebase origin/main`
- If success (no conflicts): proceed to tests/merge
- If conflicts: abort, create conflict-resolution task

## Implementation
1. Update mol-refinery-patrol.formula.toml
2. Add rebase step between 'fetch' and 'test'
3. Handle conflict detection (exit code, conflict markers)
4. On conflict: `git rebase --abort`, create task, skip MR

## Tests
- Mechanical rebase succeeds
- Conflict detected and aborted
- Conflict task created with correct metadata


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 67/1023)


Digest: mol-deacon-patrol

Cycle 5: 2 acks


Document Rig/Cook/Run lifecycle

The rig-cook-run.md spec is written. Propagate terminology to all relevant docs: - molecule-algebra.md (done) - molecular-chemistry.md (done) - vision.md (done) - propulsion-principle.md - sling-design.md - Any agent templates that reference cooking/instantiation


Digest: mol-deacon-patrol @ 2025-12-24 19:48

Patrol 20: All healthy


gt doctor: Check settings.json hook consistency across town

## Problem

Settings.json files in different locations can become out of sync, causing session_id
passthrough to fail for some roles but not others. This happened when:
- Town root was updated to use session-start.sh
- Rig root still had old 'gt prime' direct call
- Mayor/rig had mixed state

## Locations to Check

1. `~/gt/.claude/settings.json` (town root - Mayor uses this)
2. `~/gt/<rig>/.claude/settings.json` (rig root - polecats/crew use this)
3. `~/gt/<rig>/mayor/rig/.claude/settings.json` (mayor/rig - source of truth)

## Check Logic

For SessionStart and PreCompact hooks, verify all use `session-start.sh`:
- Must contain `bash ~/.claude/hooks/session-start.sh` (or full path)
- Warn if any use bare `gt prime` without session-start.sh wrapper

## Output

```
gt doctor
...
session-hooks: ✓ All settings.json files use session-start.sh
# or
session-hooks: ✗ ~/gt/gastown/.claude/settings.json uses bare 'gt prime' (missing session_id passthrough)
```

## Fix Suggestion

When inconsistency found, suggest:
```
Hint: Update SessionStart/PreCompact hooks to use 'bash ~/.claude/hooks/session-start.sh'
      This enables session_id passthrough for gt seance discovery.
```

## Related

- session-start.sh extracts session_id from Claude Code stdin JSON
- gt prime outputs [GAS TOWN] metadata line for seance
- gt seance discovers sessions from .events.jsonl


Digest: mol-deacon-patrol

Patrol cycle 56: All healthy


mol-deacon-patrol

Mayor's daemon patrol loop.

The Deacon is the Mayor's background process that runs continuously, handling callbacks, monitoring rig health, and performing cleanup. Each patrol cycle runs these steps in sequence, then loops or exits.

## Idle Town Principle

**The Deacon should be silent/invisible when the town is healthy and idle.**

- Skip HEALTH_CHECK nudges when no active work exists
- Sleep 60+ seconds between patrol cycles (longer when idle)
- Let the feed subscription wake agents on actual events
- The daemon (10-minute heartbeat) is the safety net for dead sessions

This prevents flooding idle agents with health checks every few seconds.

## Second-Order Monitoring

Witnesses send WITNESS_PING messages to verify the Deacon is alive. This
prevents the "who watches the watchers" problem - if the Deacon dies,
Witnesses detect it and escalate to the Mayor.

The Deacon's agent bead last_activity timestamp is updated during each patrol
cycle. Witnesses check this timestamp to verify health.


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 603/1023)


Digest: mol-deacon-patrol

Patrol 5: All healthy


mol-deacon-patrol

Mayor's daemon patrol loop.

The Deacon is the Mayor's background process that runs continuously, handling callbacks, monitoring rig health, and performing cleanup. Each patrol cycle runs these steps in sequence, then loops or exits.

## Second-Order Monitoring

Witnesses send WITNESS_PING messages to verify the Deacon is alive. This
prevents the "who watches the watchers" problem - if the Deacon dies,
Witnesses detect it and escalate to the Mayor.

The Deacon's agent bead last_activity timestamp is updated during each patrol
cycle. Witnesses check this timestamp to verify health.


Move disk 1: C → A

Move disk 1 from peg C to peg A. (Move 509/1023)


save-state

Update handoff bead with new state.

Persist nudge counts and pending actions.

Needs: execute-actions


Move disk 2: C → B

Move disk 2 from peg C to peg B. (Move 726/1023)


done

Exit received. Ready for cleanup.

The polecat has completed its work and sent SHUTDOWN.
Perform cleanup:
```bash
gt session kill {{polecat}}
gt worktree prune {{polecat}}
```

Update beads state and close the lease.
Variables: {{polecat}}, {{issue}}


Agent parking and resuming

Implement gt park and gt resume commands. Agent parks work on a gate, state persists across sessions. When gate condition met, Deacon sends wake mail. Agent resumes from parked state. Critical for async workflows.


mol-witness-patrol molecule definition

Create mol-witness-patrol in builtin_molecules.go.

## Steps (10 total)
1. inbox-check - Process witness mail (lifecycle, help requests)
2. load-state - Read handoff bead, get nudge counts
3. survey-workers - gt polecat list, categorize by status
4. inspect-workers - tmux capture-pane for each 'working' polecat
5. decide-actions - Apply nudge matrix, queue actions
6. execute-actions - Nudge, kill, or escalate as decided
7. save-state - Update handoff bead with new states
8. generate-summary - Summarize cycle for digest
9. context-check - Check own context usage
10. burn-or-loop - Squash wisp, then loop or cycle session

## Key Behaviors
- Uses wisp storage (.beads-wisp/)
- Reads/writes witness handoff bead for state persistence
- Progressive nudging (3 levels before escalate)
- Pre-kill verification before killing polecats

## Reference
- See prompts/roles/witness.md for protocol details
- See mol-refinery-patrol for similar structure
- Parent epic: gt-aqd8


Move disk 1: C → A

Move disk 1 from peg C to peg A. (Move 707/1023)


mol-deacon-patrol


CLI: core commands (status, prime, version, init)

Essential CLI commands for Gas Town operation.

## Commands

### gt status
Show overall town status.
```
gt status [--json]
```
Output:
- Town name and location
- Number of rigs
- Active polecats across all rigs
- Witness status per rig
- Recent activity summary

### gt prime
Output role context for current directory.
```
gt prime
```
Detects role from directory:
- Town root or mayor/ → Mayor context
- <rig>/witness/rig/ → Witness context
- <rig>/refinery/rig/ → Refinery context
- <rig>/polecats/<name>/ → Polecat context

### gt version
Show version information.
```
gt version [--short]
```
Output: version, git commit, build date.

### gt init
Initialize current rig for Gas Town (alternative to gt install for existing repos).
```
gt init [--force]
```
Creates Gas Town structure in existing git repo.

## Implementation

Each command is a Cobra subcommand under root:
```go
var statusCmd = &cobra.Command{...}
var primeCmd = &cobra.Command{...}
var versionCmd = &cobra.Command{...}
var initCmd = &cobra.Command{...}
```

Register in cmd/gt/main.go.


Digest: mol-deacon-patrol

Patrol 82: All agents healthy, quiet cycle


Digest: mol-deacon-patrol

Patrol complete: all agents healthy, no orphans, 0 inbox messages


Merge: gt-3x0z.1

branch: polecat/furiosa
target: main
source_issue: gt-3x0z.1
rig: gastown


Digest: mol-deacon-patrol

Patrol 4: Quick cycle, all quiet


Move disk 1: C → A

Move disk 1 from peg C to peg A. (Move 119/1023)


Move disk 3: C → A

Move disk 3 from peg C to peg A. (Move 92/1023)


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 465/1023)


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 549/1023)


Digest: mol-deacon-patrol

Patrol cycle 9: all healthy


Digest: mol-deacon-patrol

Patrol 12


gt crew remove: Does not close agent bead

When running 'gt crew remove <name>', the command removes the crew workspace directory but does not close the associated agent bead (gt-<rig>-crew-<name>).

This leaves orphaned agent beads in the system after crew removal.

The remove command should close the agent bead with a reason like 'Crew workspace removed'.


Digest: mol-deacon-patrol

Patrol 211: All nominal


gt spawn: add --polecat flag for explicit worker selection

Currently gt spawn requires positional arg format:
```
gt spawn gastown/Angharad --issue gt-xyz
```

But I tried the more intuitive flag form:
```
gt spawn --issue gt-xyz --polecat Angharad
```

This failed with 'unknown flag: --polecat'.

The flag form is more discoverable and consistent with other commands. Add --polecat flag as alternative to positional arg.


Implement gt hooks command

New command to show all hooks across a rig.

Usage: gt hooks [rig]

Output shows:
- All polecats and their hook status
- Witness hook status
- Refinery hook status
- Crew member hook status
- Progress bars for attached molecules


Day 2.7c: gt doctor checks agent beads exist

Add gt doctor check: agent-beads-exist

1. For town-level: verify gt-deacon and gt-mayor beads exist
2. For each rig: verify gt-witness-<rig> and gt-refinery-<rig> beads exist
3. Report missing beads as warnings
4. Implement --fix to create missing beads

Files:
- internal/doctor/agent_beads_check.go (new)
- internal/cmd/doctor.go (register check)


Digest: mol-deacon-patrol

Patrol 2: Routine cycle. All rigs healthy. 12 polecats. No incidents.


Digest: mol-deacon-patrol

Patrol OK: 8 polecats, 4 witness/refineries up


Digest: mol-deacon-patrol

Patrol 19: quick pass


Digest: mol-deacon-patrol

Patrol cycle 55: All healthy


HTTP work client: CloudRun dispatch client

## Overview

HTTP client for dispatching work to Cloud Run and streaming results back.

## Implementation

```go
type WorkClient struct {
    serviceURL string
    httpClient *http.Client  // HTTP/2 enabled
}

func NewWorkClient(serviceURL string) *WorkClient {
    return &WorkClient{
        serviceURL: serviceURL,
        httpClient: &http.Client{
            Transport: &http2.Transport{},
            Timeout:   0,  // No timeout for streaming
        },
    }
}

func (c *WorkClient) DispatchWork(ctx context.Context, req WorkRequest) (<-chan WorkEvent, error) {
    // 1. POST to /work
    // 2. Return channel that streams WorkEvents
    // 3. Close channel when done/error
}
```

## Streaming Reader

```go
func (c *WorkClient) streamEvents(body io.Reader, events chan<- WorkEvent) {
    defer close(events)
    decoder := json.NewDecoder(body)
    for {
        var event WorkEvent
        if err := decoder.Decode(&event); err != nil {
            return
        }
        events <- event
    }
}
```

## Files

- `internal/cloudrun/client.go`

## Dependencies

Depends on: gt-9a2.7 (protocol types)
Used by: gt-9a2.8 (CloudRunOutpost)


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 435/1023)


Swarm learning: Session cleanup missing from swarm workflow

## Problem

After Enders Game swarm completed (18 issues merged), 16 polecat sessions were left running but idle. No automated cleanup occurred.

## What Should Happen

1. Witness detects polecat completed work (idle at prompt)
2. Witness verifies git state is clean
3. Witness shuts down session
4. Witness reports completion to Mayor

## GGT Components

- gt-cxx: Witness context cycling (covers self-cycling)
- gt-u1j.9: Witness daemon heartbeat loop
- gt-kmn.6: Witness swarm landing protocol

## Recommendation

Add to Witness responsibilities:
- Monitor for 'work complete' signals (DONE keyword, idle detection)
- Automated session shutdown after verification
- Swarm completion reporting to Mayor

See also: architecture.md 'Worker Cleanup (Witness-Owned)' section which describes this but it wasn't implemented in PGT.


Digest: mol-deacon-patrol

Patrol 5: All healthy.


gt spawn: pasted work assignment needs manual Enter to start

## Problem

After `gt spawn` pastes the work assignment into Claude, the session waits for Enter.

## Current Behavior

1. `gt spawn gastown/Rictus --issue gt-xxx`
2. Session starts, work is pasted
3. Claude shows 'Pasted text #1 +53 lines' but doesn't start
4. Must manually send Enter or attach and press Enter

## Expected

The spawn should send Enter after pasting to kick off the work.

## Related

Same debounce issue as tmux notifications (gt-vnp9).


gt-gastown-polecat-bravo

gt-gastown-polecat-bravo

role_type: polecat
rig: gastown
agent_state: spawning
hook_bead: null
role_bead: gt-polecat-role
cleanup_status: null


Update deacon.md.tmpl with correct molecule commands

The deacon prompt references commands that don't exist:
- gt mol bond → should be bd mol run or gt mol arm
- gt mol status → needs gt mol command tree first

Update after gt mol command tree is implemented.

Depends on: gt mol command tree issue


Digest: mol-deacon-patrol

Patrol 2: All healthy, fixed 1 stale lock


Merge: slit-mjvtz18y

branch: polecat/slit-mjvtz18y
target: main
source_issue: slit-mjvtz18y
rig: gastown
agent_bead: gt-gastown-polecat-slit


Digest: mol-refinery-patrol

Patrol: Closed 21 merge requests that were already merged to main. All tests passed. Queue now empty.


Digest: mol-deacon-patrol

Cycle 7: quiet


Wisp GC command

Implement bd wisp gc command that cleans orphaned wisps older than a threshold (default 1h). Safety net for wisps that escape normal burn-or-loop cleanup. Should run as part of Deacon patrol.


Digest: mol-deacon-patrol


Digest: mol-deacon-patrol

Patrol complete: routine, town stable


Digest: mol-deacon-patrol

Patrol cycle 10: All quiet.


Digest: mol-deacon-patrol

Patrol 13: Routine


Plugin: plan-oracle (work decomposition)

Plugin that helps decompose epics/issues into sub-tasks. Analyzes scope, identifies dependencies, estimates complexity for parallelization, creates beads for sub-tasks with dependency links.


Move disk 2: C → B

Move disk 2 from peg C to peg B. (Move 186/1023)


Polecat management: add, remove, list, state

Polecat lifecycle: add, remove, list, state tracking.

## Data Model

```go
type Polecat struct {
    Name      string          `json:"name"`
    Rig       string          `json:"rig"`
    State     PolecatState    `json:"state"`
    ClonePath string          `json:"clone_path"`
    Branch    string          `json:"branch"`
    Issue     string          `json:"issue,omitempty"`
    CreatedAt time.Time       `json:"created_at"`
    UpdatedAt time.Time       `json:"updated_at"`
}

type PolecatState string
const (
    StateIdle       PolecatState = "idle"
    StateActive     PolecatState = "active"
    StateWorking    PolecatState = "working"
    StateDone       PolecatState = "done"
    StateStuck      PolecatState = "stuck"
)
```

## Interface

```go
type PolecatManager struct {
    rig *Rig
    git *Git
}

func NewPolecatManager(rig *Rig, git *Git) *PolecatManager

// Lifecycle
func (pm *PolecatManager) Add(name string) (*Polecat, error)
func (pm *PolecatManager) Remove(name string) error
func (pm *PolecatManager) List() ([]*Polecat, error)
func (pm *PolecatManager) Get(name string) (*Polecat, error)

// State
func (pm *PolecatManager) SetState(name string, state PolecatState) error
func (pm *PolecatManager) AssignIssue(name, issue string) error
func (pm *PolecatManager) ClearIssue(name string) error

// Convenience
func (pm *PolecatManager) Wake(name string) error   // idle → active
func (pm *PolecatManager) Sleep(name string) error  // active → idle
```

## Add Flow

1. Create directory: `<rig>/polecats/<name>/`
2. Clone rig repo into it (or copy from rig root)
3. Create new branch: `polecat/<name>`
4. Initialize polecat state file
5. Create mail inbox

## Remove Flow

1. Verify session not running
2. Check for uncommitted changes (warn/error)
3. Remove directory
4. Clean up state

## State Persistence

Store in `<rig>/polecats/<name>/state.json`


load-context

Run gt prime and bd prime. Verify issue assignment.
Check inbox for any relevant messages.

Read the assigned issue (gt-u2vg) and understand the requirements.
Identify any blockers or missing information.


gt rig start <rig>... - start witness + refinery on patrol

Start one or more rigs by launching their witness and refinery workers on patrol. Should support multiple rigs: gt rig start gastown beads


Digest: mol-deacon-patrol

Patrol 61: All agents healthy, 2 convoys in progress, 1 idle dog, no incidents


Digest: mol-deacon-patrol

Patrol 2: All agents healthy, no issues.


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 111/1023)


Move disk 2: C → B

Move disk 2 from peg C to peg B. (Move 546/1023)


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 801/1023)


Digest: mol-deacon-patrol

Patrol cycle 78: All healthy


Digest: mol-deacon-patrol

Patrol #1: No issues found. All 6 agents healthy. No orphans.


Mail system: message types and threading

GGT mail system needs message types and threading like PGT.

## 1. Message Types
Add to internal/mail/types.go:
```go
type MessageType string
const (
    TypeTask         MessageType = "task"         // Required processing
    TypeScavenge     MessageType = "scavenge"     // Optional first-come work
    TypeNotification MessageType = "notification" // Informational
    TypeReply        MessageType = "reply"        // Response to message
)

// Update Message struct
type Message struct {
    // existing fields...
    Type     MessageType `json:"type"`
    ThreadID string      `json:"thread_id,omitempty"`
    ReplyTo  string      `json:"reply_to,omitempty"`
}
```

## 2. Priority Levels
Expand from 2 to 4:
```go
type Priority string
const (
    PriorityLow    Priority = "low"
    PriorityNormal Priority = "normal"
    PriorityHigh   Priority = "high"
    PriorityUrgent Priority = "urgent"
)
```

## 3. CLI Updates
internal/cmd/mail.go:
- Add --type flag to send: `gt mail send ... --type task`
- Add --reply-to flag: `gt mail send ... --reply-to <msg-id>`
- Add thread command: `gt mail thread <thread-id>`

## 4. Threading Logic
NewMessage() should auto-generate thread_id if not a reply.
Reply messages inherit thread_id from original.

## Files to Modify
- internal/mail/types.go: Add types, expand Priority
- internal/mail/mailbox.go: Thread filtering
- internal/cmd/mail.go: CLI flags and thread command

## PGT Reference
gastown-py/src/gastown/mail/message.py

## Acceptance Criteria
- [ ] Messages have type field (default: notification)
- [ ] 4 priority levels supported
- [ ] Reply creates thread with shared thread_id
- [ ] gt mail thread <id> shows conversation


Digest: mol-deacon-patrol

Patrol 12: Quiet


Digest: mol-deacon-patrol

Patrol 16: all healthy


Digest: mol-deacon-patrol

Patrol 243 complete: no incidents


Move disk 2: B → A

Move disk 2 from peg B to peg A. (Move 178/1023)


Digest: mol-deacon-patrol

Patrol 220: All nominal - handing off after 20 cycles


Merge: capable-1767081117001

branch: polecat/capable-1767081117001
target: main
source_issue: capable-1767081117001
rig: gastown


Digest: mol-deacon-patrol

Patrol 113: All healthy


Digest: mol-deacon-patrol

Patrol 13: all quiet


mol-deacon-patrol

Mayor's daemon patrol loop.

The Deacon is the Mayor's background process that runs continuously, handling callbacks, monitoring rig health, and performing cleanup. Each patrol cycle runs these steps in sequence, then loops or exits.

## Second-Order Monitoring

Witnesses send WITNESS_PING messages to verify the Deacon is alive. This
prevents the "who watches the watchers" problem - if the Deacon dies,
Witnesses detect it and escalate to the Mayor.

The Deacon's agent bead last_activity timestamp is updated during each patrol
cycle. Witnesses check this timestamp to verify health.


gt spawn --issue should auto-attach mol-polecat-work

When spawning a polecat with --issue but no --molecule, the polecat gets an issue assigned and work assignment mail, but no molecule on their hook. They check 'gt mol status', see nothing, and are stuck.

Fix: If --issue is provided but --molecule is not, auto-attach mol-polecat-work (or a configurable default) to the polecat's hook.

Current behavior:
- Issue assigned in beads ✓
- Mail sent ✓
- No molecule attached ✗

Expected:
- Issue assigned in beads ✓
- Mail sent ✓
- mol-polecat-work attached to hook ✓


Digest: mol-deacon-patrol

Patrol 5: 11 sessions, all healthy


Digest: mol-deacon-patrol

Patrol 15: All healthy.


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 847/1023)


Digest: mol-deacon-patrol

Patrol 7: nominal


mol-deacon-patrol


Digest: mol-deacon-patrol

Patrol 41: All healthy, 3 rigs, 3W/3R pinged, no incidents


Digest: mol-deacon-patrol


Maintain dog pool

Ensure dog pool has available workers for dispatch.

**Step 1: Check dog pool status**
```bash
gt dog status
# Shows idle/working counts
```

**Step 2: Ensure minimum idle dogs**
If idle count is 0 and working count is at capacity, consider spawning:
```bash
# If no idle dogs available
gt dog add <name>
# Names: alpha, bravo, charlie, delta, etc.
```

**Step 3: Retire stale dogs (optional)**
Dogs that have been idle for >24 hours can be removed to save resources:
```bash
gt dog status <name>
# Check last_active timestamp
# If idle > 24h: gt dog remove <name>
```

**Pool sizing guidelines:**
- Minimum: 1 idle dog always available
- Maximum: 4 dogs total (balance resources vs throughput)
- Spawn on demand when pool is empty

**Exit criteria:** Pool has at least 1 idle dog.


Check Witness and Refinery health

Check Witness and Refinery health for each rig.

**ZFC Principle**: You (Claude) make the judgment call about what is "stuck" or "unresponsive" - there are no hardcoded thresholds in Go. Read the signals, consider context, and decide.

For each rig, run:
```bash
gt witness status <rig>
gt refinery status <rig>
```

**Signals to assess:**

| Component | Healthy Signals | Concerning Signals |
|-----------|-----------------|-------------------|
| Witness | State: running, recent activity | State: not running, no heartbeat |
| Refinery | State: running, queue processing | Queue stuck, merge failures |

**Tracking unresponsive cycles:**

Maintain in your patrol state (persisted across cycles):
```
health_state:
  <rig>:
    witness:
      unresponsive_cycles: 0
      last_seen_healthy: <timestamp>
    refinery:
      unresponsive_cycles: 0
      last_seen_healthy: <timestamp>
```

**Decision matrix** (you decide the thresholds based on context):

| Cycles Unresponsive | Suggested Action |
|---------------------|------------------|
| 1-2 | Note it, check again next cycle |
| 3-4 | Attempt restart: gt witness restart <rig> |
| 5+ | Escalate to Mayor with context |

**Restart commands:**
```bash
gt witness restart <rig>
gt refinery restart <rig>
```

**Escalation:**
```bash
gt mail send mayor/ -s "Health: <rig> <component> unresponsive" \
  -m "Component has been unresponsive for N cycles. Restart attempts failed.
      Last healthy: <timestamp>
      Error signals: <details>"
```

Reset unresponsive_cycles to 0 when component responds normally.


Move disk 3: B → C

Move disk 3 from peg B to peg C. (Move 684/1023)


Digest: mol-deacon-patrol

Patrol cycle 15: All 3 rigs healthy. No incidents.


Move disk 4: B → A

Move disk 4 from peg B to peg A. (Move 232/1023)


Digest: mol-deacon-patrol

Patrol 20: Routine - handoff threshold reached


Digest: mol-deacon-patrol

Patrol 7: Quiet


Merge: warboy-mjwjbptd

branch: polecat/warboy-mjwjbptd
target: main
source_issue: warboy-mjwjbptd
rig: gastown
agent_bead: gt-gastown-polecat-warboy


Digest: mol-deacon-patrol

Patrol #9: Stable


Move disk 2: C → B

Move disk 2 from peg C to peg B. (Move 882/1023)


ensure-witnesses

Parallel container: Start all rig witnesses.

## Execution
Children execute in parallel. Container completes when all children complete.

## Children
- ensure-gastown-witness
- ensure-beads-witness

## Verify
All child witness steps pass verification.


Add display guards for large molecules

bd mol current and convoy displays need guards:
- If steps > 100, show summary instead of list
- Add --range flag for viewing specific step ranges
- Convoy panel shows count + percentage, not child list


Digest: mol-deacon-patrol

Patrol 7: Quick cycle, all quiet


Move disk 2: C → B

Move disk 2 from peg C to peg B. (Move 318/1023)


Digest: mol-deacon-patrol

Patrol cycle 14: all healthy


Move disk 2: B → A

Move disk 2 from peg B to peg A. (Move 418/1023)


Merge: gt-qna4

branch: polecat/capable
target: main
source_issue: gt-qna4
rig: gastown


Digest: mol-deacon-patrol

Patrol 6


Move disk 3: C → A

Move disk 3 from peg C to peg A. (Move 668/1023)


Digest: mol-deacon-patrol


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 973/1023)


mol-deacon-patrol

Mayor's daemon patrol loop.

The Deacon is the Mayor's background process that runs continuously, handling callbacks, monitoring rig health, and performing cleanup. Each patrol cycle runs these steps in sequence, then loops or exits.

## Second-Order Monitoring

Witnesses send WITNESS_PING messages to verify the Deacon is alive. This
prevents the "who watches the watchers" problem - if the Deacon dies,
Witnesses detect it and escalate to the Mayor.

The Deacon's agent bead last_activity timestamp is updated during each patrol
cycle. Witnesses check this timestamp to verify health.


Digest: mol-deacon-patrol

Patrol 15: Quiet


gt hook: Support viewing other agents' hooks

Currently `gt hook` only shows your own hook. Would be useful to query any agent's hook:

```
gt hook show gastown/polecats/nux    # What's nux working on?
gt hook show gastown/witness         # What's the witness hooked to?
```

**Use cases**:
- Mayor checking what polecats are working on
- Witness checking polecat status
- Debugging coordination issues
- Quick status overview

**Compact output** (one line):
```
gastown/polecats/nux: gt-abc123 'Fix the widget bug' [in_progress]
```

Filed by: gastown/polecats/nux (agent UX feedback)


Merge: gt-cehl8

branch: polecat/furiosa-mjuibvz8
target: main
source_issue: gt-cehl8
rig: gastown


Digest: mol-deacon-patrol @ 2025-12-24 19:46

Patrol 13: All healthy


Digest: mol-deacon-patrol

Patrol cycle 20: All healthy


Clean dead sessions

Clean dead sessions and orphaned state.

Run `gt doctor --fix` to handle all cleanup:

```bash
# Preview what needs cleaning
gt doctor -v

# Fix everything
gt doctor --fix
```

This handles:
- **orphan-sessions**: Kill orphaned tmux sessions (gt-* not matching valid patterns)
- **orphan-processes**: Kill orphaned Claude processes (no tmux parent)
- **wisp-gc**: Garbage collect abandoned wisps (>1h old)

All cleanup is handled by doctor checks - no need to run separate commands.


Digest: mol-deacon-patrol

Cycle 17


Digest: mol-deacon-patrol

Patrol 9: Mayor OK, 11 sessions


Digest: mol-deacon-patrol

Patrol 31: all quiet


Merge: slit-1767075898886

branch: polecat/slit-1767075898886
target: main
source_issue: slit-1767075898886
rig: gastown


Digest: mol-deacon-patrol

Patrol 82: 3 rigs healthy, 6 agents pinged, no incidents


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 771/1023)


gt spawn --continue for resuming parked molecules

Add `--continue` flag to gt spawn for resuming parked molecules:

```bash
gt spawn --continue gt-mol-root
```

This:
1. Finds molecule root
2. Verifies molecule is in "parked" state (in_progress, no assignee)
3. Checks external deps are now satisfied
4. Spawns polecat with molecule context
5. Polecat reads handoff mail and continues from blocked step

Part of cross-project dependency system.
See: docs/cross-project-deps.md

Depends on: gt-zniu (gt park)
Depends on Beads: bd-zmmy (bd ready resolution)


Digest: mol-deacon-patrol

Patrol 1: inbox clear, gates clear, no pending spawns, witnesses/refineries healthy, no orphans


Create activity aggregator

Component that connects to multiple rig beads daemons and merges their activity into a unified view. Polls GetMutations and GetWorkerStatus from each rig, groups by rig/worker. Handles connection failures gracefully.

BLOCKED BY (Beads rig):
- bd-gqxd: Enrich MutationEvent with title and assignee
- bd-l13p: Add GetWorkerStatus RPC endpoint
- bd-0oqz: Add GetMoleculeProgress RPC endpoint


gt mail read: Support numeric indices for message ID

Allow 'gt mail read 1' to read the first message in inbox.

Current behavior requires full message ID like 'msg-abc123'.
Should support:
- Numeric index: 'gt mail read 1' reads first/newest message
- Partial ID match: 'gt mail read abc' matches 'msg-abc123'

This is a UX improvement - agents frequently type 'gt mail read 1'.


test


Pillar 2: Patrol Ignition

Witness and Refinery patrol loops fire reliably.

Key deliverables:
- Witness patrol reads agent beads for polecat state
- Witness sends MERGE_READY to refinery on completion
- Refinery processes MERGE_READY mail
- Both send completion signals

Subsumes existing work:
- gt-6qyt1: Refinery event-driven merge queue
- gt-qpwv4: Witness detect completion
- gt-dtw9u: Witness active monitoring

Reference: ~/gt/docs/liftoff-plan.md

Parent: gt-oki8p


mol-deacon-patrol


Add --account flag to gt spawn and gt crew attach

Add --account=<handle> flag. Precedence: GT_ACCOUNT env > --account flag > default from config.


Digest: mol-deacon-patrol

Patrol 16: Green


Digest: mol-deacon-patrol

Patrol 59: All healthy


Move disk 2: A → C

Move disk 2 from peg A to peg C. (Move 902/1023)


Digest: mol-deacon-patrol

Patrol 14: all healthy


Digest: mol-deacon-patrol

Patrol 4: All agents healthy, routine


gt polecat done should auto-stop running session

Currently 'gt polecat done' fails if session is running, requiring a separate 'gt session stop' first. This is unnecessary friction - done should just stop the session automatically since that's always what you want.


Cook patrol formulas into proto beads

Use bd cook to transform formula YAML into proto beads with proper child beads for each step.

Verify with bd mol show that protos have all children.


mol-witness-patrol

Per-rig worker monitor patrol loop using the Christmas Ornament pattern.

The Witness is the Pit Boss for your rig. You watch polecats, nudge them toward
completion, verify clean git state before kills, and escalate stuck workers.

**You do NOT do implementation work.** Your job is oversight, not coding.

This molecule uses dynamic bonding to spawn mol-polecat-arm for each worker,
enabling parallel inspection with a fanout gate for aggregation.

## The Christmas Ornament Shape

```
                     ★ mol-witness-patrol (trunk)
                    /|\
          ┌────────┘ │ └────────┐
       PREFLIGHT  DISCOVERY  CLEANUP
          │          │           │
      inbox-check  survey    aggregate (WaitsFor: all-children)
      check-refnry   │       save-state
      load-state     │       generate-summary
                     ↓       context-check
             ┌───────┼───────┐  burn-or-loop
             ●       ●       ●   mol-polecat-arm (dynamic)
            ace     nux    toast
```


Digest: mol-deacon-patrol

Patrol 3: Quiet, all agents healthy


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 721/1023)


Move disk 5: B → C

Move disk 5 from peg B to peg C. (Move 912/1023)


Digest: mol-deacon-patrol

Patrol 3: All healthy, no issues


Phase 3.2: mol-polecat-work squash step

Add summary+squash as final steps in mol-polecat-work.

## Current Steps

1. read-assignment
2. understand-task
3. implement-solution
4. verify-tests
5. commit-work
6. signal-done

## Updated Steps

1. read-assignment
2. understand-task
3. implement-solution
4. verify-tests
5. commit-work
6. **generate-summary** ← NEW
7. **squash-molecule** ← NEW
8. signal-done

## Step Definitions

### generate-summary
Agent writes a concise summary following the template.
Save to a local variable or temp file.

### squash-molecule
Run: bd squash $MOLECULE_ROOT --summary "$SUMMARY"
This creates digest in main beads, cleans ephemeral.

## Update Location

This requires updating the mol-polecat-work definition in beads molecule catalog.


Merge: nux-1767138828269

branch: polecat/nux-1767138828269
target: main
source_issue: nux-1767138828269
rig: gastown


Standardize wisp creation syntax across role templates

## Task

Role templates use inconsistent syntax for creating wisps.

## Current State

**Deacon template:**
```bash
bd mol wisp create mol-deacon-patrol
bd update <wisp-id> --status=pinned --assignee=deacon
```

**Witness template (BROKEN - see gt-xxx):**
```bash
bd mol wisp mol-witness-patrol --assignee={{ .RigName }}/witness
```

## Recommended Pattern

All patrol roles should use the same two-step pattern:
```bash
bd mol wisp create mol-<role>-patrol
bd update <wisp-id> --status=pinned --assignee=<identity>
```

Or we should add `--assignee` flag to `bd mol wisp` (file in beads repo if preferred).

## Templates to Update

- witness.md.tmpl (broken, needs immediate fix)
- Verify consistency in refinery.md.tmpl if it also creates wisps

## Related

This is a consistency task; the witness template bug is tracked separately as P0.


gt prime should detect mayor role from any rig's mayor/ folder

Currently gt prime only detects the Mayor role when run from town root (~/gt). It should also detect Mayor when run from:
- ~/gt/gastown/mayor/rig (rig's internal mayor dir)
- Any path containing /mayor/ under a rig

This would allow the mayor session to work correctly regardless of which rig directory it's attached to.


Digest: mol-deacon-patrol

Patrol 4: Routine


Work on gt-role-template: Refine witness/CLAUDE.md role t...

Work on gt-role-template: Refine witness/CLAUDE.md role template. Run 'bd show gt-role-template' to see the full issue.


Digest: mol-deacon-patrol

Patrol 3: all healthy, mayor running, witnesses running


Digest: mol-deacon-patrol

Patrol cycle 19: all healthy


Add WaitsFor parsing to molecule steps

Add WaitsFor field to MoleculeStep struct and parse 'WaitsFor: all-children' (and future variants) from molecule descriptions.

This enables:
- mol progress to understand fanout patterns
- Validation that WaitsFor references valid constructs
- Future automated orchestration

Implementation:
1. Add WaitsFor []string to MoleculeStep struct
2. Add waitsForLineRegex to parse 'WaitsFor: ...' lines
3. Update ParseMoleculeSteps to extract WaitsFor
4. Update tests


Merge: nux-mjxaphp6

branch: polecat/nux-mjxaphp6
target: main
source_issue: nux-mjxaphp6
rig: gastown
agent_bead: gt-gastown-polecat-nux


Move disk 3: A → B

Move disk 3 from peg A to peg B. (Move 412/1023)


Implement Christmas Ornament pattern for mol-witness-patrol

Integrate dynamic bonding into mol-witness-patrol once Beads primitives are ready.

## Completed

- ✅ WaitsFor parsing (gt-odfr) - Parser now extracts WaitsFor: all-children
- ✅ mol bond command (gt-isje) - gt mol bond creates dynamic children with --var expansion
- ✅ WitnessPatrolMolecule() updated with Christmas Ornament structure (gt-tnow.1)
- ✅ PolecatArmMolecule() created for per-polecat inspection (gt-tnow.2)

## Remaining

- gt-tnow.3: Plugin hook support (P2)
- gt-tnow.4: Integration test with live polecats (P2)

## Design Docs

- docs/molecular-chemistry.md (already updated with pattern)
- docs/architecture.md (already updated with activity feed)
- gt-qflq: mol-witness-patrol design bead (updated)
- gt-dapb: mol-polecat-arm proto


Polecat Arm (arm-toast)

Single polecat inspection and action cycle.

This molecule is bonded dynamically by mol-witness-patrol's survey-workers step.
Each polecat being monitored gets one arm that runs in parallel with other arms.

## Variables

| Variable | Required | Description |
|----------|----------|-------------|
| polecat_name | Yes | Name of the polecat to inspect |
| rig | Yes | Rig containing the polecat |

## Step: capture
Capture recent tmux output for toast.

```bash
tmux capture-pane -t gt-gastown-toast -p | tail -50
```

Record:
- Last activity timestamp (when was last tool call?)
- Visible errors or stack traces
- Completion indicators ("Done", "Finished", etc.)

## Step: assess
Categorize polecat state based on captured output.

States:
- **working**: Recent tool calls, active processing
- **idle**: At prompt, no recent activity
- **error**: Showing errors or stack traces
- **requesting_shutdown**: Sent LIFECYCLE/Shutdown mail
- **done**: Showing completion indicators

Calculate: minutes since last activity.
Needs: capture

## Step: load-history
Read nudge history for toast from patrol state.

```
nudge_count = state.nudges[toast].count
last_nudge_time = state.nudges[toast].timestamp
```

This data was loaded by the parent patrol's load-state step and passed
to the arm via the bonding context.
Needs: assess

## Step: decide
Apply the nudge matrix to determine action for toast.

| State | Idle Time | Nudge Count | Action |
|-------|-----------|-------------|--------|
| working | any | any | none |
| idle | <10min | any | none |
| idle | 10-15min | 0 | nudge-1 (gentle) |
| idle | 15-20min | 1 | nudge-2 (direct) |
| idle | 20+min | 2 | nudge-3 (final) |
| idle | any | 3 | escalate |
| error | any | any | assess-severity |
| requesting_shutdown | any | any | pre-kill-verify |
| done | any | any | pre-kill-verify |

Nudge text:
1. "How's progress? Need any help?"
2. "Please wrap up soon. What's blocking you?"
3. "Final check. Will escalate in 5 min if no response."

Record decision and rationale.
Needs: load-history

## Step: execute
Take the decided action for toast.

**nudge-N**:
```bash
tmux send-keys -t gt-gastown-toast "{{nudge_text}}" Enter
```

**pre-kill-verify**:
```bash
cd polecats/toast
git status                    # Must be clean
git log origin/main..HEAD     # Check for unpushed
bd show <assigned-issue>      # Verify closed/deferred
```
If clean: kill session, remove worktree, delete branch
If dirty: record failure, retry next cycle

**escalate**:
```bash
gt mail send mayor/ -s "Escalation: toast stuck" -m "..."
```

**none**: No action needed.

Record: action taken, result, updated nudge count.
Needs: decide

## Output

The arm completes with:
- action_taken: none | nudge-1 | nudge-2 | nudge-3 | killed | escalated
- result: success | failed | pending
- updated_state: New nudge count and timestamp for toast

This data feeds back to the parent patrol's aggregate step.
---
bonded_from: mol-polecat-arm
bonded_to: gt-f14c
bonded_ref: arm-toast
bonded_at: 2025-12-23T10:00:00Z


Witness Role Definition

You are the Witness - per-rig worker monitor. You watch polecats, nudge them
toward completion, verify clean git state before kills, and escalate stuck
workers to the Mayor.

You do NOT do implementation work. Your job is oversight, not coding.

session_pattern: gt-{rig}-witness
work_dir_pattern: {town}/{rig}
needs_pre_sync: false
start_command: exec claude --dangerously-skip-permissions

default_molecule: mol-witness-patrol
capabilities:
  - monitor_workers
  - nudge_stuck
  - pre_kill_verify
  - session_lifecycle
  - escalation

## Core Responsibilities

1. Monitor workers: Track polecat health and progress
2. Nudge: Prompt slow workers toward completion
3. Pre-kill verification: Ensure git state is clean before killing sessions
4. Session lifecycle: Kill sessions, update worker state
5. Self-cycling: Hand off to fresh session when context fills
6. Escalation: Report stuck workers to Mayor

Key principle: You own ALL per-worker cleanup. Mayor is never involved in
routine worker management.

## Propulsion Principle

If you find something on your hook, YOU RUN IT.

Your work is defined by the mol-witness-patrol molecule. Execute steps:
- bd ready (find next step)
- bd show <step-id> (see what to do)
- bd close <step-id> (mark complete)

## Nudge Protocol

Progress through stages. Track nudge count per worker per issue.
- First Nudge (10+ min idle): Gentle inquiry
- Second Nudge (15 min): Direct question
- Third Nudge (20 min): Final warning
After 3 nudges with no progress then escalate to Mayor

## Pre-Kill Verification

Before killing ANY polecat session:
1. gt polecat git-state <name> - Must be clean
2. Check for uncommitted work
3. Check for unpushed commits
4. Verify issue closed
5. Verify PR submitted (if applicable)

## Commands

- gt polecat list <rig> - See all polecats
- gt polecat git-state <name> - Check git cleanliness
- tmux capture-pane -t gt-<rig>-<name> -p | tail -40 - Session inspection
- gt mail inbox - Check messages
- gt mail send mayor/ -s "Subject" -m "Message" - Escalate


Pillar 3: Polecat Lifecycle

Session-per-step model with automated recycle/nuke.

Key deliverables:
- gt polecat recycle <name> - kill session, preserve sandbox
- gt polecat nuke <name> - kill everything
- Witness calls recycle between molecule steps
- Refinery calls nuke after merge

Subsumes existing work:
- gt-budeb: Witness auto-nuke polecats after merge
- gt-1dbcp: Polecat auto-start nudge fix

Reference: ~/gt/docs/liftoff-plan.md

Parent: gt-oki8p


Merge: rictus-1767087768853

branch: polecat/rictus-1767087768853
target: main
source_issue: rictus-1767087768853
rig: gastown


Digest: mol-deacon-patrol

Patrol OK: 0 polecats, 6 core sessions up, town quiet


Load context

Run gt prime and bd prime. Verify issue assignment.
Check inbox for any relevant messages.

Read the assigned issue (gt-8tmz.34) and understand the requirements.
Identify any blockers or missing information.


Digest: mol-deacon-patrol

Patrol cycle 10: All healthy.


Digest: mol-deacon-patrol

Patrol cycle 2: All 6 agents healthy, no incidents


Swarm doesn't track dynamically added workers

When creating a swarm with --worker flags and then adding more polecats later, the swarm status only shows the original workers.

Steps to reproduce:
1. gt swarm create gastown --epic gt-i26df --worker slit --worker rictus --start
2. Add more polecats: gt polecat add gastown capable
3. gt sling gt-xxx gastown/capable
4. gt swarm status gt-i26df -> only shows slit, rictus

Expected: Swarm tracks all workers that are working on swarm tasks.
Actual: Only original workers shown.


Digest: mol-deacon-patrol

Cycle 6


Move disk 4: A → C

Move disk 4 from peg A to peg C. (Move 728/1023)


Digest: mol-deacon-patrol

Patrol cycle 8: All healthy, 4 polecats active (furiosa, nux, rictus, slit)


Merge: gt-3x1

branch: polecat/Slit
target: main
source_issue: gt-3x1
rig: gastown


Move disk 3: A → B

Move disk 3 from peg A to peg B. (Move 484/1023)


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 1021/1023)


Digest: mol-deacon-patrol

Patrol complete: 0 polecats, 0 gates, all witnesses/refineries healthy, no orphans


Test


gt park command for parking molecules on external deps

Add `gt park` command for when polecat hits external dependency:

```bash
gt park --step=gt-mol.3 --waiting="beads:mol-run-assignee"
```

This command:
1. Adds blocked_by: external:beads:mol-run-assignee to the step
2. Clears assignee on the step
3. Clears assignee on molecule root
4. Sends handoff mail to self with context
5. Shuts down polecat session

The molecule enters "parked" state (derived: in_progress + no assignee + blocked step).

Part of cross-project dependency system.
See: docs/cross-project-deps.md

Depends on Beads: bd-om4a (external: blocked_by support)


Phase 5.2: Ephemeral error handling and recovery

Handle edge cases in ephemeral molecule lifecycle.

## Scenarios

### Agent dies mid-molecule
- Ephemeral state persists
- Witness detects stall (no heartbeat)
- Options:
  a. Nudge agent to resume
  b. Reassign to new agent
  c. Escalate to Mayor

### Squash fails
- Retry with exponential backoff
- If persistent failure, escalate
- Don't lose the ephemeral state until squash succeeds

### Orphaned molecules
- Molecule started, never completed
- gt doctor detects (>24h old with no activity)
- Options:
  a. Manual review
  b. Auto-abandon with 'abandoned' digest
  c. Reassign

### Ephemeral repo corruption
- Re-init from scratch
- Active molecules are lost
- Main beads is source of truth for assigned work

## Implementation

Add error handling to:
- bd mol bond (handle init failures)
- bd squash (retry logic)
- gt doctor (recovery suggestions)


Digest: mol-deacon-patrol

Patrol 2: all healthy, no incidents


Doctor check: Zombie session cleanup

Detect and clean up zombie tmux sessions via gt doctor.

## Problem

Zombie sessions occur when:
- Agent crashes without cleanup
- gt kill fails mid-operation
- System restart leaves orphan sessions
- Session naming collision

## Checks

### ZombieSessionCheck
- List all tmux sessions matching gt-* pattern
- Cross-reference with known polecats
- Flag sessions with no corresponding polecat state
- Flag sessions for removed polecats
- Check session age vs polecat creation time

### Detection Criteria
- Session exists but polecat directory doesn't
- Session name doesn't match any registered polecat
- Polecat state=idle but session running
- Multiple sessions for same polecat

## Output

```
[WARN] Zombie tmux sessions detected:
  - gt-wyvern-OldPolecat (polecat removed)
  - gt-beads-Unknown (no matching polecat)
  - gt-wyvern-Toast (duplicate session)

  Run 'gt doctor --fix' to clean up
```

## Auto-Fix (--fix flag)

- Kill orphan tmux sessions
- Update polecat state to match reality
- Log all cleanup actions

## Safety

- Never kill sessions where polecat state=working
- Prompt before killing if --fix used without --force
- Create audit log of killed sessions


Day 3.5: Test polecat → refinery → merged flow

Integration test:
1. Spawn polecat with work
2. Polecat completes (updates state, closes bead)
3. Witness detects completion
4. Witness sends MERGE_READY
5. Refinery processes and merges
6. MERGED signal received

Parent: gt-hwka3


Digest: mol-deacon-patrol

Patrol complete: all agents healthy, cycling at 20 patrols


Mayor session cycling prompting

Add session cycling section to Mayor CLAUDE.md template.

## When to Cycle

Cycle proactively when:
- Running for several hours
- Context feels crowded (losing track of earlier state)
- Major phase completed
- About to start complex new work

## Composing Handoff Notes

1. Gather information:
   town status    # Overall health
   town rigs      # Each rig state
   town inbox     # Pending messages
   bd ready       # Work items

2. Compose note with this structure:

[HANDOFF_TYPE]: mayor_cycle
[TIMESTAMP]: <current time>
[SESSION_DURATION]: <how long running>

## Active Swarms
<per-rig swarm status>

## Rig Status
<table of rig health>

## Pending Escalations
<issues needing your decision>

## In-Flight Decisions
<decisions being made>

## Recent Actions
<last 5-10 things you did>

## Delegated Work
<work sent to refineries>

## User Requests
<pending user asks>

## Next Steps
<what next session should do>

## Warnings/Notes
<critical info for next session>

3. Send handoff:
   town mail send mayor/ -s "Session Handoff" -m "<note>"

4. End session - next instance picks up from handoff.


Merge: rictus-mjw3nj1a

branch: polecat/rictus-mjw3nj1a
target: main
source_issue: rictus-mjw3nj1a
rig: gastown
agent_bead: gt-gastown-polecat-rictus


Digest: mol-deacon-patrol

Patrol 20: Final cycle, all services healthy, handoff


Design future federation model

Document how remote/federated refinery would work in the future.

## Options to document
1. Git bundles - portable patches, no branches on origin
2. Dedicated integration branch pattern (integration/*)
3. Hybrid - local for same-machine, bundles for remote

## Deliverable
Design doc in docs/federation-refinery.md or similar.
Not implementing now - just capturing the design for when needed.


Digest: mol-deacon-patrol

Patrol 10


Merge: gt-jzot

branch: polecat/nux
target: main
source_issue: gt-jzot
rig: gastown


Add crew lifecycle support to Deacon

Currently crew sessions (like gastown/crew/max, beads/crew/dave) are marked as 'human-managed' and excluded from automated lifecycle.

## Current State
- `getManager(RoleCrew)` returns `"human"` (handoff.go:273)
- `gt handoff` for crew just prints a message, no lifecycle request sent
- Crew cannot request automated refresh from Deacon

## Desired State
Crew members should be able to request lifecycle actions from Deacon:
- `gt handoff --cycle` sends request to Deacon, which kills/restarts the crew session
- Useful when: context full, running molecules that need fresh session, automation

## Implementation
1. Change `getManager(RoleCrew)` to return `"deacon/"` (or new crew manager)
2. Teach Deacon to recognize crew session naming pattern
3. Add crew to Deacon's respawn loop handling
4. Test with `gt nudge` for reliable message delivery

## Use Case
Running a molecule (e.g., version-bump) and discovering mid-workflow that a fresh session is needed. Agent should be able to request refresh automatically rather than requiring human intervention.

## Related
- gt nudge: reliable message delivery to Claude sessions
- bd mol bond: molecule instantiation (coming in beads)


Crew agent beads never created (dead code in reportAgentState)

## Problem

In prime.go, reportAgentState is called for ALL roles including crew workers.
The function calls bd.UpdateAgentState for crew with ID like gt-crew-gastown-max.

But crew agent beads are NEVER created:
- Polecats: Created on spawn (polecat/manager.go:167)
- Infrastructure: Created by doctor/install (doctor/agent_beads_check.go)
- Crew: Nothing creates them

The error is silently ignored, so this doesn't break anything, but it's dead code.

## Found in commit

f3a6ef6 (feat: Witness reads polecat state from agent beads)

## Decision

**Create crew agent beads** on first gt prime if they don't exist.

Crew workers are human-managed but their state is still valuable for:
- Town-wide status dashboards
- Understanding who's working on what
- Consistent agent bead model across all agent types

## Implementation

In prime.go reportAgentState(), before calling UpdateAgentState:
1. Try to get the agent bead
2. If it doesn't exist, create it with CreateAgentBead
3. Then update state as normal


Refactor formula transformation pipeline to shared helper

The formula transformation pipeline (control flow, advice, expansions, aspects) is duplicated between cook.go and mol_bond.go. Should be extracted to a shared function in the formula package.

Current duplication in:
- cmd/bd/cook.go:96-136
- cmd/bd/mol_bond.go:598-633

Suggested approach:
- Add formula.Transform(resolved *Formula, parser *Parser) (*Formula, error)
- Handles all transformation steps in order
- Both cook.go and mol_bond.go call this single function


Digest: mol-deacon-patrol

Patrol 2: all healthy, no action needed


verify-town-health

Final verification that Gas Town is healthy.

## Action
```bash
gt status
```

## Verify
1. Daemon running: Shows daemon status OK
2. Deacon active: Shows deacon in patrol mode
3. All witnesses: Each rig witness shows active
4. All refineries: Each rig refinery shows active

## OnStall
N/A - this is a read-only verification step.

## OnFail
Log degraded state but consider boot complete. Some agents may need manual recovery.
Run `gt doctor` for detailed diagnostics.


Auto-create convoy when slinging single issue

When gt sling is used without an existing convoy context, auto-create one for dashboard visibility.

CURRENT:
gt sling bd-xyz beads/amber
# Issue assigned, but not tracked in convoy dashboard

DESIRED:
gt sling bd-xyz beads/amber
# -> Created convoy 'Work: bd-xyz' (hq-cv-xxx)
# -> Tracking bd-xyz
# -> Assigned to beads/amber

This ensures ALL work appears in gt convoy list, even 'swarm of one'.

IMPLEMENTATION:
File: internal/cmd/sling.go
1. Check if issue is already tracked by a convoy
2. If not, create convoy with title 'Work: <issue-title>'
3. Add tracks relation
4. Proceed with normal sling

OPTIONAL FLAG:
--no-convoy to skip auto-convoy creation


Missing space in error messages (handoff.go, prime.go)

Minor typo in error messages at two locations:

**handoff.go L895**:
```go
fmt.Println(style.Dim.Render("Run manually: bd --no-daemon wisp" + protoID))
// Missing space before protoID
```

**prime.go L1061**:
Same issue.

**Fix**: Add space before protoID:
```go
fmt.Println(style.Dim.Render("Run manually: bd --no-daemon wisp " + protoID))
```


Digest: mol-deacon-patrol

Patrol 17: 5 new polecats spawned (17 total). All healthy.


Polecat template: move startup announcement into molecule

Template has STARTUP PROTOCOL with 'Announce: beads Polecat furiosa, checking in.' This should be a startup step in the polecat molecule, not prose instruction in CLAUDE.md. The molecule drives behavior, not the template prose.


Move disk 6: B → A

Move disk 6 from peg B to peg A. (Move 544/1023)


Merge: rictus-mjw3nj1a


Digest: mol-deacon-patrol

Cycle 12


Merge: capable-1767140263101

branch: polecat/capable-1767140263101
target: main
source_issue: capable-1767140263101
rig: gastown


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 993/1023)


Digest: mol-deacon-patrol

Patrol cycle 10: All healthy


Add audit trail for hook detach operations

Log detachment events for debugging and monitoring.

When work is detached from hook:
- Log timestamp, agent, molecule ID, reason
- If abnormal (not completion), notify Witness
- Consider adding to wisp digest for patrol cycles


Digest: mol-deacon-patrol

Patrol 84: All healthy


Digest: mol-deacon-patrol

Patrol 11: clear


Digest: mol-deacon-patrol

P11: stable


Digest: mol-deacon-patrol

Patrol 9: All clear


mol-deacon-patrol

Mayor's daemon patrol loop.

The Deacon is the Mayor's background process that runs continuously, handling callbacks, monitoring rig health, and performing cleanup. Each patrol cycle runs these steps in sequence, then loops or exits.

## Second-Order Monitoring

Witnesses send WITNESS_PING messages to verify the Deacon is alive. This
prevents the "who watches the watchers" problem - if the Deacon dies,
Witnesses detect it and escalate to the Mayor.

The Deacon's agent bead last_activity timestamp is updated during each patrol
cycle. Witnesses check this timestamp to verify health.


Digest: mol-deacon-patrol

Patrol 1: All agents healthy, no messages, no orphans


Move disk 3: A → B

Move disk 3 from peg A to peg B. (Move 148/1023)


Review dimensions as aspects

Refactor code-review molecule to use aspects for each review dimension (security, performance, accessibility). More flexible than current pluggable molecule approach - add/remove checks by composing aspects.


Digest: mol-deacon-patrol

Patrol 12: All healthy


Digest: mol-deacon-patrol

Patrol 83: All healthy, quiet


Cost tracking v1: tmux scraping + ledger

## Overview
Implement basic cost tracking for Gas Town agents using tmux scraping.

## Scope

### 1. Live cost scraping
- `gt costs` command that:
  - Finds all Claude Code tmux sessions (polecat-*, witness-*, refinery-*, mayor-*)
  - Runs `tmux capture-pane -t <session> -p`
  - Extracts cost with regex: `\$[0-9]+\.[0-9]+`
  - Displays table: session | role | cost

### 2. Cost ledger
- File: `~/.gt/costs.jsonl`
- Schema: `{session_id, role, rig, cost_usd, started_at, ended_at, work_item}`
- Written on session end (SessionEnd hook integration)

### 3. Aggregation commands
- `gt costs` - Live costs from running sessions
- `gt costs --today` - Today's total from ledger
- `gt costs --week` - This week's total
- `gt costs --by-role` - Breakdown by role (polecat, witness, etc.)
- `gt costs --by-rig` - Breakdown by rig

### 4. Hook integration
- Add SessionEnd hook handler that:
  - Captures final cost
  - Writes to ledger
  - Includes work_item if attached

## Non-goals (v2)
- Per-convoy attribution
- Cost warnings/budgets
- Historical trends
- Deacon integration for periodic capture

## Reference
- GitHub issue #24
- docs/agent-compatibility.md (future direction)


Digest: mol-deacon-patrol

Patrol 1: All healthy - Mayor OK, 2 witnesses OK, 2 refineries OK, 1 polecat active (furiosa). No lifecycle requests or orphans.


towers-of-hanoi-10

AGENT EXECUTION PROTOCOL - Towers of Hanoi (10 disks, 1023 moves)

PURPOSE: This is a durability proof, not computation. Steps are pre-computed.
Your job is to execute them mechanically, proving crash-recovery at scale.

EXECUTION LOOP:
1. Find current state: bd mol current <mol-id>
2. Find the next ready (unblocked) step
3. Close it: bd close <step-id>
4. Repeat until no ready steps remain

ON RESUME (after crash/restart/handoff):
- Same as fresh start. The molecule IS the state.
- Query `bd mol current <mol-id>`, continue from there.
- No memory of previous session needed.

DO:
- Close steps as fast as possible (they're trivial mechanical moves)
- Use `gt handoff` when context fills (proactive cycling)
- Trust the pre-computed solution - every move is already correct

DO NOT:
- Try to solve Hanoi yourself - moves are already computed
- Mark steps in_progress - just close them directly
- Ask for permission - this is GUPP territory, just execute
- Stop for human input - run autonomously until complete

MONITORING:
- Progress: Count closed children of the molecule
- For mega-molecules: Use convoy dashboard when available
- Completion: All steps closed = molecule complete

This proves Gas Town can execute arbitrarily long workflows with
nondeterministic idempotence - different sessions, same outcome.


Move disk 1: A → B

Move disk 1 from peg A to peg B. (Move 673/1023)


Daemon: verify requesting_cycle before kill

Per gt-gby spec, daemon should verify agent state shows requesting_cycle=true before killing session. Currently kills on any lifecycle request without verification.

Requires state.json in agent workspace with requesting_cycle field.


mol-deacon-patrol


Convoy list UI: numbered shortcuts + expandable tree view

Improve gt convoy list UI:

1. Add numbered shortcuts so users can type 'gt convoy status 1' instead of full ID
2. Consider charmbracelet TUI (bubbletea/gum/lipgloss) for expandable tree view
3. Design decision: simple numbered list vs interactive TUI vs hybrid

Current output shows convoy IDs that are hard to type:
  🚚 hq-cv-7x3ig: Witness nuke fix ●
  🚚 hq-cv-eyxnc: Hanoi Demo Launch Prep ●


towers-of-hanoi

AGENT EXECUTION PROTOCOL - Towers of Hanoi

PURPOSE: This is a durability proof, not computation. Steps are pre-computed.
Your job is to execute them mechanically, proving crash-recovery at scale.

EXECUTION LOOP:
1. Find current state: bd mol current <mol-id>
2. Find the next ready (unblocked) step
3. Close it: bd close <step-id>
4. Repeat until no ready steps remain

ON RESUME (after crash/restart/handoff):
- Same as fresh start. The molecule IS the state.
- Query `bd mol current <mol-id>`, continue from there.
- No memory of previous session needed.

DO:
- Close steps as fast as possible (they're trivial mechanical moves)
- Use `gt handoff` when context fills (proactive cycling)
- Trust the pre-computed solution - every move is already correct

DO NOT:
- Try to solve Hanoi yourself - moves are already computed
- Mark steps in_progress - just close them directly
- Ask for permission - this is GUPP territory, just execute
- Stop for human input - run autonomously until complete

MONITORING:
- Progress: Count closed children of the molecule
- For mega-molecules: Use convoy dashboard when available
- Completion: All steps closed = molecule complete

This proves Gas Town can execute arbitrarily long workflows with
nondeterministic idempotence - different sessions, same outcome.


Move disk 2: C → B

Move disk 2 from peg C to peg B. (Move 690/1023)


Digest: mol-deacon-patrol

Patrol complete: checked inbox (empty), scanned health (all witnesses/refineries running), no gates, no convoys, no orphans, 1 dog idle, no plugins


Merge: rictus-1767082306179

branch: polecat/rictus-1767082306179
target: main
source_issue: rictus-1767082306179
rig: gastown


Test message

Test body


Move disk 1: B → C

Move disk 1 from peg B to peg C. (Move 1023/1023)


gt sling command implementation

Implement the gt sling command for handoff with attached work.

## Command Signature

```bash
gt sling <bead-id> [-s subject] [-m message]
```

## Behavior

1. Validate the bead exists: bd show <bead-id>
2. Create wisp on agents hook:
   - File: .beads-wisp/hook-<agent>.wisp.yaml
   - Content: bead_id, slung_at, optional context
3. Optionally send handoff mail with subject/message
4. Exit cleanly (or signal restart)

## Wisp Format

```yaml
type: slung-work
bead_id: gt-xxx
slung_at: 2025-12-24T...
slung_by: crew/joe
context: "Optional message"
```

## Files to Create/Modify

- cmd/gt/sling.go (new)
- internal/wisp/wisp.go (may need creation)
- internal/wisp/hook.go (hook reading)

## Notes

- Keep it simple - this is connector code
- The wisp is burned after pickup
- Sling should work for any role (crew, polecat, deacon)


Add INSTALLING.md with full setup guide

README Quick Start is too brief. Create docs/INSTALLING.md with:
1. All prerequisites with install commands
2. Step-by-step install for macOS and Linux
3. Verification steps (gt doctor, gt status)
4. Troubleshooting common issues
5. Minimal mode vs full-stack mode setup


Digest: mol-deacon-patrol

Patrol 10: All healthy


Move disk 1: C → A

Move disk 1 from peg C to peg A. (Move 29/1023)


Digest: mol-deacon-patrol

Patrol cycle 64: All healthy


gt rig stop <rig>... - stop rig workers with shutdown semantics

Stop one or more rigs with same flags and semantics as gt shutdown (for polecats). Should support multiple rigs: gt rig stop gastown beads


Digest: mol-deacon-patrol

Patrol 9: All healthy


Day 5.0: gt status shows pinned role beads and slots

Enhance gt status to display:
- All pinned role beads (mayor, witness, refinery, polecats)
- Their current hook slot contents (what molecule/bead is attached)
- Agent state if available

This gives a single-command view of who's working on what across the town.

Example output:
```
gt status

Town: gastown
Daemon: running (pid 1234)

Agents:
  mayor/           gt-liftoff (pinned)     idle
  witness/gastown  gt-wisp-abc (patrol)    running
  refinery/gastown (empty)                 idle
  polecat/nux      gt-xyz (in_progress)    working
  polecat/rictus   (empty)                 idle
```


Add hook status to gt status output

Enhance gt status to show hook summary for each rig.

Current: Shows rig list and basic counts
New: Also shows occupied hooks count and any stale attachments


Move disk 1: C → A

Move disk 1 from peg C to peg A. (Move 95/1023)


Move disk 2: B → A

Move disk 2 from peg B to peg A. (Move 526/1023)


Move disk 3: B → C

Move disk 3 from peg B to peg C. (Move 780/1023)


Crew worker gus in gastown - human-managed persistent workspace.

role_type: crew
rig: gastown
agent_state: idle
hook_bead: null
role_bead: gt-crew-role
cleanup_status: null


mol-outpost-assign: Intelligent work routing to outposts

The federation design shows outposts.yaml with a static policy section. Simple preference ordering is fine as config, but intelligent work routing should be a molecule.

Current static approach:
```yaml
policy:
  default_preference: [local, gce-burst, cloudrun-burst]
```

Cases requiring cognition:
- "This is a long-running research task, route to VM not CloudRun"
- "This touches sensitive code, keep local"
- "These 5 issues are related, batch them to same outpost"
- "CloudRun cost is high today, prefer local even if slower"

## Molecule: outpost-assign
Intelligent work-to-outpost routing.

## Step: classify-work
Analyze the issue/work item:
- Expected duration (quick fix vs multi-hour)
- Resource requirements
- Sensitivity/security tier
- Related work (same epic?)

## Step: check-capacity
Query outpost status:
- Current load on each
- Cost accrued today
- Health status

## Step: select-outpost
Choose optimal outpost based on:
- Work classification
- Capacity/cost
- Policy constraints
Needs: classify-work, check-capacity

## Step: emit-assignment
Record decision in beads for audit.
Needs: select-outpost

## Notes
- This molecule is invoked by Mayor/Witness when spawning
- Simple cases can short-circuit to static policy
- Full analysis only for ambiguous cases


gt-gastown-polecat-dex

gt-gastown-polecat-dex

role_type: polecat
rig: gastown
agent_state: spawning
hook_bead: null
role_bead: gt-polecat-role
cleanup_status: clean


Design: Failure modes and recovery

Document failure modes and recovery strategies for Gas Town operations.

## Critical Failure Modes

### 1. Agent Crash Mid-Operation

**Scenario**: Polecat crashes while committing, Witness crashes while verifying

**Detection**:
- Session suddenly gone (tmux check fails)
- State shows 'working' but no session
- Heartbeat stops (for Witness)

**Recovery**:
- Doctor detects via ZombieSessionCheck
- Capture any recoverable state
- Reset agent state to 'idle'
- For Witness: auto-restart via supervisor or manual gt witness start

### 2. Git State Corruption

**Scenario**: Merge conflict, failed rebase, detached HEAD

**Detection**:
- Git commands fail
- Dirty state that won't commit
- Branch diverged from origin

**Recovery**:
- gt doctor reports git health issues
- Manual intervention recommended
- Severe cases: remove clone, re-clone

### 3. Beads Sync Conflict

**Scenario**: Two polecats modify same issue

**Detection**:
- bd sync fails with conflict
- Beads tombstone mechanism handles most cases

**Recovery**:
- Beads has last-write-wins semantics
- bd sync --force in extreme cases
- Issues may need manual dedup

### 4. Tmux Failure

**Scenario**: Tmux server crashes, socket issues

**Detection**:
- All sessions inaccessible
- "no server running" errors

**Recovery**:
- Kill any orphan processes
- tmux kill-server && tmux start-server
- All agent states reset to idle
- Re-spawn active work

### 5. Claude API Issues

**Scenario**: Rate limits, outages, context limits

**Detection**:
- Sessions hang or produce errors
- Repeated failure patterns

**Recovery**:
- Exponential backoff (handled by Claude Code)
- For context limits: session cycling (mail-to-self)
- For outages: wait and retry

### 6. Disk Full

**Scenario**: Clones, logs, or beads fill disk

**Detection**:
- Write operations fail
- git/bd commands error

**Recovery**:
- Clean up logs: rm ~/.gastown/logs/*
- Remove old polecat clones
- gt doctor --fix can clean some cruft

### 7. Network Failure

**Scenario**: Can't reach GitHub, API servers

**Detection**:
- git fetch/push fails
- Claude sessions hang

**Recovery**:
- Work continues locally
- Queue pushes for later
- Sync when connectivity restored

## Recovery Principles

1. **Fail safe**: Prefer stopping over corrupting
2. **State is recoverable**: Git and beads have recovery mechanisms
3. **Doctor heals**: gt doctor --fix handles common issues
4. **Emergency stop**: gt stop --all as last resort
5. **Human escalation**: Some failures need Overseer intervention

## Implementation

- Document each failure mode in architecture.md
- Ensure doctor checks cover detection
- Add recovery hints to error messages
- Log all failures for debugging


implement

Implement the solution for gt-u2vg. Follow codebase conventions.
File discovered work as new issues with bd create.

Make regular commits with clear messages.
Keep changes focused on the assigned issue.

Depends: load-context


Digest: mol-deacon-patrol

Patrol #8: Stable


Move disk 2: B → A

Move disk 2 from peg B to peg A. (Move 994/1023)


Nudge newly spawned polecats

Nudge newly spawned polecats that are ready for input.

When polecats are spawned, their Claude session takes 10-20 seconds to initialize.
The spawn command returns immediately without waiting. This step finds spawned
polecats that are now ready and sends them a trigger to start working.

```bash
# For each rig with polecats
for rig in gastown beads; do
    gt polecats $rig
    # For each working polecat, check if Claude is ready
    # Use tmux capture-pane to look for "> " prompt
done
```

For each ready polecat that hasn't been triggered yet:
1. Send "Begin." to trigger UserPromptSubmit hook
2. The hook injects mail, polecat sees its assignment
3. Mark polecat as triggered in state

Use WaitForClaudeReady from tmux package (polls for "> " prompt).
Timeout: 60 seconds per polecat. If not ready, try again next cycle.


Merge: toast-1767074978542

branch: polecat/toast-1767074978542
target: main
source_issue: toast-1767074978542
rig: gastown


CLI: all command for batch polecat operations

Batch operations across multiple polecats.

## Commands

### gt all start
```
gt all start [--awake-only] [<specs>...]
```
Start sessions for multiple polecats.
- --awake-only: Only start awake polecats
- specs: Polecat names, rig/polecat patterns

### gt all stop
```
gt all stop [<specs>...] [--force]
```
Stop sessions for multiple polecats.

### gt all status
```
gt all status [<specs>...] [--json]
```
Show status of multiple polecats.

### gt all attach
```
gt all attach [<specs>...]
```
Attach to multiple sessions in tmux panes/windows.

### gt all run
```
gt all run <command> [<specs>...]
```
Run command in multiple polecat sessions.

## Spec Patterns
- `Toast`: Specific polecat (in default/current rig)
- `gastown/Toast`: Specific rig/polecat
- `gastown/*`: All polecats in rig
- `*`: All polecats everywhere

## Implementation
```go
func expandSpecs(specs []string, awakeOnly bool) ([]*polecat.Polecat, error) {
    // Expand patterns to list of polecats
}

func runForAll(polecats []*polecat.Polecat, action func(*polecat.Polecat) error) error {
    // Run action for each, collect errors
}
```

## New File
internal/cmd/all.go

## PGT Reference
gastown-py/src/gastown/cli/all_cmd.py

## Acceptance Criteria
- [ ] Pattern expansion works
- [ ] Parallel execution where safe
- [ ] Aggregate error reporting
- [ ] --awake-only filter works


Digest: mol-deacon-patrol

Patrol 1: All healthy - Mayor OK, 2 witnesses, 2 refineries, 0 polecats, 8 sessions, no callbacks


Crew worker wolf in gastown - human-managed persistent workspace.

role_type: crew
rig: gastown
agent_state: idle
hook_bead: null
role_bead: gt-crew-gastown-wolf-role
cleanup_status: null


mol-deacon-patrol

Mayor's daemon patrol loop.

The Deacon is the Mayor's background process that runs continuously, handling callbacks, monitoring rig health, and performing cleanup. Each patrol cycle runs these steps in sequence, then loops or exits.

## Second-Order Monitoring

Witnesses send WITNESS_PING messages to verify the Deacon is alive. This
prevents the "who watches the watchers" problem - if the Deacon dies,
Witnesses detect it and escalate to the Mayor.

The Deacon's agent bead last_activity timestamp is updated during each patrol
cycle. Witnesses check this timestamp to verify health.


Fanout gate runtime evaluation

Aggregate step uses waits-for: all-children. Deacon must evaluate this gate by checking if all dynamically-bonded arm children are complete. If no children bonded, gate passes immediately.


Digest: mol-deacon-patrol

Patrol cycle 5: All 3 rigs healthy. No incidents.


gt nudge doesn't work with crew addresses

## Bug

`gt nudge beads/crew/dave "message"` fails because it uses the polecat session manager which produces wrong session names.

## Expected
Session name: `gt-beads-crew-dave` (hyphen)

## Actual
Session name: `gt-beads-crew/dave` (slash, from polecat manager)

## Root Cause

In nudge.go line 46-57, parseAddress returns polecatName=`crew/dave`, then SessionName keeps the slash.

## Fix

Detect `crew/` prefix and use crewSessionName() instead.


Crew worker max in gastown - human-managed persistent workspace.

role_type: crew
rig: gastown
agent_state: running
hook_bead: null
role_bead: gt-crew-role
cleanup_status: has_uncommitted


Digest: mol-deacon-patrol

Patrol 18: Green


Merge: toast-1767140378007

branch: polecat/toast-1767140378007
target: main
source_issue: toast-1767140378007
rig: gastown