Handle callbacks from agents

Handle callbacks from agents.

Check the Mayor's inbox for messages from:
- Witnesses reporting polecat status
- Refineries reporting merge results
- Polecats requesting help or escalation
- External triggers (webhooks, timers)

```bash
gt mail inbox
# For each message:
gt mail read <id>
# Handle based on message type
```

**WITNESS_PING**:
Witnesses periodically ping to verify Deacon is alive. Simply acknowledge
and archive - the fact that you're processing mail proves you're running.
Your agent bead last_activity is updated automatically during patrol.
```bash
gt mail archive <message-id>
```

**HELP / Escalation**:
Assess and handle or forward to Mayor.
Archive after handling:
```bash
gt mail archive <message-id>
```

**LIFECYCLE messages**:
Polecats reporting completion, refineries reporting merge results.
Archive after processing:
```bash
gt mail archive <message-id>
```

**DOG_DONE messages**:
Dogs report completion after infrastructure tasks (orphan-scan, session-gc, etc.).
Subject format: `DOG_DONE <hostname>`
Body contains: task name, counts, status.
```bash
# Parse the report, log metrics if needed
gt mail read <id>
# Archive after noting completion
gt mail archive <message-id>
```
Dogs return to idle automatically. The report is informational - no action needed
unless the dog reports errors that require escalation.

Callbacks may spawn new polecats, update issue state, or trigger other actions.

**Hygiene principle**: Archive messages after they're fully processed.
Keep inbox near-empty - only unprocessed items should remain.


Digest: mol-deacon-patrol

Patrol 6: all clear


Move disk 2: B → A

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


Move disk 1: C → A

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


Move disk 2: A → C

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


Digest: mol-deacon-patrol

Patrol 12: All clear


Move disk 2: C → B

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


Move disk 1: C → A

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


Digest: mol-deacon-patrol

Patrol 208: All nominal


Implement shared beads architecture for rig

Implement redirect-based shared beads to eliminate git sync overhead within a rig.

## Background
Each polecat currently has its own .beads/ directory synced via git. This burns tokens on sync operations.

## Solution
Use bd's redirect feature:
1. Create single shared .beads/ at rig root
2. Polecats get redirect files pointing to shared location
3. All agents connect to same daemon
4. SQLite WAL + daemon serialization handles concurrency

## Implementation
1. Create shared .beads/ at rig root (e.g., ~/gt/gastown/.beads/)
2. Update gt spawn to create redirect files:
   mkdir -p polecats/nux/.beads
   echo ../../.beads > polecats/nux/.beads/redirect
3. Test that all polecats connect to same daemon
4. Remove git sync from intra-rig workflow
5. Keep JSONL export for backup/cross-rig only

## Reference
beads/polecats/rictus/internal/beads/beads.go:45 - followRedirect()


Move disk 2: B → A

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


Digest: mol-deacon-patrol

Patrol cycle 74: All healthy


Digest: mol-deacon-patrol

Patrol 12: All healthy


Digest: mol-deacon-patrol

Patrol 19: routine


Digest: mol-deacon-patrol

Patrol 10: All healthy.


Merge: furiosa-mjw349y2

branch: polecat/furiosa-mjw349y2
target: main
source_issue: furiosa-mjw349y2
rig: gastown
agent_bead: gt-gastown-polecat-furiosa


Move disk 2: A → C

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


Move disk 2: B → A

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


Digest: mol-deacon-patrol

Patrol 7: All agents 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.


Conditional aspects (feature flags)

Apply aspects conditionally based on environment or config. Example: apply security-audit only when env.SECURITY_SCANNING == enabled. Adds 'when' clause to aspect composition.


Create rig .runtime/ for rig runtime state

Move ephemeral rig state to .runtime/:
- Create <rig>/.runtime/ directory
- Move .gastown/witness.json → .runtime/witness.json
- Move .gastown/refinery.json → .runtime/refinery.json
- Move .gastown/namepool.json (state portion) → .runtime/namepool-state.json
- Update .gitignore to ignore .runtime/
- Update all code references


Digest: mol-deacon-patrol

Patrol #4: 2 Witnesses OK, 2 Refineries OK


Digest: mol-deacon-patrol

Patrol cycle 65: All healthy


Digest: mol-deacon-patrol

Cycle 185: Nominal


Digest: mol-deacon-patrol

Patrol 15: routine


mol progress: track dynamically bonded children

Extend `gt mol progress` to show dynamically bonded children.

## Current Behavior

```
gt mol progress gt-abc
```

Shows progress through pre-defined steps from InstantiateMolecule.

## New Behavior

Also show dynamically bonded children:

```
📊 Progress: mol-witness-patrol (gt-abc)

  Steps (9):
    ✓ inbox-check
    ✓ check-refinery
    ✓ load-state
    ◐ survey-workers (bonded 3 children)
    ○ aggregate (WaitsFor: all-children)
    ○ save-state
    ○ generate-summary
    ○ context-check
    ○ burn-or-loop

  Bonded Children (3):
    ✓ arm-toast (5/5 steps)
    ◐ arm-nux (3/5 steps)
    ○ arm-furiosa (0/5 steps)

  Progress: 4/9 steps, 3 arms (1 complete, 1 in-progress, 1 pending)
```

## Implementation

1. Find children with bonded_to: <parent-id> in description
2. Recursively get progress for each bonded child
3. Aggregate into parent progress display


Digest: mol-deacon-patrol

Patrol 2: 3 rigs healthy, no incidents


Digest: mol-deacon-patrol

Patrol 4: quick pass


Timer gate evaluation

Implement timer gate type. Format: timer:<duration> (5m, 1h, 24h). Deacon evaluates pending timer gates each patrol cycle. Gate closes when duration elapsed since creation. Simplest gate type - implement first.


Digest: mol-deacon-patrol

Patrol 11: All healthy, no messages


Move disk 1: B → C

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


Work on gt-o9j: Fix tmux status bar polecat count - exclu...

Work on gt-o9j: Fix tmux status bar polecat count - exclude static roles (mayor, deacon, witnesses, refineries, docs, hop). Run 'bd show gt-o9j' for details.


Day 2.4: Add timeout fallback for dead agents

For truly dead agents that can't report their own death:
- Daemon tracks last_seen timestamp from heartbeats
- If no heartbeat for N minutes AND state=running, mark state=dead
- This is fallback only, not primary state source

Parent: gt-d0jqp


Test: release command verification


Move disk 1: A → B

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


Digest: mol-deacon-patrol

Patrol 7: Mayor OK, 11 sessions


Digest: mol-deacon-patrol

Patrol 5: routine


Move disk 2: C → B

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


Digest: mol-deacon-patrol

Patrol 80: Routine, completing 20-cycle handoff


Session: gt-gastown-test2 completed gt-f7jxr


Digest: mol-deacon-patrol

Patrol 256 complete: no incidents


Digest: mol-deacon-patrol

Patrol 109: All healthy


Digest: mol-deacon-patrol

Patrol cycle 7: All 6 agents healthy


Digest: mol-deacon-patrol

Patrol cycle 3: All agents healthy, no callbacks, no orphans


Digest: mol-deacon-patrol

Patrol 135: All healthy


Merge: gt-xw7b

branch: polecat/morsov
target: main
source_issue: gt-xw7b
rig: gastown


Digest: mol-deacon-patrol

Patrol cycle 7: all nominal


Digest: mol-deacon-patrol

Patrol 5: All agents healthy, routine


Digest: mol-deacon-patrol

Patrol 5: all clear


Digest: mol-deacon-patrol

Patrol 4: routine checks all clear


mol-deacon-patrol


Silent error handling with _ = err patterns

Multiple locations intentionally ignore errors with comments like 'Ignore errors'. While some are valid (best-effort operations), others should be audited:

- witness/manager.go:542 - Ignores cmd.Run() error
- refinery/manager.go:411, 438, 509 - Ignores loadState and git pull errors
- swarm/manager.go:47 - Ignores getGitHead error
- polecat/manager.go:69, 284 - Ignores pool.Load and DeleteBranch errors
- swarm/integration.go:101, 137 - Ignores git pull and push errors

Each should be evaluated: log it, handle it, or confirm ignoring is intentional.


Digest: mol-deacon-patrol

Patrol cycle 18: All 6 agents healthy


Digest: mol-deacon-patrol

Patrol #4: Stable


Merge: toast-mjtm1hg8

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


Witness emits activity events

Witness emits events to activity stream for patrol activity:

Events to emit:
- patrol_started: When witness begins patrol cycle
- polecat_checked: When witness checks a polecat
- polecat_nudged: When witness nudges a stuck polecat
- escalation_sent: When witness escalates to Mayor/Deacon
- patrol_complete: When patrol cycle finishes

This replaces stats tracking in .runtime/witness.json


Add Gas Town theory of operation to all role primings

All roles (Mayor, Witness, Refinery, Polecat) should get basic GT architecture context: harness, rigs, agents, mail, beads workflow


Refinery agent: merge queue processing loop

The Refinery agent processes the merge queue, merging polecat work to main.

## Interface

```go
type Refinery struct {
    rig    *Rig
    queue  *MergeQueue
    git    *Git
    mail   *Mailbox
    config RefineryConfig
}

type RefineryConfig struct {
    AutoMerge     bool          // Auto-merge passing MRs
    RunTests      bool          // Run tests before merge
    TestCommand   string        // Command to run tests
    RequireReview bool          // Require review before merge (future)
}

func NewRefinery(rig *Rig, ...) *Refinery

// Lifecycle
func (r *Refinery) Start() error
func (r *Refinery) Stop() error
func (r *Refinery) IsRunning() bool

// Processing
func (r *Refinery) ProcessQueue() error
func (r *Refinery) ProcessMR(mr *MergeRequest) error
```

## Processing Loop

1. Check queue for pending MRs
2. For each pending MR:
   a. Fetch polecat branch
   b. Attempt merge to refinery/rig (local main)
   c. Run tests if configured
   d. If pass: push to origin, mark merged
   e. If fail: mark rejected, notify polecat
3. Sleep, repeat

## Merge Strategy

- Fast-forward when possible
- Merge commit when not
- On conflict: reject MR, polecat must rebase

## Test Integration

If tests configured:
```bash
cd refinery/rig
git merge polecat/branch
<test_command>  # e.g., go test ./...
```
Result determines merge/reject.

## Notifications

On merge success:
- Mail to polecat: "Your work merged"
- Update bead if issue tracked

On merge failure:
- Mail to polecat: "Merge failed: <reason>"
- Include conflict details if applicable

## Dependencies

Needs: Rig management, Git wrapper, Mail system, Merge queue


Move disk 1: C → A

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


Move disk 2: A → C

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


Clean up stale children on deacon handoff bead

The deacon handoff bead hq-8r8 has 7 stale children (hq-8r8.1 through hq-8r8.7) from a previous patrol that got incorrectly parented. These should be cleaned up.

The handoff bead should only contain the attached_molecule reference, not instantiated steps.


Move disk 2: B → A

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


Refinery semantic merge processing loop

Implement the Refinery semantic merge loop for processing polecat work.

## Overview

The Refinery is a fully empowered Claude Code agent that:
1. Fetches polecat branches
2. Merges to integration branch
3. Resolves conflicts semantically (re-implements if needed)
4. Runs tests
5. Escalates only when truly stuck

## Processing Loop

1. Check queue for completed tasks (polecat done, not yet merged)
2. For each task:
   - Fetch polecat branch
   - Attempt merge to integration/<swarm-id>
   - On conflict: semantic resolution (understand intent, re-implement)
   - Run tests if configured
   - On success: mark merged, file bead, notify witness
   - On failure: notify polecat (test fail) or escalate (stuck)
3. When all tasks merged: land integration to main

## Semantic Merge

When git merge fails, Refinery:
1. Reads polecat changes and beads issue
2. Understands intent
3. Re-implements on current integration branch
4. Only escalates if truly blocked

## Daemon Poking

Refinery is poked by:
- Daemon heartbeat (periodic)
- Witness notification (polecat done)
- Mayor request (check queue)

## Dependencies

Needs: gt-u1j.6 (mail), gt-u1j.3 (git), gt-u1j.14 (merge queue)

## Reference

See PGT ephemeral.py for branch operations.


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 4: B → A

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


gt crew at/attach: Start session in crew workspace

Implement 'gt crew at <rig>/<name>' and 'gt crew attach <name>' commands:
- Start tmux session (optional - could just print cd instructions)
- Launch claude code in the workspace
- Deliver any pending mail
- Support --no-tmux to just print directory path
- 'attach' infers rig from cwd


gt sling: '.' target should resolve to current agent identity, not literal dot

## Problem

When slinging from a crew directory with "." as target, the assignee becomes
literal "." instead of resolving to the current agent.

```bash
cd ~/gt/beads/crew/dave
gt sling bd-tksk .
# Result: assignee="." instead of "beads/crew/dave"
```

## Expected

"." should resolve to the current agent identity based on cwd, like git does
with "." meaning current directory.

## Impact

Work is not properly assigned, agent cannot find hooked work.

## Fix

In sling.go, resolve "." target to current agent identity before updating.


Move disk 1: C → A

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


Digest: mol-deacon-patrol

Patrol 12: Nominal


Define PlatformAdapter interface

Define the PlatformAdapter interface in Go. The interface specification is already
documented in ~/gt/docs/hop/PLATFORM-OF-PLATFORMS.md (lines 118-152).

**Location**: Create `internal/hop/platform.go` in the beads repo

**Interface methods** (from doc):
- Registration: GetPlatformID, GetPlatformMetadata
- Identity: MapIdentity, GetSovereigntyTier, ResolveEntity
- Work Translation: TranslateWorkUnit, TranslateToNative
- Validation: SubmitCompletion, QueryValidations
- Skills: ExtractSkills, GetSkillOntology
- Governance: GetPlatformRules, ValidateWork
- Payment (optional): GetPaymentRails, RecordPayment
- Federation: GetFederationEndpoint, CanFederateWith

**Supporting types needed**:
- SovereigntyTier enum (see gt-jzmsj.2)
- PlatformMetadata struct
- HopEntity (maps to existing EntityRef)
- HopWorkUnit (maps to existing Issue/Bead)
- ValidationRecord (maps to existing Validation)
- SkillVector, SkillOntology (stub for now)
- GovernanceRules, Violation
- PaymentRail, Payment, Receipt

**Acceptance criteria**:
1. Interface compiles and is documented
2. Types compile with reasonable defaults
3. No implementation yet - interface only


Digest: mol-deacon-patrol

Patrol 13: healthy


Merge: gt-caih

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


Digest: mol-deacon-patrol

Patrol 150 complete


Witness Patrol

Per-rig worker monitor patrol loop with progressive nudging.


Swarm-in-Beads: Discovery-based swarm execution

Swarm-in-Beads: Make swarm state derive from beads, not separate JSON. See ~/gt/docs/swarm-architecture.md for full design. Core principles: discovery over tracking, ready front model, nondeterministic idempotence.


mol-deacon-patrol


Formula error handling and recovery

Specify how cooking errors are reported and recovered:
- What happens when extends chain is broken (missing formula)?
- What happens when aspect pointcut matches nothing?
- What happens when expansion produces invalid structure?
- Graceful degradation vs fail-fast semantics
- Error metadata in cooked protos

Deferred: post-launch polish


Remove keepalive file infrastructure

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

**Current state:**
- keepalive.TouchTownActivity() writes to activity.json on every gt/bd command
- Daemon reads activity.json to calculate exponential backoff

**New model (feed-based wake):**
- Patrol agents subscribe to `bd activity --follow`
- Any beads mutation wakes agents within ~500ms
- Daemon heartbeat is recovery-focused, not wake-focused
- Read-only commands don't need to wake the town

**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):
- gt mail inbox (checking for work?)
- None identified yet

See docs/patrol-system-design.md for full feed-based wake design.


Documentation overhaul: User Guide approach

## Problem

Current docs are:
1. **Grandiose** - Too much vision, belongs in ~/gt/docs (HOP), not here
2. **Verbose** - Need bullets/tables, not sections. Too many separate files.
3. **Bottom-up** - Written as we built. Users need top-down.

Gas Town is a simple agent orchestrator (4-10 → 20-30 agents). Not a manifesto.

## Target Structure

### 1. Features at a Glance
- Persistent agent identities with mail inboxes and "work hooks"
- Sling work to agents, pinned to their hook
- Universal Propulsion: If hook is pinned, RUN IT
- Hooks survive crash, shutdown, compaction, restart
- Self-sling for auto-restart workflows
- Pin individual beads or entire epics

### 2. Available Workflows
- tmux mode vs no-tmux (raw Claude Code)
- Full Gas Town vs partial (single roles)
- Modular and resilient - one role at a time

### 3. Cooking Formulas
- Molecules = chains of issues (railroad tracks)
- Formulas = step descriptions (atoms)
- Cook formulas → molecules → durable workflows
- Examples: release molecule, deacon patrol, polecat workflow, shiny

### 4. (Optional) MEOW Deep Dive
- Structured epics as chained work graphs
- Serial/parallel branches, gates, loops, algebra
- States of matter, polymorphic bond operators
- But users just need to cook formulas

## Deliverable

One README + maybe one or two supporting docs. Radically condensed.


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

Patrol 19


refinery Handoff

# Merge queue tracking
last_processed_branch: null
branches_merged_this_cycle: 0


Merge: organic-mjwjck2f

branch: polecat/organic-mjwjck2f
target: main
source_issue: organic-mjwjck2f
rig: gastown
agent_bead: gt-gastown-polecat-organic


Digest: mol-deacon-patrol


Digest: mol-deacon-patrol

Patrol cycle 14: nominal


Beads epic templates for batch work patterns

Optional: Define templates for common batch work patterns.

## Concept

A template encodes a workflow pattern that can be instantiated as beads:

```yaml
# templates/batch-basic.yaml
name: basic-batch
description: Simple batch work pattern
phases:
  - name: startup
    issues:
      - title: "Verify workers ready"
  - name: working
    # Actual work issues added separately
  - name: cleanup
    issues:
      - title: "Merge all branches"
      - title: "Clean up workers"
      - title: "Report to Mayor"
```

## Usage

```bash
gt spawn --template basic-batch --epic gt-u1j --workers 3
```

Creates beads epic with template phases + actual work from gt-u1j children.

## Decision Point

Templates are OPTIONAL. The core design (beads as state, multi-wave orchestration) works without templates. Templates are sugar for common patterns.

Consider deferring to P3 or dropping entirely if beads epics with dependencies suffice.

## Note

No "swarm IDs" involved - templates just pre-populate epic/issue structure.


Move disk 3: A → B

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


Digest: mol-deacon-patrol

Patrol 209: All nominal


Digest: mol-deacon-patrol

Patrol 18: Nominal


Add expandQueue() to resolve queue workers from messaging.json

Add queue expansion to internal/mail/router.go.

PATTERN TO FOLLOW:
Look at expandList() at lines 63-87 as the template.

IMPLEMENTATION:
1. Add expandQueue(queueName string) (*config.QueueConfig, error)
2. Load messaging.json via config.LoadMessagingConfig
3. Look up queueName in cfg.Queues map
4. Return the QueueConfig (workers list, max_claims) or ErrUnknownQueue

FILE: internal/mail/router.go
ADD: var ErrUnknownQueue = errors.New("unknown queue") near ErrUnknownList

TESTS: Add TestExpandQueue in router_test.go

Depends on isQueueAddress being added first.


BUG: gt swarm create uses non-existent --mol-type flag on bd update

gt swarm create fails because it tries to use --mol-type=swarm with bd update, but that flag doesn't exist.

## Location
internal/cmd/swarm.go lines 241, 252, 661-662

## Problem
- `bd list --mol-type=swarm` works (flag exists)
- `bd create --mol-type=swarm` works (flag exists)
- `bd update --mol-type=swarm` FAILS (flag doesn't exist)

## Fix Options
1. Add --mol-type flag to bd update command (beads change)
2. Use labels instead of mol-type for swarm marking
3. Only set mol-type during bd create, not update

## Reported By
gus during gt-d46 swarm attempt


Digest: mol-deacon-patrol

Patrol 8: all healthy


Digest: mol-deacon-patrol

Patrol #1: All witnesses/refineries running (beads, gastown, wyvern). 1 dog idle. No convoys, no gates, no pending spawns. Clean cycle.


Digest: mol-deacon-patrol

Patrol 12: quick pass


Comprehensive help text and examples

Improve help text with examples and cross-references.

## Improvements

### 1. Examples Section
Add to Long description:
```go
var spawnCmd = &cobra.Command{
    Long: `Spawn a polecat with work assignment.

Examples:
  gt spawn gastown/Toast --issue gt-abc
  gt spawn gastown --issue gt-def          # auto-select polecat
  gt spawn gastown/Nux -m "Fix the tests"  # free-form task`,
}
```

### 2. Cross-References
Reference related commands:
```
See also:
  gt polecat list    List available polecats
  gt session attach  Attach to spawned session
```

### 3. Flag Descriptions
More detail on flags:
```go
cmd.Flags().StringVar(&issue, "issue", "",
    "Beads issue ID to assign. The polecat will work on this issue.")
```

### 4. Common Workflows
Add workflow docs to gt --help:
```
Common Workflows:
  Start a swarm:
    gt swarm preflight
    gt swarm create gastown --epic gt-abc --worker Toast --worker Nux --start
    gt refinery start gastown

  Check status:
    gt status
    gt swarm status <id>
```

## Files to Update
All internal/cmd/*.go files

## Acceptance Criteria
- [ ] All commands have Examples
- [ ] Related commands cross-referenced
- [ ] Flags have detailed descriptions
- [ ] Root help shows workflows


Molecule state file management

## Cross-Repo Reference

This work is tracked in beads repo as **bd-hulf**.

The gastown task gt-qvn7.2.2 is a placeholder.
Actual implementation happens in beads.

See: bd show bd-hulf (from beads/crew/dave)


Digest: mol-deacon-patrol

Patrol 17: Quiet


implement

Implement the solution for {{issue}}. 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 17: All healthy


Digest: mol-deacon-patrol

Patrol cycle 4: 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.


Digest: mol-deacon-patrol

Patrol 1: No callbacks, closed completed convoy hq-cv-ckisw, all agents healthy, no orphans


Move disk 1: B → C

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


Move disk 2: B → A

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


Digest: mol-deacon-patrol

Patrol 252 complete: no incidents


Move disk 4: C → B

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


Find abandoned work

Find abandoned work.

Scan for orphaned state:
- Issues marked in_progress with no active polecat
- Polecats that stopped responding mid-work
- Merge queue entries with no polecat owner
- Wisp sessions that outlived their spawner

```bash
bd list --status=in_progress
gt polecats --all --orphan
```

For each orphan:
- Check if polecat session still exists
- If not, mark issue for reassignment or retry
- File incident beads if data loss occurred


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

Patrol 6: All healthy


Digest: mol-deacon-patrol

Patrol 6: 9 sessions healthy


gt polecat add: should handle existing branch gracefully

## Problem

`gt polecat add gastown Nux` fails if the branch `polecat/Nux` already exists.

## Current Behavior

```
fatal: a branch named 'polecat/Nux' already exists
```

## Expected Behavior

Should either:
1. Reuse the existing branch
2. Or prompt to delete/recreate
3. Or auto-suffix: polecat/Nux-2

## Context

Branch may exist from previous polecat that was removed but branch wasn't cleaned up.


Update templates with molecule navigation workflow

Update all agent templates to use new molecule navigation commands.

## Commands to integrate
- bd mol current: orientation after startup/handoff (bd-sal9)
- bd close --continue: seamless step transitions (bd-ieyy)

## Templates to update

### prompts/roles/polecat.md
- Add bd mol current to 'Finding Your Work' section
- Replace manual 3-command dance with bd close --continue
- Update 'Working Through Steps' section

### prompts/roles/crew.md
- Add molecule navigation to workflow section
- Show bd mol current for session startup

### prompts/roles/refinery.md
- Update patrol step transitions to use --continue

### prompts/roles/witness.md
- Update patrol step transitions to use --continue

### prompts/roles/deacon.md
- Update patrol step transitions to use --continue

## Key message
The Propulsion Principle: close a step, immediately get handed the next.
No friction, no forgetting, no 3-command dance.

## Blocked by (Beads features)
- bd-sal9: bd mol current
- bd-ieyy: bd close --continue

BLOCKED 2025-12-23 00:17: Waiting for beads features (bd mol current, bd close --continue) to be implemented. Notified mayor.


Digest: mol-deacon-patrol

Patrol 2 complete. All agents healthy.


Digest: mol-deacon-patrol

Patrol 1 complete. All agents healthy. No callbacks, convoys, spawns, gates, orphans. 3 rigs monitored.


Interrupt vs Queue mail semantics

Add priority/delivery semantics to mail messages.

## Semantics

| Type | Delivery | Use Case |
|------|----------|----------|
| Interrupt | tmux send-keys | Lifecycle, URGENT, stuck detection |
| Queue | Create message only | Normal mail, status, heartbeat |

## Implementation

- `bd mail send --interrupt` uses tmux send-keys notification
- Default is queue (agent checks with `gt mail check`)
- Urgent flag on messages for interrupt delivery

## Agent Side

- `gt mail check --quiet` - non-blocking check for queued mail
- `gt mail wait` - block until mail arrives (for idle agents)
- Heartbeats become queued, agent checks at natural breakpoints


Merge: dementus-mjtlqmya

branch: polecat/dementus-mjtlqmya
target: main
source_issue: dementus-mjtlqmya
rig: gastown


Digest: mol-refinery-patrol

Refinery patrol: no MRs in queue. Tests passed (all ok). No issues filed.


Clarify Mayor vs Witness cleanup responsibilities

Document the cleanup authority model: Witness owns ALL per-worker cleanup, Mayor never involved.

## The Rule

**Witness handles ALL per-worker cleanup. Mayor is never involved.**

## Why This Matters

1. Separation of concerns: Mayor strategic, Witness operational
2. Reduced coordination overhead: No back-and-forth for routine cleanup
3. Faster shutdown: Witness kills workers immediately upon verification
4. Cleaner escalation: Mayor only hears about problems

## What Witness Handles

- Verifying worker git state before kill
- Nudging workers to fix dirty state
- Killing worker sessions
- Updating worker state (sleep/wake)
- Logging verification results

## What Mayor Handles

- Receiving swarm complete notifications
- Deciding whether to start new swarms
- Handling escalations (stuck workers after 3 retries)
- Cross-rig coordination

## Escalation Path

Worker stuck -> Witness nudges (up to 3x) -> Witness escalates to Mayor -> Mayor decides: force kill, reassign, or human

## Anti-Patterns

DO NOT: Mayor asks Witness if worker X is clean
DO: Witness reports swarm complete, all workers verified

DO NOT: Mayor kills worker sessions directly
DO: Mayor tells Witness to abort swarm, Witness handles cleanup

DO NOT: Workers report done to Mayor
DO: Workers report to Witness, Witness aggregates and reports up


Digest: mol-deacon-patrol


Digest: mol-refinery-patrol

Patrol cycle: checked mail (empty), scanned MR queue (0 open), no branches to merge. All MRs already processed.


Move disk 1: A → B

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


mol-deacon-patrol


Digest: mol-deacon-patrol

Patrol cycle 13: All 6 agents healthy


Step recovery: timeout and release

Implement recovery mechanism for stuck molecule steps.

## Problem
When a worker dies mid-step, the step stays in_progress forever.
Need timeout/release mechanism for nondeterministic idempotence.

## Solution
1. Track step start time (claimed_at timestamp)
2. Timeout: After 30 min in_progress, step returns to pending
3. Manual release: bd release <step-id>

## Implementation Options

### Option A: Beads-level timeout
- Add claimed_at field to issues
- bd ready excludes items in_progress < 30 min
- bd ready includes items in_progress > 30 min (auto-recovery)

### Option B: Daemon-level timeout
- Daemon watches in_progress items
- Moves back to pending after timeout

### Option C: Manual only (MVP)
- bd release <id> manually moves in_progress → pending
- Document recovery procedure
- Witness can automate for polecats

## Recommendation
Start with Option C (manual) for Christmas. Add Option A later.

## Acceptance
- [ ] bd release command works
- [ ] Stuck steps can be recovered
- [ ] Documented recovery procedure


Move disk 1: B → C

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


Merge: toast-1767081120579

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


Digest: mol-deacon-patrol

Patrol 2: Quick scan, all healthy, no work


Digest: mol-deacon-patrol

Patrol 8: healthy


Digest: mol-deacon-patrol

Patrol 14: routine


E2E Test: Verify mol-polecat-work spawn

Simple test task for Phase 5 E2E validation


Merge: nux-1767084010093

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


Digest: mol-deacon-patrol

Patrol #20: All healthy, 3 convoys active


Digest: mol-deacon-patrol

Patrol cycle 2: All rigs healthy. No callbacks. Town idle.


gt crew status: Show workspace status

Implement 'gt crew status [<name>]' command:
- Show session state (running/stopped)
- Show git status (branch, uncommitted changes, unpushed)
- Show last commit info
- Show mail inbox status (unread count)
- If no name given, show all crew workers


Digest: mol-deacon-patrol

Patrol cycle 5: all healthy


Refinery patrol: Add banners and wisp-based execution

Bring Refinery patrol up to Deacon's level of sophistication:

## Current state
- mol-refinery-patrol exists (needs verification)
- Basic merge queue processing

## Needed
1. **Banners** - Print step banners like Deacon does:
   ```
   ═══════════════════════════════════════════════════════════════
     ⚗ QUEUE-CHECK
     Processing merge queue entries
   ═══════════════════════════════════════════════════════════════
   ```

2. **Wisp-based execution** - Spawn patrol as wisp, squash when complete
3. **Handoff bead attachment** - Refinery needs its own handoff bead with attached_molecule
4. **Loop-or-exit step** - Context-aware cycling like Deacon
5. **Patrol summary banner** at end of each cycle

## Reference
See Deacon patrol implementation in ~/gt/deacon/CLAUDE.md


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.

**ZFC-Compliant Observation** (AI observes AI):

```bash
# View pending spawns with captured terminal output
gt deacon pending
```

For each pending session, analyze the captured output:
- Look for Claude's prompt indicator "> " at the start of a line
- If prompt is visible, Claude is ready for input
- Make the judgment call yourself - you're the AI observer

For each ready polecat:
```bash
# 1. Trigger the polecat
gt nudge <session> "Begin."

# 2. Clear from pending list
gt deacon pending <session>
```

This triggers the UserPromptSubmit hook, which injects mail so the polecat sees its assignment.

**Bootstrap mode** (daemon-only, no AI available):
The daemon uses `gt deacon trigger-pending` with regex detection. This ZFC violation is acceptable during cold startup when no AI agent is running yet.


Add hook-attachment-valid doctor check

Add gt doctor check to verify attached molecules exist and are not closed.

Check: hook-attachment-valid
Error if: Hook's attached_molecule field points to non-existent or closed issue
Fix suggestion: Clear attachment with gt mol detach


Digest: mol-deacon-patrol

Patrol 4: routine, all healthy


Move disk 6: A → C

Move disk 6 from peg A to peg C. (Move 32/1023)


Digest: mol-deacon-patrol

Patrol cycle 80: All healthy


Move disk 2: A → C

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


Digest: mol-deacon-patrol

Patrol complete: all 3 rigs healthy, no incidents


Dog agent beads with role_type=dog

## Dog Agent Beads for @group Resolution

Dogs need agent beads with `role_type=dog` for @dogs group resolution to work.

## Background

Dogs are Deacon's reusable helper workers (see patrol-system-design.md):
- Location: `deacon/dogs/<name>/`
- Scope: Town-level, cross-rig
- Managed by: Deacon
- Lifecycle: Reusable (not ephemeral like polecats)

## Deliverables

1. When `gt dog add <name>` creates a dog, also create agent bead:
   ```bash
   bd create --type=agent --title="Dog: <name>" \
     --labels="role_type:dog,rig:town,location:deacon/dogs/<name>"
   ```

2. When `gt dog remove <name>` removes a dog, close the agent bead

3. Ensure `bd list --type=agent --role_type=dog` returns all dogs

## Schema

Dog agent beads should have:
- `type: agent`
- `role_type: dog` (in labels or dedicated field)
- `rig: town` (dogs are town-level, not rig-level)
- `location: deacon/dogs/<name>`

## Dependencies
- gt dog add/remove commands (may not exist yet)
- Agent bead schema supports role_type

## Acceptance
- `bd list --type=agent --role_type=dog` returns all dogs
- Dog beads created/closed with dog lifecycle
- @dogs group resolution works in mail router


Digest: mol-deacon-patrol

Patrol cycle 14: All healthy - dag polecat started


self-review

Review your own changes. Look for:
- Bugs and edge cases
- Style issues
- Missing error handling
- Security concerns

Fix any issues found before proceeding.

Depends: implement


Test merge request

branch: polecat/Test/gt-test
target: main
source_issue: gt-test
worker: TestWorker
rig: gastown


Move disk 2: B → A

Move disk 2 from peg B to peg A. (Move 670/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.


mol-deacon-patrol


Digest: mol-deacon-patrol

Patrol complete: cleaned 1 orphaned process, all 8 sessions healthy, no stuck wisps


Merge: gt-h6eq.4

branch: polecat/valkyrie
target: main
source_issue: gt-h6eq.4
rig: gastown


Move disk 1: A → B

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


Move disk 2: B → A

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


Digest: mol-deacon-patrol

Patrol 15: clear


Digest: mol-deacon-patrol

Patrol cycle 19: routine


End-of-cycle inbox hygiene

Verify inbox hygiene before ending patrol cycle.

**Step 1: Check inbox state**
```bash
gt mail inbox
```

Inbox should be EMPTY or contain only just-arrived unprocessed messages.

**Step 2: Archive any remaining processed messages**

All message types should have been archived during inbox-check processing:
- WITNESS_PING → archived after acknowledging
- HELP/Escalation → archived after handling
- LIFECYCLE → archived after processing

If any were missed:
```bash
# For each stale message found:
gt mail archive <message-id>
```

**Goal**: Inbox should have ≤2 active messages at end of cycle.
Deacon mail should flow through quickly - no accumulation.


Digest: mol-deacon-patrol

Patrol: slit handoff (landing protocol), polecats cleaned (0 now), 4 witness/refineries up


Cost tracking v2: Use beads instead of JSONL

## Overview

Revise cost tracking to use beads as the storage layer instead of `~/.gt/costs.jsonl`. This aligns with Gas Town's "Discover, Don't Track" principle and keeps beads as the single source of truth.

## Dependencies

- **bd-vii9**: Agent identity beads (service polecats) - provides the parent beads for sessions

## Model

### Agent Identity Bead (type: agent)

Created on first use of a polecat/agent name. Persists across session lifecycles.

```yaml
id: gt-gastown-polecat-toast
type: agent
title: "Agent: gt-gastown-polecat-toast"
status: open  # Always open (persistent identity)
metadata:
  role: polecat
  rig: gastown
  name: toast
labels:
  total_cost: "4.56"       # Cache for fast queries
  session_count: "12"
  last_active: "2026-01-02"
```

### Session Event Bead (type: session)

Created when a session ends (via Stop hook).

```yaml
id: gt-sess-abc123
type: session
title: "Session: toast completed gt-nrpiq"
parent: gt-gastown-polecat-toast   # Links to agent
status: closed
metadata:
  cost_usd: 1.23
  duration_seconds: 1800
  work_item: gt-nrpiq
  started_at: "2026-01-02T12:00:00Z"
  ended_at: "2026-01-02T12:30:00Z"
```

## Implementation

### 1. Update `gt costs record`

Instead of appending to JSONL:
```go
// Create session bead
bd create --type session --parent $AGENT_BEAD \
  --title "Session: $NAME completed $WORK_ITEM" \
  --metadata cost_usd=1.23,duration_seconds=1800,...

// Update agent bead labels (cache)
bd label $AGENT_BEAD total_cost=$NEW_TOTAL session_count=$NEW_COUNT
```

### 2. Update `gt costs` queries

Replace JSONL parsing with bd queries:
```bash
# Today's sessions
bd list --type=session --since=today

# Sessions for agent
bd list --type=session --parent=gt-gastown-polecat-toast

# All agents with costs
bd list --type=agent
```

### 3. Remove JSONL support

- Remove `~/.gt/costs.jsonl` writes
- Remove JSONL parsing code
- Migration: optionally import existing JSONL into beads

## Queries Supported

| Command | Implementation |
|---------|---------------|
| `gt costs` | Live tmux scrape (unchanged) |
| `gt costs --today` | `bd list --type=session --since=today` + sum |
| `gt costs --week` | `bd list --type=session --since=week` + sum |
| `gt costs --by-role` | `bd list --type=agent` + group by role label |
| `gt costs --by-rig` | `bd list --type=agent` + group by rig label |

## Benefits

- Single source of truth (beads)
- Git-backed audit trail
- Queryable via `bd list`
- Syncs with `bd sync`
- Follows "Events as State History, Labels as Cache" pattern

## Non-goals

- Per-message cost tracking (too granular)
- Real-time cost streaming (agent limitation)

## References

- GH #24 (original cost tracking issue)
- bd-vii9 (agent identity beads)
- docs/agent-compatibility.md


ensure-gastown-witness

Start the gastown rig Witness.

## Action
```bash
gt witness start gastown
```

## Verify
1. Session exists: `tmux has-session -t gastown-witness 2>/dev/null`
2. Not stalled: `gt peek gastown/witness` does NOT show "> Try" prompt
3. Heartbeat fresh: Last patrol cycle < 5 min ago

## OnStall
```bash
gt nudge gastown/witness "Start patrol."
sleep 30
# Re-verify
```

## OnFail
Log error. Rig polecats will be unmonitored until Witness recovers.


Move disk 1: C → A

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


Handle callbacks from agents

Handle callbacks from agents.

Check the Mayor's inbox for messages from:
- Witnesses reporting polecat status
- Refineries reporting merge results
- Polecats requesting help or escalation
- External triggers (webhooks, timers)

```bash
gt mail inbox
# For each message:
gt mail read <id>
# Handle based on message type
```

**WITNESS_PING**:
Witnesses periodically ping to verify Deacon is alive. Simply acknowledge
and archive - the fact that you're processing mail proves you're running.
Your agent bead last_activity is updated automatically during patrol.
```bash
gt mail archive <message-id>
```

**HELP / Escalation**:
Assess and handle or forward to Mayor.
Archive after handling:
```bash
gt mail archive <message-id>
```

**LIFECYCLE messages**:
Polecats reporting completion, refineries reporting merge results.
Archive after processing:
```bash
gt mail archive <message-id>
```

**DOG_DONE messages**:
Dogs report completion after infrastructure tasks (orphan-scan, session-gc, etc.).
Subject format: `DOG_DONE <hostname>`
Body contains: task name, counts, status.
```bash
# Parse the report, log metrics if needed
gt mail read <id>
# Archive after noting completion
gt mail archive <message-id>
```
Dogs return to idle automatically. The report is informational - no action needed
unless the dog reports errors that require escalation.

Callbacks may spawn new polecats, update issue state, or trigger other actions.

**Hygiene principle**: Archive messages after they're fully processed.
Keep inbox near-empty - only unprocessed items should remain.


Move disk 3: C → A

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


Merge: gt-frs

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


Merge: capable-1767084028536

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


Move disk 1: A → B

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


Move disk 4: A → C

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


Boot needs CLAUDE.md and directory setup

Boot spawns in ~/gt/deacon but:
1. No ~/gt/deacon/dogs/boot/ directory exists
2. Boot reads Deacon's CLAUDE.md (wrong role context)
3. spawnTmux() doesn't send initial triage prompt

Fix:
- Create ~/gt/deacon/dogs/boot/CLAUDE.md with Boot role instructions
- Update EnsureDir() to create directory on spawn
- Consider sending 'gt boot triage' as initial prompt

Boot should know it's a fresh-each-tick watchdog that:
- Observes Deacon state
- Decides: start/wake/nudge/nothing
- Cleans stale inbox
- Exits (never handoffs)


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 32: all quiet


Move disk 3: C → A

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


Move disk 1: B → C

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


Merge: dementus-1767140140908

branch: polecat/dementus-1767140140908
target: main
source_issue: dementus-1767140140908
rig: gastown


Merge: toast-mjw7062w

branch: polecat/toast-mjw7062w
target: main
source_issue: toast-mjw7062w
rig: gastown
agent_bead: gt-gastown-polecat-toast


Digest: mol-deacon-patrol

Patrol 10: All clear


Digest: mol-deacon-patrol

Patrol 10: all clear


Run the test suite.

Run the test suite.

```bash
go test ./...
```

Track results: pass count, fail count, specific failures.

instantiated_from: mol-refinery-patrol
step: run-tests


Digest: mol-deacon-patrol

Patrol 154: All healthy


Patrol lifecycle integration test

Verify patrol runs 3+ cycles without wisp accumulation. bd wisp list should show <5 wisps. Context cycles cleanly produce handoff mail. Test with Deacon patrol.


Digest: mol-deacon-patrol

Patrol 6: all clear, agents healthy


Remove gt mail dependency on bd mail commands

Replaced bd mail send/inbox/read/ack with bd create/list/show/close. Messages are now stored as beads issues with type=message.


Implement announce:name address type for bulletin-board messaging

Add support for announce:name addresses for read-only bulletin boards.

SEMANTICS:
- Messages to announce:name create ONE copy in shared location
- All eligible readers can read (no claiming, no removal)
- Messages retained up to retain_count, oldest pruned
- No inbox pollution - readers check the announce channel explicitly

USE CASE:
Low urgency broadcast that does not need ack, e.g. clean up your branches.

IMPLEMENTATION:
1. Add isAnnounceAddress() / parseAnnounceName() helpers
2. Add sendToAnnounce() - creates message in announce location
3. Add gt mail announces - list available announce channels
4. Add gt mail read-announce <channel> - read messages from channel
5. Add retention pruning on new message

CONFIG (already in messaging.json schema):
announces.alerts.readers = [@town]
announces.alerts.retain_count = 100


Digest: mol-deacon-patrol

Patrol cycle 66: All healthy


Digest: mol-deacon-patrol

Patrol 155: All healthy


Digest: mol-deacon-patrol

Patrol cycle 3: All healthy


Merge: capable-1767074169502

attached_args: Code review this merge request

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


Move disk 1: A → B

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


Refactor all startup paths to use StartupNudge

## Files to Refactor

| File | Function | Current Approach |
|------|----------|------------------|
| start.go:788 | runStartCrew | SendKeys(claude) then SendKeys(gt prime) |
| start.go:747 | runStartCrew restart | Same |
| start.go:929 | another path | SendKeys without prime |
| crew_lifecycle.go:354 | restart | SendKeys(gt prime) after start |
| crew_lifecycle.go:525 | another path | Same |
| crew_at.go:154 | --detached | Claude arg "gt prime" ✓ |
| handoff.go:331 | handoff | Claude arg "gt prime" ✓ |
| deacon.go:294 | deacon start | Relies on hooks |
| witness.go:336 | witness start | Relies on hooks |
| polecat_spawn.go | spawn | Various |

## Pattern
Replace scattered logic with:
```go
cfg := StartupNudgeConfig{
    Recipient: address,
    Sender:    sender,
    Topic:     "cold-start",  // or "handoff", mol-id, etc.
}
if err := session.StartupNudge(t, sessionName, cfg); err \!= nil {
    // handle
}
```

## Dependencies
- gt-bgfqy: Create StartupNudge function
- gt-dc2fs: Add runtime configuration


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

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


gt-gastown-polecat-testcat

gt-gastown-polecat-testcat

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


Digest: mol-deacon-patrol

Patrol 3: all healthy


Integration test: agent waits for CI via gate

End-to-end test of the gate workflow.

## Test Scenario
1. Agent creates gate: bd gate create --await gh:run:123 --timeout 5m --notify beads/dave
2. Agent writes handoff and exits
3. Deacon patrol checks gate condition
4. (Mock) GitHub run completes
5. Deacon notifies waiter and closes gate
6. New agent session reads mail and resumes

## Test Requirements
- Mock GitHub API responses
- Test timeout path
- Test multiple waiters
- Verify mail notifications sent

## Moved from beads
Originally bd-rl5t. Tests Deacon patrol which is in gastown.


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: C → A

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


Digest: mol-deacon-patrol

Patrol #17: Stable


Digest: mol-deacon-patrol

Patrol cycle 6: routine, healthy


gt mol attach: Auto-detect agent from cwd when single arg provided

## Current Behavior

gt mol attach requires 2 args:
  gt mol attach <agent-bead-id> <molecule-id>

## Expected Behavior

When called with 1 arg from an agent working directory:
  gt mol attach <molecule-id>

Should auto-detect the agent from cwd (same detection used by gt mail, bd, etc.)
and attach the molecule to that agent hook.

## Example

From ~/gt/gastown/mayor/rig:
  gt mol attach gt-y14l7
  -> detects mayor role
  -> attaches gt-y14l7 to gt-mayor hook

## Implementation

1. Check arg count
2. If 1 arg, call role detection from cwd
3. Resolve agent bead ID from role (gt-mayor, gt-witness-gastown, etc.)
4. Proceed with attachment

This makes the common case (attaching work to yourself) ergonomic.


gt doctor: Add Boot health check (vet mode)

gt doctor should check Boot health:
- Is Boot directory present?
- Is Boot session alive?
- Last execution status (success/error)
- Marker file freshness

The vet checks on the dog.


Move disk 1: A → B

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


Move disk 2: B → A

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


Slim down rig root config.json to identity only

Rig root config.json should only contain identity:
- type, version, name, git_url, beads.prefix, created_at
- Remove any behavioral config (move to settings/config.json)
- Update RigConfig type to separate identity from settings
- Ensure loader reads identity from root, settings from settings/


Digest: mol-deacon-patrol

Patrol OK: no mail, 8 polecats working, all witnesses/refineries up


Digest: mol-deacon-patrol

P5: stable


Polecat spawn: Environment vars not exported to shell

Polecat sessions set tmux environment but don't export to shell before Claude

In session/manager.go Start():
  _ = m.tmux.SetEnvironment(sessionID, "GT_RIG", m.rig.Name)
  _ = m.tmux.SetEnvironment(sessionID, "GT_POLECAT", polecat)
  ...
  command = "claude --dangerously-skip-permissions"

Compare to crew_lifecycle.go which exports inline:
  claudeCmd := fmt.Sprintf("export GT_ROLE=crew GT_RIG=%s GT_CREW=%s && claude ...")

Result: Claude can't detect polecat identity, falls back to 'mayor', shows wrong hook.

Fix: Export GT_ROLE=polecat GT_RIG=X GT_POLECAT=Y inline before running Claude.


Digest: mol-deacon-patrol

Patrol #13


Batch work landing report generation

Generate reports on batch work completion.

## Trigger

When all children of an epic are closed, generate a completion report.

## Report Contents

- Epic metadata (ID, title, created by, duration)
- Task summary (completed counts, timing)
- Per-task details (issue, assignee, time taken)
- Git stats (commits merged, lines changed)
- Cleanup stats (branches deleted)

## Output Locations

1. Mail to Mayor - summary report
2. Optional: save to file with --save flag

## Command

```bash
gt report --epic <epic-id> [--save report.md]
```

## Format

Markdown with sections:
- Summary
- Tasks
- Workers
- Timeline

## Note

This replaces the swarm-based reporting (gt-662). Reports are generated from epic/issue data, not from separate swarm state files.

## Reference

PGT: swarm/report.py (for format ideas, ignore swarm ID patterns)


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 2: Quiet cycle, all agents healthy


Digest: mol-deacon-patrol

Cycle 196: Nominal


Polecat template: fix hard-to-parse sentence about persistence

This sentence is hard to parse: 'When in doubt, prefer bd—persistence you don't need beats lost context'. Rewrite for clarity, e.g., 'When in doubt, use bd for tracking - unnecessary persistence is better than lost context.'


Merge: nux-mjvtlh4f

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


Move disk 6: B → A

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


Move disk 2: A → C

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


gt crew start <rig> [name] | --all - start crew workers

Start crew workers in a rig. Can specify a name to start one, or --all to start all crew members in the rig.


gt-gastown-polecat-testcat4

gt-gastown-polecat-testcat4

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


gt sling --on flag for wisp scaffolding

Add --on flag to gt sling for applying forms to existing work:
  gt sling shiny gastown/Toast --on gt-abc123

When --on is specified, implies --wisp (scaffolding existing work).
The form shapes execution of the target bead.


Digest: mol-deacon-patrol

Patrol 2: All healthy, no changes


Create mol-install-go-binary molecule

Create a single-step molecule for building and installing the gt binary.

## Molecule Definition
\`\`\`markdown
## Molecule: install-go-binary
Single step to rebuild and install the gt binary after code changes.

## Step: install
Build and install the gt binary locally.

Run from the rig directory:
\`\`\`
go build -o gt ./cmd/gt
go install ./cmd/gt
\`\`\`

Verify the installed binary is updated:
\`\`\`
which gt
gt --version  # if we have version command
\`\`\`
\`\`\`

## Implementation
1. Add to builtin_molecules.go
2. Update SeedBuiltinMolecules to include it
3. Run gt molecule seed

## Acceptance
- [ ] mol-install-go-binary exists in beads
- [ ] Can be instantiated standalone
- [ ] Can be included by other molecules


gt mol status: Change 'Pinned' to 'Hooked' in output

The `gt mol status` output shows "📌 Pinned: <bead-id>" for hooked beads, which is confusing now that we have distinct statuses:

- **hooked**: Work assigned to you (triggers autonomous mode)
- **pinned**: Permanent reference beads (like agent beads, role beads)

The output currently says:
```
📌 Pinned: gt-3amkz: Overhaul autonomous-mode guidance...
No molecule attached
```

Should say:
```
🪝 Hooked: gt-3amkz: Overhaul autonomous-mode guidance...
No molecule attached
```

Additional improvements:
1. Change icon from 📌 to 🪝 for hooked beads
2. Add a note clarifying that hooked work triggers autonomous mode even without an attached molecule
3. Consider adding "AUTONOMOUS MODE" banner when hooked work is found (similar to gt prime)

Files to update:
- internal/cmd/molecule_status.go (outputMoleculeStatus function around line 576)


Digest: mol-deacon-patrol

Patrol 20: Mayor OK, 11 sessions


Work on gt-role-template: Refine witness/CLAUDE.md role template. Add clearer heartbeat protocol, mail checking procedure, nudge decision criteria, escalation thresholds. Run 'bd show gt-role-template' for details.


CRITICAL: ProcessMRFromQueue not implemented - Refinery merge logic stubbed

File: internal/refinery/engineer.go:384
The ProcessMRFromQueue() function returns hardcoded failure with TODO comment.
This is a core refinery function that cannot process merges in current state.
Must implement actual merge logic before OSS launch.


Move disk 2: C → B

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


Move disk 1: B → C

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


Move disk 1: B → C

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


Refinery as Worktree: Local MR Integration

Move refinery from separate clone to git worktree. Polecats stop pushing to origin - refinery sees their branches locally. MRs become wisps (ephemeral). Only main gets pushed after merge.

## Goals
- Origin stays clean (only main + beads-sync branches)
- No orphaned polecat branches ever
- Simpler mental model for MR coordination
- Faster integration (no network for local MR ops)

## Trade-offs
- Machine crash = redo pending work (acceptable, beads track state)
- Future federation needs different approach (bundles or integration branch)

## Components Affected
- Rig initialization (refinery setup)
- Spawn/polecat workflow (remove origin push)
- Refinery manager (local branch access)
- Documentation (architecture, workflows)
- Molecule templates (remove push instructions)


Digest: mol-deacon-patrol

Patrol complete: checked inbox (0 msgs), health check passed (all rigs healthy), cleaned 3 stale locks


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 5: clear


mol-deacon-patrol


Digest: mol-deacon-patrol

Patrol 16 complete


Digest: mol-deacon-patrol

Patrol #5: Stable


Preflight molecule: verify baseline health before work

Before assigning work, verify baseline (main branch) is healthy.

**From VC**: Self-healing state machine (HEALTHY → SELF_HEALING → ESCALATED). ~200 lines.

**Gas Town implementation**: Preflight molecule or refinery feature:
```yaml
preflight:
  gates: [test, lint, build]
  on_failure: create-fix-issue
```

Run at session start. If baseline broken, file a P0 fix issue and work on that first.

**Value**: Self-healing baseline. Agents don't start from broken state.

**VC lesson**: Prevents cascading failures. Agent shouldn't start work on broken code.


gt-polecat-gastown-ace

gt-polecat-gastown-ace

role_type: polecat
rig: gastown
agent_state: running
hook_bead: gt-795e8
role_bead: null


Deacon convoy patrol steps

New Deacon patrol steps for convoy orchestration.

Steps:
1. check-convoy-completion
   - Watch town feed for tracked issue closures
   - Auto-close convoys when all tracked issues complete

2. resolve-external-deps
   - When external issue closes, propagate to dependents in other rigs
   - Update blocked status across project chain boundaries

3. fire-notifications
   - Convoy complete → notify Overseer inbox
   - Cross-rig dep resolved → notify affected rigs

Depends on: gt feed, bd-hj0s (convoy type)
Related: hq-7h8jx (Convoy System epic in town beads)


Move disk 1: B → C

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


Digest: mol-deacon-patrol

Patrol #20: Stable, handoff threshold reached


Bug: parseLifecycleRequest always matches 'cycle' due to LIFECYCLE prefix

In lifecycle.go, parseLifecycleRequest checks strings.Contains(title, "cycle") first, but the prefix "LIFECYCLE:" contains the word "cycle". This means ALL lifecycle messages match the cycle action, making restart and shutdown unreachable. Fix: check for restart/shutdown before cycle, or use word boundaries.


Merge: nux-1767084010093

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


Merge: gt-99a

branch: polecat/Slit
target: main
source_issue: gt-99a
rig: gastown


Pinned Beads: Ongoing concerns and anchors

Pinned beads represent persistent concerns that do not close traditionally. Stay out of bd ready. Examples: Monitor production, Weekly syncs. Implementation: pinned: true field on bead.


gt doctor: Detect and clean up orphaned sessions/processes

## Problem
Orphaned tmux sessions and Claude processes accumulate over time, consuming memory.

## Discovered Orphans
- gt-deacon: Idle Claude session, not part of any rig

## Proposed Solution

### gt doctor --check (default)
Detect issues without fixing:
- Orphan sessions (not matching rig/polecat/crew/witness/refinery/mayor pattern)
- Claude processes without parent tmux session
- Tmux sessions without Claude (stuck at bash prompt)
- Polecats marked 'working' but session idle

### gt doctor --fix
Clean up detected issues:
- Kill orphan sessions
- Kill orphan Claude processes
- Optionally reset stuck polecat state

### gt gc (alternative name)
Short alias for cleanup operations.

## Acceptance Criteria
- [ ] Detects orphan sessions
- [ ] Detects orphan processes
- [ ] Safe cleanup (doesn't kill active work)
- [ ] Reports what was cleaned


implement

Implement the solution for gt-test123. 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


Move disk 1: C → A

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


Witness: instantiate mol-witness-patrol on start

When witness starts, create a mol-witness-patrol instance and pin it to the witness hook.

## Changes to witness/manager.go

In Start() or run():
1. Check if patrol instance exists on hook
2. If not, call beads.InstantiateMolecule(mol-witness-patrol, handoffBead)
3. Store instance ID for later reference

## Hook Structure

The witness handoff bead gets:
- attached_molecule: gt-patrol-xyz
- attached_at: timestamp

## Idempotency

If patrol already exists (from previous session), reuse it.
Don't create duplicate instances on restart.


load-context

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

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


Move disk 1: A → B

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


Digest: mol-deacon-patrol

Patrol 77: Routine


Digest: mol-deacon-patrol

Patrol 106: All healthy


Move disk 1: B → C

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


Digest: mol-deacon-patrol

Patrol 7: 3 rigs healthy


Digest: mol-deacon-patrol

Patrol 20: Final. 19 polecats. 3 MQ pending. All healthy.


Check convoy completion

Check convoy completion status.

Convoys are coordination beads that track multiple issues across rigs. When all tracked issues close, the convoy auto-closes.

**Step 1: Find open convoys**
```bash
bd list --type=convoy --status=open
```

**Step 2: For each open convoy, check tracked issues**
```bash
bd show <convoy-id>
# Look for 'tracks' or 'dependencies' field listing tracked issues
```

**Step 3: If all tracked issues are closed, close the convoy**
```bash
# Check each tracked issue
for issue in tracked_issues:
    bd show <issue-id>
    # If status is open/in_progress, convoy stays open
    # If all are closed (completed, wontfix, etc.), convoy is complete

# Close convoy when all tracked issues are done
bd close <convoy-id> --reason "All tracked issues completed"
```

**Note**: Convoys support cross-prefix tracking (e.g., hq-* convoy can track gt-*, bd-* issues). Use full IDs when checking.


Digest: mol-deacon-patrol

Patrol 3: All healthy


E2E Phase 2 observability test

End-to-end test of Phase 2 observability:

Test scenario:
1. Sling work to polecat
2. Watch gt feed for polecat activity
3. Polecat completes, signals done
4. Watch gt feed for MQ events (merge_started, merged)
5. gt status shows queue depth changes
6. Swarm status visible in gt swarm status

All observable without checking .runtime/*.json files.

Success = glass cockpit is lit.


Deacon has no rig-level presence - only global gt-deacon

The Deacon patrol role exists only at the global level (~/gt/deacon) but doesn't have per-rig presence like Witness and Refinery.

Current structure:
```
~/gt/
├── deacon/           ← Global deacon only
├── beads/
│   ├── witness/      ← Per-rig witness
│   ├── refinery/     ← Per-rig refinery
│   └── (no deacon)   ← Missing
└── gastown/
    ├── witness/
    ├── refinery/
    └── (no deacon)   ← Missing
```

Question: Should Deacon be per-rig like Witness/Refinery, or is global-only intentional?

If per-rig is needed: Create beads/deacon and gastown/deacon with appropriate CLAUDE.md files.


Digest: mol-deacon-patrol

Patrol 20: Final patrol, handing off


Hookable mail beads: Ad-hoc instruction handoff

## Summary
Enable mail beads to be hooked, providing a mechanism for ad-hoc instruction handoff that complements structured molecules.

## Two Use Cases
A. **Hook existing mail**: `gt hook attach <mail-id>` - for backlog mail that becomes priority
B. **Hook new instructions**: `gt handoff -m "..."` auto-hooks the mail it creates

## Current Gap
- Molecules (GUPP+MEOW): Structured work, hookable, machine-guided execution
- Issues: Hookable via mol wrapper
- Mail: Contains ad-hoc instructions but NOT hookable - relies on successor checking inbox

## Proposed Behavior

### gt hook attach <bead-id>
Already exists but should work for ANY bead type including mail:
```bash
gt hook attach hq-abc123  # Works for mail, issues, mols
```

### gt handoff (enhanced)
```bash
gt handoff -s "Swarm execution" -m "1. Create convoy..."
# Creates mail bead
# Auto-hooks the mail
# Respawns session
```

### Successor Startup
```bash
gt hook
# Shows: 🪝 Hook: hq-xxx (mail from mayor/)
#        Subject: 🤝 HANDOFF: Swarm execution
#        Run: gt mail read hq-xxx
```

GUPP applies: If hooked, execute (read mail, follow instructions).

## Execution Models
| Hooked Type | Execution |
|-------------|-----------|
| Molecule | Cook formula, follow steps |
| Issue | Claim and complete task |
| Mail | Read, interpret, execute prose |

## Documentation Required
- [ ] All role CLAUDE.md files
- [ ] Priming docs (gt prime output)
- [ ] gt handoff --help
- [ ] Hook system docs

## Implementation
1. Ensure `gt hook attach` accepts any bead type
2. Enhance `gt hook` display for mail beads
3. Update `gt handoff` to auto-hook mail
4. Update startup hooks to handle mail on hook


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 3: A → B

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


mol-deacon-patrol


Digest: mol-deacon-patrol

Patrol 19: all quiet


Digest: mol-deacon-patrol

P15: stable


Move disk 1: C → A

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


Digest: mol-deacon-patrol

Patrol cycle 12: All agents healthy


Polecat Mood Plugin (standard)

Standard witness plugin molecule that assesses polecat emotional state.

## Molecule Definition

```json
{
  "id": "mol-polecat-mood",
  "title": "Assess mood for {{polecat_name}}",
  "description": "Analyze captured output and determine emotional state.\n\nVars:\n- {{polecat_name}} - The polecat to assess\n- {{captured_output}} - Recent tmux capture\n\nOutput: gt polecat mood {{polecat_name}} <emoji>",
  "labels": ["template", "plugin", "witness", "tier:haiku"],
  "issue_type": "task"
}
```

## Mood Emojis

```
😺 working     Active tool calls, making progress
😸 productive  Completing tasks, tests passing
🐱 idle        Waiting at prompt, no recent activity
😼 confident   Self-reviewing, about to submit
😿 struggling  Repeated errors, test failures
🙀 stuck       No progress for 10+ min
😽 done        Work complete, requesting shutdown
😾 blocked     Explicitly waiting on dependency
```

## Bonding

During witness patrol plugin-run step:

```bash
bd mol bond mol-polecat-mood $PATROL_WISP \
  --ref mood-{{polecat_name}} \
  --var polecat_name=ace \
  --var captured_output="$TMUX_CAPTURE"
```

## Installation

```bash
bd mol install mol-polecat-mood  # From Mol Mall
```

## Customization

Fork the molecule and modify description to change assessment criteria or add custom moods. Install your fork to override.


Digest: mol-deacon-patrol

Patrol cycle 22: All healthy, no incidents


Move disk 2: A → C

Move disk 2 from peg A to peg C. (Move 710/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.

## 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.


Digest: mol-deacon-patrol

Cycle 188: Nominal


Move disk 6: B → A

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


Digest: mol-deacon-patrol

Patrol cycle 26: All healthy, no incidents


Digest: mol-deacon-patrol

Patrol cycle 14


Move disk 3: B → C

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


Digest: mol-deacon-patrol

Patrol #10: Stable


Digest: mol-deacon-patrol

Patrol #14


CloudRun worker container: Dockerfile and entrypoint

## Overview

Docker container image for Cloud Run workers.

## Dockerfile

```dockerfile
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o gt ./cmd/gt

FROM ubuntu:22.04

# Install Claude Code
RUN apt-get update && apt-get install -y     curl git nodejs npm     && npm install -g @anthropic-ai/claude-code     && apt-get clean

# Install gt
COPY --from=builder /app/gt /usr/local/bin/gt

# Worker entrypoint
COPY deploy/cloudrun/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

EXPOSE 8080
ENTRYPOINT ["/entrypoint.sh"]
```

## Entrypoint

```bash
#!/bin/bash
git config --global user.name "$GIT_USER"
git config --global user.email "$GIT_EMAIL"
exec gt worker serve --port 8080
```

## Files

- `deploy/cloudrun/Dockerfile`
- `deploy/cloudrun/entrypoint.sh`
- `deploy/cloudrun/README.md`

## Dependencies

Depends on: gt-9a2.11 (HTTP server - gt worker serve)


Move disk 6: B → A

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


mol-deacon-patrol


Digest: mol-deacon-patrol

Patrol complete: all agents healthy


Move disk 2: A → C

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


Move disk 1: C → A

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


Load context

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

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


Merge: dementus-mjw46vz4

branch: polecat/dementus-mjw46vz4
target: main
source_issue: dementus-mjw46vz4
rig: gastown
agent_bead: gt-gastown-polecat-dementus


Document the Propulsion Principle

Write canonical documentation for the Universal Gas Town Propulsion Principle.

Location: gastown/mayor/rig/docs/propulsion-principle.md

Content:
- The One Rule (hook has work → work happens)
- Why it works (stateless agents, molecule-driven)
- The sling lifecycle diagram
- Agent startup protocol
- Examples and anti-patterns

This is foundational theory-of-operation documentation.


Molecule-based Witness Patrol

Wire up mol-witness-patrol as a tracking ledger for the Go-based witness.

## Key Insight

The molecule is NOT an executor - it's a **tracking structure**. The existing
Go code in internal/witness/manager.go continues to run the patrol loop.
The molecule instance provides visibility, audit trail, and polecat tracking.

## Current State

- Witness runs as Go code with direct patrol logic
- mol-witness-patrol and mol-polecat-arm exist as molecule definitions
- gt mol bond creates dynamic children
- No molecule tracking of actual witness operations

## Target State

1. When witness starts → instantiate mol-witness-patrol on its hook
2. When Go code discovers polecat → bond mol-polecat-arm child
3. When polecat completes/dies → close that arm issue
4. gt mol progress shows current patrol state
5. Molecule survives wisp burns via handoff bead

## Benefits

- Visibility: gt mol status gastown/witness shows active arms
- Audit: Each polecat inspection is a trackable issue
- Consistency: Same tracking model as polecats with molecules
- Progress: gt mol progress works for witness too

## Non-Goals

- NOT replacing Go code with Claude session
- NOT running molecule steps as prompts
- NOT requiring Claude for witness operation


CLI: polecat commands (add, remove, list, wake, sleep)

Polecat management CLI commands.

## Commands

### gt polecat list
List polecats in a rig.
```
gt polecat list <rig> [--json]
gt polecat list --all [--json]
```
Output:
- Name
- State (idle/active/working/done/stuck)
- Current issue (if any)
- Session status (running/stopped)

### gt polecat add
Add a new polecat to a rig.
```
gt polecat add <rig> <name>
```
- Creates polecat directory
- Clones rig repo
- Creates work branch
- Initializes state

### gt polecat remove
Remove a polecat from a rig.
```
gt polecat remove <rig>/<polecat> [--force]
```
- Fails if session running
- Warns if uncommitted changes
- --force bypasses checks

### gt polecat wake
Mark polecat as active (ready for work).
```
gt polecat wake <rig>/<polecat>
```
Transitions: idle → active

### gt polecat sleep
Mark polecat as idle (not available).
```
gt polecat sleep <rig>/<polecat>
```
Transitions: active → idle
Fails if session running (stop first).

## Address Format

`<rig>/<polecat>` for operations on specific polecat.
`<rig>` for list command.

## Implementation

```go
var polecatCmd = &cobra.Command{Use: "polecat"}
polecatCmd.AddCommand(listCmd, addCmd, removeCmd, wakeCmd, sleepCmd)
```


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 13: Quiet


Compile-time vs runtime cooking

Distinguish two cooking modes: 1) Compile-time: produces proto with variable placeholders, for modeling/estimation/contractor handoff. 2) Runtime: produces mol with real issue IDs. Compile-time lets you pre-decompose work for untrusted executors or planning purposes.


Digest: mol-deacon-patrol

Patrol 4: Routine


Digest: mol-deacon-patrol

Patrol 13 complete


Move disk 1: C → A

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


Move disk 2: C → B

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


Digest: mol-deacon-patrol

Patrol 11


Agent state lifecycle incomplete for polecats

## Problem

The witness patrol formula (mol-witness-patrol.formula.toml) expects polecats to self-report states:
- running
- idle
- stuck
- done

But looking at the code, the only state transitions that actually happen are:

1. **spawning** - Set when polecat is created (polecat/manager.go:170)
2. **running** - Set when agent runs `gt prime` (prime.go:112)
3. **dead** - Set by daemon when agent goes unresponsive (daemon/lifecycle.go:647)

**Missing transitions:**
- `stuck` - No code path exists for agents to report this
- `done` - No code path exists for agents to report this
- `idle` - Only set for infrastructure agents, never for polecats

## Impact

The witness cannot rely on agent_state to detect stuck or done polecats, contradicting the ZFC principle stated in the formula.

## Found in commit

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

## Suggested fix

Add code paths for polecats to self-report:
1. `gt done` should update agent_state to "done"
2. When stuck (detected how?), agent should update to "stuck"
3. Consider if "idle" makes sense for polecats (no current work)


Swarm learning: Witness needs automated context cycling

Furiosa hit 2% context during swarm work. Witness role needs automated detection of low context and should trigger session cycling before agents get stuck. Add to Witness responsibilities in prompts.md.


Digest: mol-deacon-patrol

Patrol 10 complete


Auto-rebase on conflict: optional automatic rebase

Implement automatic rebase as conflict resolution option.

When on_conflict=auto_rebase and conflicts detected:
1. Attempt: git rebase <target> <source-branch>
2. If clean rebase: update source branch, continue merge
3. If conflicts in rebase: abort, fall back to assign_back
4. Force push rebased branch (worker's branch)

Requires:
- Worker branch must be force-pushable
- Config: on_conflict: auto_rebase

Risks:
- Force push can confuse workers
- Complex conflicts still need manual resolution

Reference: docs/merge-queue-design.md#conflict-resolution-strategies


Digest: mol-deacon-patrol

Patrol 8: quiet


Mol Mall: Formula library and sharing

## Mol Mall

Library/marketplace for formula molecules.

### Features
- Browse available formulas
- Formula metadata (author, version, inputs, outputs)
- Custom formula creation
- Formula versioning
- Cross-town formula sharing (future)

### Commands
```bash
gt formula list              # List available formulas
gt formula show <name>       # Formula details
gt formula create <name>     # Create new formula
gt formula edit <name>       # Modify formula
gt formula export <name>     # Export for sharing
gt formula import <file>     # Import shared formula
```

### Storage
- Formulas as beads in town-level .beads/
- type: formula
- Structured schema for legs, synthesis, inputs

### Future: Public Mol Mall
- Central registry of community formulas
- gt formula search 'code review'
- gt formula install community/security-audit


gt-gastown-polecat-testcat3

gt-gastown-polecat-testcat3

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


Move disk 1: B → C

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


Convert MR queue to wisp storage

MR queue should use wisp storage (.beads-wisp/) instead of durable beads.

## Design (Simplified)

With refinery as worktree, polecats and refinery share the same machine. No cross-machine MR coordination needed. Wisps are the natural fit.

### Storage
- Location: `.beads-wisp/mq/<mr-id>.json`
- Format: Same MRFields structure (branch, target, source_issue, worker, rig)
- Lifecycle: Create on submit, delete after merge

### Code Changes

1. **MR Creation** (done.go, mq_submit.go)
   - Write to `.beads-wisp/mq/` instead of `bd create --type=merge-request`
   - Generate ID: `mr-<timestamp>-<random>` or similar

2. **Refinery Query** (refinery/manager.go, engineer.go)
   - Read from `.beads-wisp/mq/` directory
   - List files, parse JSON, process in order

3. **Cleanup**
   - Delete MR file after successful merge
   - On failure, leave file (refinery retries)

### What Stays in Beads
- Source issues (the work being merged) - still tracked in beads
- Merge commits reference source issue ID
- `bd close <issue>` still happens on merge

### Benefits
- No sync overhead for transient MR state
- Simpler model (file per MR, delete when done)
- Consistent with wisp philosophy (ephemeral operational state)

### Not Needed
- Digest squashing (MRs are deleted, not accumulated)
- Cross-machine visibility (single-machine architecture)


Move disk 1: A → B

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


Move disk 3: C → A

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


Bug: refinery --foreground detects parent session as already running

When gt refinery start gastown runs:
1. Creates tmux session gt-gastown-refinery
2. Sends 'gt refinery start gastown --foreground' into the session
3. The foreground command checks HasSession() - finds the session it's inside
4. Returns 'already running' error

The foreground mode check should either:
- Skip the tmux session check (only check PID)
- Use a different indicator that the daemon loop is running
- Pass a flag to indicate we're being called from the background starter

Workaround: Manually run 'gt refinery start gastown --foreground' from a fresh session.


Digest: mol-deacon-patrol

Patrol #15: 3/4 through


Clean up stale issue references in comments

Several code comments reference completed or tombstoned issues as if they're future work:

## Stale "will do" comments (issue is closed/done):

1. **daemon/daemon.go:313** - Says "gt-2hzl4 will add timeout fallback" but gt-2hzl4 is closed and the fallback is implemented at lifecycle.go:725. Update to past tense or remove.

2. **daemon/lifecycle.go:174** - Says "to be removed per gt-psuw7" but gt-psuw7 is closed. Either remove the legacy tmux detection code or update the comment.

## Tombstoned epic references (epic superseded):

3. **keepalive/keepalive_test.go:64** - "See gt-gaxo epic for rationale" - gt-gaxo is tombstone.

4. **cmd/doctor.go:100** - "See gt-gaxo epic for ZFC cleanup rationale" - gt-gaxo is tombstone.

## Action:
- Update stale comments to reflect current state
- Remove or update tombstone references
- For the lifecycle.go tmux detection: decide if code should stay or go


Digest: mol-deacon-patrol

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


Test Task 2: Add comment to version.go


Digest: mol-deacon-patrol

Patrol 17: All clear


Digest: mol-deacon-patrol

Patrol #17


Built-in molecules: engineer-in-box, quick-fix, research

Create built-in molecules as Beads issues:

## engineer-in-box

```markdown
id: mol-engineer-in-box
type: molecule
title: Engineer in a Box

Full workflow from design to merge.

## Step: design
Think carefully about architecture. Consider:
- Existing patterns in the codebase
- Trade-offs between approaches
- Testability and maintainability

Write a brief design summary before proceeding.

## Step: implement
Write the code. Follow codebase conventions.
Needs: design

## Step: review
Self-review the changes. Look for:
- Bugs and edge cases
- Style issues
- Missing error handling
Needs: implement

## Step: test
Write and run tests. Cover happy path and edge cases.
Fix any failures before proceeding.
Needs: implement

## Step: submit
Submit for merge via refinery.
Needs: review, test
```

## quick-fix

```markdown
id: mol-quick-fix
type: molecule
title: Quick Fix

Fast path for small changes.

## Step: implement
Make the fix. Keep it focused.

## Step: test
Run relevant tests. Fix any regressions.
Needs: implement

## Step: submit
Submit for merge.
Needs: test
```

## research

```markdown
id: mol-research
type: molecule
title: Research

Investigation workflow.

## Step: investigate
Explore the question. Search code, read docs,
understand context. Take notes.

## Step: document
Write up findings. Include:
- What you learned
- Recommendations
- Open questions
Needs: investigate
```

## Storage

Built-in molecules live in `<town>/.beads/` as regular issues.
Created during `gt install` or `bd init`.


Move disk 5: C → A

Move disk 5 from peg C to peg A. (Move 80/1023)


Digest: mol-deacon-patrol

Patrol cycle 15: 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.


Merge: valkyrie-mjw71b7u

branch: polecat/valkyrie-mjw71b7u
target: main
source_issue: valkyrie-mjw71b7u
rig: gastown
agent_bead: gt-gastown-polecat-valkyrie


Digest: mol-deacon-patrol

P6: stable, beads polecats exited


Digest: mol-deacon-patrol

Patrol 12


Digest: mol-deacon-patrol

Patrol 14: All healthy, 2 crew active


Design molecule step hooks

Hooks that fire between molecule steps. When a bead in a molecule closes, trigger hook that can spawn agent attention to prompts/requests. This enables reactive orchestration - the molecule drives, hooks respond. Gas Town feature built on Beads data plane.


Fix CLI mismatches from bd-2fs7 (wisp->ephemeral migration)

bd-2fs7 moved wisp/pour under bd mol, but gastown wasn't updated.

Fixed:
- router.go: --wisp -> --ephemeral for bd create
- patrol_helpers.go: bd wisp create -> bd mol wisp create
- wisp_check.go: bd wisp gc -> bd mol wisp gc

This was causing handoff failures (gt mail send errored with 'unknown flag: --wisp').


Move disk 1: B → C

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


Digest: mol-deacon-patrol

Patrol 12: healthy


Digest: mol-deacon-patrol

Patrol 6: all healthy


mol-deacon-patrol


Digest: mol-deacon-patrol

Patrol 14: all quiet


Digest: mol-deacon-patrol

Patrol 20: All healthy - final patrol


Move disk 1: B → C

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


Digest: mol-deacon-patrol

Patrol 155 complete


Add GitHub CI workflow for PRs

Gas Town has no CI. Add .github/workflows/ci.yml that runs tests and linter on PRs. Reference beads repo for example.


Digest: mol-deacon-patrol

Patrol 203: Routine checks, all systems nominal


Digest: mol-deacon-patrol

Patrol 19: All clear


Digest: mol-deacon-patrol

Patrol 8: OK


Move disk 1: A → B

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


Workspace detection: Find() walking up directory tree

Find workspace root by walking up directory tree looking for Gas Town markers.

## Detection Logic

Walk up from current directory, looking for:
1. `config/town.json` - Primary marker (visible config dir per gt-iib)
2. `mayor/` directory at town level - Secondary marker

Stop at filesystem root if neither found.

## Interface

```go
// Find locates the town root from the given directory
func Find(startDir string) (string, error)

// FindOrError is like Find but returns a user-friendly error
func FindOrError(startDir string) (string, error)
```

## Return Values

- Success: Absolute path to town root
- Not found: Empty string + specific error
- Error: Empty string + wrapped error

## Edge Cases

- Symlinks: Follow them (use filepath.EvalSymlinks)
- Permissions: Return error if can't read directory
- Nested towns: Return nearest ancestor (shouldn't happen in practice
EOF
)


Worker prompting: Beads write access

Add beads write access section to polecat AGENTS.md.template.

## Beads Access Section for Prompting

```markdown
## Beads Access

You have **full beads access** - create, update, and close issues.

### Quick Reference

```bash
# View work
bd ready                    # Issues ready (no blockers)
bd list                     # All open issues
bd show <id>                # Issue details

# Create issues
bd create --title="Fix bug" --type=bug --priority=2
bd create --title="Add feature" --type=feature

# Update issues
bd update <id> --status=in_progress    # Claim work
bd close <id>                          # Mark complete

# Sync (required before merge!)
bd sync                     # Commit beads changes to git
```

### When to Create Issues

Create beads issues when you discover work that:
- Is outside your current task scope
- Would benefit from tracking
- Should be done by someone else

**Good examples**:
```bash
bd create --title="Race condition in auth" --type=bug --priority=1
bd create --title="Document API rate limits" --type=task --priority=3
```

**Don't create for**:
- Tiny fixes you can do in 2 minutes
- Vague "improvements" with no scope
- Work already tracked elsewhere

### Beads Sync Protocol

**CRITICAL**: Always sync beads before merging!

```bash
bd sync                    # Commits beads changes
git add .beads/
git commit -m "beads: sync"
```

If you forget to sync, beads changes are lost when session ends.
```

## Implementation

Add to AGENTS.md.template polecat section.


Digest: mol-deacon-patrol

Patrol 128: All healthy


Move disk 3: A → B

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


Digest: mol-deacon-patrol

Patrol cycle 16: All healthy.


Move disk 2: A → C

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


Resolve external dependencies

Resolve external dependencies across rigs.

When an issue in one rig closes, any dependencies in other rigs should be notified. This enables cross-rig coordination without tight coupling.

**Step 1: Check recent closures from feed**
```bash
gt feed --since 10m --plain | grep "✓"
# Look for recently closed issues
```

**Step 2: For each closed issue, check cross-rig dependents**
```bash
bd show <closed-issue>
# Look at 'blocks' field - these are issues that were waiting on this one
# If any blocked issue is in a different rig/prefix, it may now be unblocked
```

**Step 3: Update blocked status**
For blocked issues in other rigs, the closure should automatically unblock them (beads handles this). But verify:
```bash
bd blocked
# Should no longer show the previously-blocked issue if dependency is met
```

**Cross-rig scenarios:**
- bd-xxx closes → gt-yyy that depended on it is unblocked
- External issue closes → internal convoy step can proceed
- Rig A issue closes → Rig B issue waiting on it proceeds

No manual intervention needed if dependencies are properly tracked - this step just validates the propagation occurred.


Enhance Mayor CLAUDE.md with GGT milestone tracking

Update ~/ai/CLAUDE.md (Mayor startup context) with:

1. GGT Self-Hosting Milestone section
   - Track progress toward gt replacing town
   - Key blockers: gt-h5n (merge queue), gt-974 (daemon)
   - What "self-hosting" means (GGT working on itself)

2. Recent Architecture Decisions
   - Engineer = role, Refinery = place
   - Merge queue in Beads (not branch discovery)
   - Session restart protocol

3. Transition Plan
   - Current: use town commands (PGT)
   - Target: use gt commands (GGT)
   - Switch criteria: gt-b1g closed

Keep it concise - Mayor context should be quick to scan.


Load persisted patrol state

Read handoff bead and get nudge counts.

Load persistent state from the witness handoff bead:
- Active workers and their status from last cycle
- Nudge counts per worker per issue
- Last nudge timestamps
- Pending escalations

```bash
bd show <handoff-bead-id>
```

If no handoff exists (fresh start), initialize empty state.
This state persists across wisp burns and session cycles.


Digest: mol-deacon-patrol

P9: stable


Implement

Implement the solution for gt-8tmz.34. 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.


Molecule schema: YAML format for workflow definitions

Define the YAML schema for molecule definitions:

```yaml
molecule: <name>
version: 1
description: "Human description"
steps:
  - id: <step-id>
    title: "Step title"
    prompt: "Instructions for agent"
    depends: [<other-step-ids>]  # optional
    tier: haiku|sonnet|opus      # optional, default from config
    timeout: 30m                 # optional
```

Store molecules in:
- `<rig>/molecules/<name>.yaml` for rig-specific
- `<town>/molecules/<name>.yaml` for town-wide

Built-in molecules to ship:
- engineer-in-box: design→code→review→test→submit
- quick-fix: implement→test→submit
- research: investigate→document


Move disk 2: C → B

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


Rotate logs and prune state

Maintain daemon logs and state files.

**Step 1: Check daemon.log size**
```bash
# Get log file size
ls -la ~/.beads/daemon*.log 2>/dev/null || ls -la ~/gt/.beads/daemon*.log 2>/dev/null
```

If daemon.log exceeds 10MB:
```bash
# Rotate with date suffix and gzip
LOGFILE="$HOME/gt/.beads/daemon.log"
if [ -f "$LOGFILE" ] && [ $(stat -f%z "$LOGFILE" 2>/dev/null || stat -c%s "$LOGFILE") -gt 10485760 ]; then
    DATE=$(date +%Y-%m-%dT%H-%M-%S)
    mv "$LOGFILE" "${LOGFILE%.log}-${DATE}.log"
    gzip "${LOGFILE%.log}-${DATE}.log"
fi
```

**Step 2: Archive old daemon logs**

Clean up daemon logs older than 7 days:
```bash
find ~/gt/.beads/ -name "daemon-*.log.gz" -mtime +7 -delete
```

**Step 3: Prune state.json of dead sessions**

The state.json tracks active sessions. Prune entries for sessions that no longer exist:
```bash
# Check for stale session entries
gt daemon status --json 2>/dev/null
```

If state.json references sessions not in tmux:
- Remove the stale entries
- The daemon's internal cleanup should handle this, but verify

**Note**: Log rotation prevents disk bloat from long-running daemons.
State pruning keeps runtime state accurate.


Digest: mol-deacon-patrol

Patrol cycle 10: routine, healthy - midpoint


Add GitHub issue/PR templates

Add .github/ISSUE_TEMPLATE/ with bug and feature templates. Add .github/PULL_REQUEST_TEMPLATE.md. Reference beads repo for examples.


Digest: mol-deacon-patrol

Patrol #18: Stable


Digest: mol-deacon-patrol

Patrol 14: all clear


Move disk 3: A → C

Move the largest disk from peg A to peg C.


Digest: mol-deacon-patrol

Patrol #13: Dog pool healthy, 1 idle.


Move disk 1: C → A

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


Merge: dementus-1767084022436

branch: polecat/dementus-1767084022436
target: main
source_issue: dementus-1767084022436
rig: gastown


MVP Takeoff: Polecats just work

## Goal
Get to the point where we can sling any issue to a polecat with a formula and it "just works" end-to-end.

## Success Criteria
1. `gt daemon start` brings up the engine
2. Deacon patrols: inbox, health checks, cleanup
3. Witnesses patrol: monitor polecats, verify completion, cleanup
4. Refineries patrol: process merge queue
5. Polecat lifecycle: spawn → work → complete → cleanup
6. Shiny formula: design → implement → review → test → submit

## What This Enables
- "Engineer in a box" - take any issue, expand via shiny, get a reviewed/tested PR
- Reliable multi-agent coordination
- Self-healing infrastructure (patrols fix problems)

## Blocked By
- gt-ronyn (deacon murder bug) - FIXED
- Basic patrol formulas - DONE (mol-*-patrol.formula.toml exist)

## Children
See linked tasks below.


Clean dead sessions

Clean dead sessions.

Garbage collect terminated sessions:
- Remove stale polecat directories
- Clean up wisp session artifacts
- Prune old logs and temp files
- Archive completed molecule state

```bash
gt gc --sessions
gt gc --wisps --age=1h
```

Preserve audit trail. Only clean sessions confirmed dead.


Digest: mol-deacon-patrol

Patrol 16


Digest: mol-deacon-patrol

Patrol 16: OK


Move disk 1: C → A

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


Digest: mol-deacon-patrol

P12: stable


Digest: mol-deacon-patrol

Patrol 118: All healthy


Merge: bullet-mjwlbeu5

branch: polecat/bullet-mjwlbeu5
target: main
source_issue: bullet-mjwlbeu5
rig: gastown
agent_bead: gt-gastown-polecat-bullet


Digest: mol-deacon-patrol

Patrol 4: All clear


gt convoy create: Default --notify to mayor/

When Mayor creates a convoy, --notify should default to mayor/ since:
1. Mayor dispatched the work
2. Mayor should know when it lands
3. Reduces flag boilerplate

Implementation: Check actor identity, if mayor, default notify to 'mayor/'


Move disk 2: A → C

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