Fix namepool Save() to use write lock

attached_args: Fix namepool Save() mutex for thread safety

Fix incorrect mutex usage in namepool Save() method.

## Files to modify
- internal/polecat/namepool.go

## Problem (lines 179-194)
Save() uses RLock() but performs file I/O:
```go
func (p *NamePool) Save() error {
    p.mu.RLock()  // WRONG: file write needs write lock
    defer p.mu.RUnlock()
    // ... file operations ...
}
```

## Fix
Change to write lock:
```go
func (p *NamePool) Save() error {
    p.mu.Lock()
    defer p.mu.Unlock()
    // ... file operations ...
}
```

## Acceptance criteria
- [ ] Save() uses Lock() instead of RLock()
- [ ] go test -race ./internal/polecat/... passes
- [ ] Existing namepool tests still pass


Digest: mol-deacon-patrol

Patrol #18: Quick cycle, all quiet.


Add self-check context guidance to role CLAUDE.md files

Each role's CLAUDE.md needs guidance for context self-management:

- After each patrol cycle, self-assess context pressure
- Heuristics: feeling compressed, lots of tool calls, long session
- If triggered: initiate handoff before continuing

Roles to update:
- Mayor (~/gt/CLAUDE.md)
- Witness template
- Refinery template
- Polecat template
- Crew template
- Deacon template

This is the 'inversion of control' - agents decide when to cycle, not external monitoring.


Merge: dementus-1767140140908

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


Digest: mol-deacon-patrol

Cycle 9: quiet


Digest: mol-deacon-patrol

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


Digest: mol-deacon-patrol

Patrol 7: All clear


Digest: mol-deacon-patrol

Patrol 1: All 3 rigs healthy, 17 sessions running, no issues


Add --fart as easter egg alias for bd mol bond

Add a hidden alias for the bond command:

```bash
bd mol fart mol-polecat-work --wisp
# equivalent to:
bd mol bond mol-polecat-work --wisp
```

## Context
The fart joke: instantiating a proto can produce either:
- A Mol (solid/substantial output)
- A Wisp (gas/ephemeral output)

## Implementation
- Add 'fart' as an alias in the mol subcommand
- No documentation needed (easter egg)
- Maybe a fun message: 'Bonding molecule...' or similar

Low priority, just for fun.


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.


Digest: mol-deacon-patrol

Patrol 2: Quick pass, all healthy


Add Boot shutdown to gt shutdown

gt shutdown should stop Boot if running. Currently Boot is only spawned by daemon but never explicitly stopped.

Added Boot shutdown to gt down command. Boot now stopped between Mayor and Deacon.


Digest: mol-deacon-patrol

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


Activity stream infrastructure check

Verify activity stream infrastructure exists and is sufficient for MQ/witness events.

Check:
- Does gt feed already have event infrastructure?
- Can we emit custom events from Go code?
- What format do events need?

If infrastructure exists, close this. If not, implement minimal event emission.

## Infrastructure Assessment: SUFFICIENT with minor gaps

### Current Event Infrastructure

1. **townlog** (internal/townlog/logger.go)
   - CAN emit events from Go code
   - Event types: spawn, wake, nudge, handoff, done, crash, kill
   - Output: ~/gt/logs/town.log (text format)
   - Convenience functions: LogSpawn, LogWake, LogNudge, LogDone, etc.
   - Used by: session.go, stop.go, log.go

2. **bd activity** (beads CLI)
   - Shows issue/molecule state changes
   - Events from beads database mutations
   - This IS what gt feed TUI displays
   - To emit events: create/update beads issues

3. **JSONLSource** (internal/tui/feed/events.go:214-290)
   - Ready to read JSONL events from file
   - Format: {timestamp, type, actor, target, message, rig, role}
   - Currently unused (no producer writes to this)

4. **gt feed TUI** (internal/cmd/feed.go)
   - Wraps bd activity in interactive TUI
   - Agent tree + event stream panels
   - Can consume from BdActivitySource or JSONLSource

### Answers to Task Questions

Q: Does gt feed already have event infrastructure?
A: YES - reads from bd activity (beads mutations) and has JSONLSource ready

Q: Can we emit custom events from Go code?
A: YES - townlog.Logger.Log() emits events, but they go to text log not activity stream

Q: What format do events need?
A: For gt feed: JSONL with {timestamp, type, actor, target, message, rig, role}

### Gap Analysis

For MQ/Witness events to appear in gt feed, dependent tasks need to either:

**Option A** (Recommended): Extend townlog to dual-write
- Add new EventTypes (patrol_started, merge_started, etc.)
- Write to JSONL file in addition to text log
- Update gt feed to also consume from this file
- ~50-100 lines of changes

**Option B**: Use beads issues
- Create operational beads for patrol cycles, merge requests
- Their state changes appear automatically in bd activity
- More invasive, creates many ephemeral beads

### Files for Dependent Tasks

- internal/townlog/logger.go - Add event types, dual-write
- internal/tui/feed/events.go - JSONLSource already exists
- internal/cmd/feed.go - Add secondary source (if needed)


Digest: mol-deacon-patrol

Patrol 132: All healthy


Digest: mol-deacon-patrol

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


Digest: mol-deacon-patrol

Patrol 11: All healthy


Merge: morsov-mjwcd60m

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


Digest: mol-deacon-patrol

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


Digest: mol-deacon-patrol

Patrol #6: All nominal


Digest: mol-deacon-patrol

Patrol cycle 58: All healthy


Protocol: Type System for Formulas

Protocols define interfaces that formulas implement - a type system for workflows.

## Concept

```toml
# reviewable.protocol
[protocol]
name = "Reviewable"

[requires]
steps = ["review"]  # Must have a step tagged "review"
outputs = ["review_decision"]  # Must produce this

[guarantees]
"review completes before any deploy step"
```

Formulas declare: `implements = ["Reviewable", "Deployable"]`

System verifies compliance statically.

## Use Cases

1. Ensure all deploy formulas have review steps
2. Define compliance requirements as protocols
3. Enable formula discovery: "Give me all Deployable formulas"
4. Validate formula composition compatibility

## Properties

- Static verification (before execution)
- Composable (protocol can extend protocol)
- Documentation value (self-describing contracts)

## Open Questions

1. Protocol syntax - embedded in formula or separate files?
2. Verification timing - cook time? load time?
3. Protocol versioning - how do protocols evolve?
4. Inheritance - can protocols extend other protocols?

## Related

- docs/formula_evolution.md - "Formula Schemas" section
- gt-8tmz - molecule algebra


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 217: All nominal


Implement sendToQueue() for queue message delivery

Add queue message delivery to internal/mail/router.go.

SEMANTICS:
- Queue messages are stored in a shared location, NOT individual inboxes
- Location: {townRoot}/.beads/ with special metadata

MESSAGE METADATA:
Add to message struct or use existing fields:
- queue_name: which queue this belongs to
- claimed_by: empty until claimed
- claimed_at: timestamp when claimed

IMPLEMENTATION:
1. Add sendToQueue(msg *Message) error
2. Validate sender is eligible (optional, or allow anyone to post)
3. Create message bead with queue_name in metadata
4. Message To field should be 'queue:{name}'

FILE: internal/mail/router.go
PATTERN: Follow sendToList() at line 567 but create ONE copy, not fan-out

Do not implement claim/release yet - just delivery.


Merge: furiosa-mjw1p03l

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

Stale MR - branch has no new commits or doesn't exist


Clarify formula semantics: read-only reference, not instantiated

## Problem

An agent (likely the Deacon) read the `mol-deacon-patrol.formula.toml` file and created beads from its steps. This is wrong - formulas are reference documents describing a workflow, not templates to be instantiated into trackable work.

## What Happened

1. Formula exists at `.beads/formulas/mol-deacon-patrol.formula.toml`
2. Deacon (or predecessor agent) created an epic + 9 task beads matching the formula steps
3. These showed up in `bd ready` (separate bug filed)

## Correct Model

| Artifact | Purpose | Created How |
|----------|---------|-------------|
| Formula (.toml) | Reference doc describing workflow | Manual/design |
| Wisp | Ephemeral execution context | `bd wisp create` (no child beads) |
| Proto | Template for pour | `bd cook` from formula |

**Formulas should NOT create beads.** They're documentation. When the Deacon runs a patrol, it follows the formula instructions directly - it doesn't need beads for each step.

## Fix Needed

1. Update Deacon template to clarify: "Follow the formula instructions. Do not create beads from formula steps."
2. Audit what command created the beads - was it `bd wisp create` expanding the formula? If so, that command shouldn't create child beads.
3. Consider renaming formulas to `.md` if they're just prose instructions.

(Moved from hq-ufiy)

Invalid premise. Formulas ARE meant to create beads when poured/wisped - that's the core MEOW design. The actual bug was an agent manually creating issues from formula steps instead of using bd wisp/pour commands.


Digest: mol-deacon-patrol

Patrol 8


Digest: mol-deacon-patrol

Patrol 22: Rotated 10MB daemon log. All agents healthy. 3 polecats idle. No callbacks. 3 convoys in progress.


gt unsling uses wrong beads dir for remote agents

**Bug**: `gt unsling <target-agent>` searches the local beads directory instead of the target agent's rig beads.

**Reproduction**:
```bash
# From gastown/crew/max:
gt status  # Shows joe has hook gt-7aw1m
gt unsling gastown/crew/joe -f  # Says 'No work hooked'
```

**Root cause**: `internal/cmd/unsling.go:88` calls `findLocalBeadsDir()` which uses cwd.

**Fix**: When `targetAgent` is set, resolve the target's rig path and use `beads.New(rigPath)` instead of local beads dir.

**Reference**: `gt status` does this correctly in `discoverRigHooks()` using `beads.New(r.Path)`.


Digest: mol-deacon-patrol

Patrol cycle 10: All quiet.


Digest: mol-deacon-patrol

Patrol #17: Health pinged all refineries.


Make documentation convoy-first

Update all gt/gastown documentation to be convoy-first:

1. Reference docs: Show convoy create before sling in examples
2. CLAUDE.md / mayor priming: Convoy is the standard workflow
3. User docs: convoy list as primary dashboard view
4. Remove/update any 'just sling' examples that skip convoy

Convoy is the primary unit of work tracking. All slings should be part of a convoy.

Updated README.md, reference.md, understanding-gas-town.md, mayor.md.tmpl, and crew.md.tmpl to be convoy-first


Digest: mol-deacon-patrol

Patrol 4: All clear


Digest: mol-deacon-patrol

Patrol 5: All healthy.


Day 2.5: Test daemon pokes based on agent state

Integration test:
1. Create agent bead with state=idle
2. Sling work → hook_bead set
3. Verify daemon pokes
4. Update state=running
5. Verify daemon doesn't double-poke
6. Update state=stopped
7. Verify daemon re-pokes on new work

Parent: gt-d0jqp


Digest: mol-deacon-patrol

Patrol 2: 3 rigs healthy, no incidents


Digest: mol-deacon-patrol

Patrol 12: all clear


Digest: mol-deacon-patrol

Patrol cycle 47: All healthy


Digest: mol-deacon-patrol

Patrol 13: quiet


Merge: nux-mjw3mn8o

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


Digest: mol-deacon-patrol

Patrol 10: Routine. All 3 rigs healthy. 12 polecats. 1 MQ pending.


Fix convoy refresh scheduling causing duplicates

model.go:191-197 schedules both fetchConvoys() and convoyRefreshTick() on every update, potentially causing duplicate refreshes. The tick should only be scheduled once initially.


Merge: furiosa-1767141944421

branch: polecat/furiosa-1767141944421
target: main
source_issue: furiosa-1767141944421
rig: gastown


Digest: mol-deacon-patrol

Patrol 114: All healthy


Crew CLAUDE.md overwritten by polecat template

The crew worker CLAUDE.md files (crew/max, crew/joe, crew/jack) have been overwritten with the polecat-CLAUDE.md template content.

**Expected**: Crew workers should have mayor-like context (they share the rig repo, work on main branch, plan work)

**Actual**: Crew CLAUDE.md says 'Polecat ace' and includes polecat-specific instructions (don't push to main, wait for Witness to kill session, etc.)

**Impact**:
- Crew workers getting wrong identity context
- Ready Front planning guidance in gotchas section was lost
- Crew workers told not to push to main (but they should)

**Root cause**: Likely gt polecat template deployment hit crew directories

**Fix needed**:
- Restore crew CLAUDE.md template (or create one if missing)
- Ensure template deployment only targets polecats/ directories
- Add Ready Front planning section to crew template

Fixed crew CLAUDE.md files:
1. Regenerated with correct crew template (not polecat template)
2. Added CLAUDE.md to .gitignore to prevent cross-clone contamination
3. Each crew member now has their own CLAUDE.md with correct identity


gt polecat add should spawn with --dangerously-skip-permissions

When adding polecats via gt polecat add, the subsequent Claude session needs --dangerously-skip-permissions flag to run autonomously.

Currently:
- gt polecat add creates worktree
- tmux new-session spawns 'claude' without flags
- Polecat gets stuck at permission prompts

Needed:
- gt polecat add (or gt sling) should spawn with --dangerously-skip-permissions
- Or store a config in polecat worktree indicating autonomous mode

This is critical for swarm automation - polecats can't self-approve permissions.


Refinery emits activity events

Refinery emits events to activity stream for MQ lifecycle:

Events to emit:
- merge_started: When refinery begins processing an MR
- merged: When MR successfully merged to main
- merge_failed: When merge fails (conflict, tests, etc.)
- merge_skipped: When MR skipped (already merged, etc.)

Events should include: MR ID, worker, branch, timestamp, reason (for failures)

This replaces stats tracking in .runtime/refinery.json

Implemented all MQ lifecycle events in refinery: merge_started, merged, merge_failed, merge_skipped


Digest: mol-deacon-patrol

Patrol cycle 15: All 6 agents healthy


gt peek should support cross-rig crew paths like beads/crew/dave

## Problem

`gt peek beads/crew/dave` fails with "session not found" even when the session exists.

The command expects `<rig/polecat>` format but crew workers in other rigs use
`<rig>/crew/<name>` paths.

## Current behavior

```bash
gt peek beads/crew/dave
# Error: session not found
```

## Expected behavior

```bash
gt peek beads/crew/dave
# Should peek at the beads rig crew member dave
```

## Fix

The peek command should:
1. Parse paths with `/crew/` as crew workers, not polecats
2. Resolve cross-rig crew sessions correctly
3. Handle both `rig/polecat` and `rig/crew/name` formats

Fixed: gt peek now checks for crew/ prefix in polecatName and uses crewSessionName() to generate correct session name


Digest: mol-deacon-patrol

Patrol 10: Quiet


Digest: mol-deacon-patrol

Patrol 47: All healthy


Digest: mol-deacon-patrol

Patrol 109: All healthy


Digest: mol-deacon-patrol

Patrol cycle 14


Digest: mol-deacon-patrol

Patrol 10: all healthy


Digest: mol-deacon-patrol

Patrol cycle 20: All healthy


Digest: mol-deacon-patrol

Patrol 84: All healthy


Digest: mol-deacon-patrol

Patrol 143 complete: All agents healthy


Rig management commands for town startup/shutdown

All 5 child commands implemented and verified: gt rig start/stop/status, gt crew start/stop


Digest: mol-deacon-patrol

Patrol 20: all healthy


Digest: mol-deacon-patrol

Patrol cycle 8


Digest: mol-deacon-patrol

Patrol cycle 15


Digest: mol-deacon-patrol

Patrol 65: Routine


Digest: mol-deacon-patrol

Patrol cycle 12: All healthy.


Digest: mol-deacon-patrol

Patrol cycle 13: All healthy.


Digest: mol-deacon-patrol

Patrol #14


Merge: furiosa-mjxap5fz

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


Remove schedule/phase terminology from code

Temporal/schedule language in identifiers is an anti-pattern.

## Found Issues

### beads repo
- `examples/multi-phase-development/` directory
  - Rename to `examples/dependency-sequenced-work/` or similar

### gastown repo
- `internal/cmd/start.go` lines 178-195
  - Uses "Phase 1:", "Phase 2:", etc. in printf output
  - Change to descriptive names: "Interrupting agents...", "Requesting handoff...", etc.

- `internal/swarm/landing.go` lines ~50-70
  - Comments say "// Phase 1: Stop all polecat sessions"
  - Change to "// Step: Stop all polecat sessions" or just remove phase labels

## Why This Matters

Phase/version language in names:
1. Implies a fixed schedule (antithetical to dependency-driven work)
2. Creates confusion with molecule "phases" (solid/liquid/gas)
3. Encourages temporal thinking that leads to backwards dependencies

## What To Keep

- Molecule phase terminology (pour/wisp/proto) - this is chemistry, not scheduling
- Version fields inside files (version: 1) - this is semantic versioning


Digest: mol-deacon-patrol

Patrol 4: all healthy


Plugin: Plan-to-Epic converter

## Purpose

Help users create beads epics from various planning inputs.

## Inputs
- Markdown task lists
- GitHub issues
- Linear/Jira exports
- Free-form descriptions
- Existing beads epics

## Output
- Beads epic with properly structured children
- Dependencies set for wave ordering
- Priorities assigned
- Ready for `gt spawn --epic <id>`

## Implementation Options

### Option A: CLI Tool
```bash
gt plan import --from github --repo owner/repo --label batch-candidate
gt plan import --from markdown tasks.md
gt plan structure <epic-id>  # analyze and add dependencies
```

### Option B: Plugin Agent
A plugin at `<rig>/plugins/plan-oracle/` that:
- Receives planning requests via mail
- Analyzes scope and requirements
- Creates structured beads epic
- Sets dependencies based on analysis

### Option C: Interactive Mode
```bash
gt plan create
# Walks through questions, creates epic interactively
```

## Axiom

As stated: 'The Planning phase should end in the creation of a workable Beads plan.'

This plugin bridges the gap between human planning and machine-executable work.

## Priority

P2 - Nice to have for MVP. Manual epic creation works for now.

## Note

No "swarm IDs" - output is just a beads epic with children. Workers process it independently.


Merge: gt-veswi

branch: polecat/toast-mjxm0mmo
target: main
source_issue: gt-veswi
rig: gastown
agent_bead: gt-mayor

Merged to main at 1805d5b0 (toast-mjxm0mmo spawn alias)


Digest: mol-deacon-patrol

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


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 7: Routine


Digest: mol-deacon-patrol

Patrol 94: All healthy


Digest: mol-deacon-patrol

Patrol 6: quiet


Digest: mol-deacon-patrol

Patrol cycle 4: All healthy


Digest: mol-deacon-patrol

Patrol 10: All healthy.


Day 4.2: Implement gt polecat nuke command

Add gt polecat nuke <name> command:
- Kill the Claude session
- Delete the worktree
- Delete the branch
- Remove agent bead
- Full cleanup post-merge

Parent: gt-4a2qt


Digest: mol-deacon-patrol

Patrol 118: All healthy


Merge: gt-ldk8

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


Digest: mol-deacon-patrol

Patrol cycle 10: All healthy.


Day 4.3: Polecat self-manages session handoffs

**REVISED**: Session cadence is polecat-managed, not mechanically forced by Witness.

Polecats decide when to cycle their own sessions:
1. Work through molecule steps sequentially in one session
2. Close each step as completed (bd close, for activity feed)
3. Self-initiate handoff when: context filling, logical chunk done, or stuck
4. Use: gt handoff -s 'Continuing molecule' -m '<context notes>'

If polecat forgets to handoff:
- Compaction will force it eventually
- Work continues from hook (molecule state preserved)
- No work is lost

Witness role changes:
- Does NOT force recycle between steps
- DOES monitor for stuck (long idle on same step)
- DOES use recycle for stuck recovery (not routine step transitions)
- DOES verify clean state before nuke

This is more ZFC-compliant: polecats report their own needs.


Show actor only when not redundant with bead ID

Currently the feed shows actor even when obvious:

  [10:17:37] ✓ gt-s6r44 completed · ... @gastown/crew/max

The actor should be omitted when:
- The bead ID already identifies the agent (gt-crew-gastown-joe)
- The action makes the actor obvious (created by = actor)

Format should be:
  {timestamp} {symbol} {issue-id} {action} · {title} [@actor if not obvious]

Part of epic gt-u7dxq

Implemented actor omission logic in view.go for redundant cases: bead ID identifies agent, or create events


gt status is slow - needs performance optimization

Optimized from 13s to <1s: --no-daemon for bd calls, bulk agent/hook/session pre-fetching, parallel rig processing, --fast flag for skipping mail


Digest: mol-deacon-patrol

Patrol 77: Routine


Digest: mol-deacon-patrol

Patrol 16 complete


Digest: mol-deacon-patrol

Patrol cycle 2: all monitors healthy, 1 dog idle, no incidents


Digest: mol-deacon-patrol

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


Remove deprecated SessionBeacon function

## Context

The StartupNudge migration (gt-7pp3l) replaced all SessionBeacon usages with StartupNudge.

## Current State

`SessionBeacon()` in `internal/session/names.go` is now dead code:
- Function definition exists at line 52
- No callers remain in the codebase

## Action

Remove the deprecated function:
```go
// SessionBeacon generates an identity beacon message for Claude Code sessions.
// ...
func SessionBeacon(address, molID string) string {
    // ...
}
```

## Risk

Low - function is unused. Verify with:
```bash
grep -r 'SessionBeacon' --include='*.go' . | grep -v 'names.go'
```

## Related

- gt-7pp3l: Migrate startup paths from SessionBeacon to StartupNudge
- gt-85whr: Agent Startup Consolidation epic (closed)

Removed SessionBeacon and documented StartupNudge format in reference.md


mol-outpost-assign: Intelligent work routing to outposts

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

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

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

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

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

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

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

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

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


Digest: mol-deacon-patrol

Patrol cycle 50: All healthy


#channel resolution for real-time broadcast

Wire tmux scanner into nudge system for #channel addresses.

## Deliverables

1. Parse #channel syntax in nudge:
   - #rig/gastown → nudge all running gastown agents
   - #town → nudge all running agents
   - #witnesses → nudge all running witnesses

2. Broadcast logic:
   - Resolve #channel to running sessions
   - Nudge each session
   - Ephemeral (no storage)

## Dependencies
- Tmux session scanner (gt-???)

## Acceptance
- #rig/gastown nudges all running gastown agents
- Ephemeral, no message storage
- Graceful handling of no-sessions


Digest: mol-deacon-patrol

Patrol cycle 35: All healthy, no incidents


Refactor patrol context functions to reduce duplication

In prime.go, three patrol context functions are nearly identical (~100 lines each):
- outputDeaconPatrolContext() - L797-940
- outputWitnessPatrolContext() - L942-1106
- outputRefineryPatrolContext() - L1108-1272

They all:
1. Check for existing patrol molecule
2. Auto-spawn if none exists
3. Display patrol work loop instructions

**Suggested refactor**:
Extract common logic into a helper:
```go
func outputPatrolContext(ctx RoleContext, patrolName string, assignee string) {
    // shared logic
}
```

Then each role-specific function just calls the helper with appropriate parameters.


gt polecat nuke: Refuse if unpushed commits or open MR

Agent prompts can be ignored. Code cannot.

`gt polecat nuke` should REFUSE to delete a polecat if:
1. Worktree has unpushed commits
2. Polecat has open MR beads
3. Polecat has work on hook

This is enforcement in code, not just instructions. The command itself should be safe.

Use existing `computeCleanupStatus()` in done.go as reference.

Implemented safety checks for gt polecat nuke: unpushed commits, open MR beads, work on hook


Digest: mol-deacon-patrol

Patrol #10: Milestone - all agents healthy. 1 dog idle. Gastown MQ 1 pending.


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

Fixed: removed --mol-type from bd update call, only set during create


Digest: mol-deacon-patrol

Patrol cycle 2: All 6 agents healthy, 3 polecats active (furiosa, nux, obsidian), beads refinery has 1 pending


Daemon sends heartbeat to Mayor instead of Deacon


Merge: gt-caih

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


Day 4.4: Witness calls nuke after MERGED signal

When refinery sends MERGED:
1. Witness receives MERGED mail
2. Witness calls gt polecat nuke
3. Full sandbox cleanup
4. Agent bead removed

Parent: gt-4a2qt


BranchPushedToRemote: Fetch remote tracking ref if not present locally

BranchPushedToRemote uses RemoteBranchExists (git ls-remote) to check if remote branch exists, but then compares with local origin/branch ref which may not exist if we just pushed.

## Repro
1. Push a new branch: git push -u origin branch-name
2. The local tracking ref origin/branch-name may not exist yet
3. BranchPushedToRemote errors: 'unknown revision origin/branch..HEAD'

## Fix
In BranchPushedToRemote, after confirming remote branch exists, run git fetch to ensure we have the local ref before comparing.

## Discovered
While implementing gt-bca67 (require pushed branch before MR creation)

Added git fetch before rev-list comparison to ensure local tracking ref exists


Digest: mol-deacon-patrol

Patrol 73: Routine


Merge: furiosa-1767138824776

branch: polecat/furiosa-1767138824776
target: main
source_issue: furiosa-1767138824776
rig: gastown


Standardize agent bead naming: prefix-rig-role-name

## The Problem

Agent bead IDs use INCONSISTENT naming patterns:

| Current (WRONG) | Should Be (prefix-rig-role-name) |
|-----------------|----------------------------------|
| gt-witness-gastown | gt-gastown-witness |
| gt-refinery-gastown | gt-gastown-refinery |
| gt-crew-gastown-max | gt-gastown-crew-max |
| gt-polecat-gastown-Toast | gt-gastown-polecat-Toast |

Town-level agents (no rig) are OK:
- gt-mayor ✓
- gt-deacon ✓

## The Convention

```
prefix-rig-role-name

Where:
- prefix: always 'gt'
- rig: rig name (absent for town-level agents)
- role: witness|refinery|crew|polecat|mayor|deacon
- name: agent name (absent for singleton roles like witness/refinery)
```

Examples:
- `gt-gastown-witness` (rig=gastown, role=witness, no name)
- `gt-gastown-crew-max` (rig=gastown, role=crew, name=max)
- `gt-beads-polecat-Toast` (rig=beads, role=polecat, name=Toast)
- `gt-mayor` (no rig, role=mayor, no name)

## Files to Update

### Agent bead ID generation
- internal/cmd/status.go (lines 316-335)
- internal/daemon/lifecycle.go (lines 546-579)
- internal/cmd/crew_add.go
- internal/polecat/manager.go
- internal/rig/manager.go
- internal/doctor/agent_beads_check.go
- internal/cmd/prime.go
- internal/session/names.go (session names vs bead IDs)

### Commands to verify
- gt status - displays agent beads
- gt doctor - creates missing agent beads
- gt rig add - creates witness/refinery beads
- gt crew add - creates crew beads
- gt sling - routes by agent ID
- gt mol status - looks up agent by ID

## Migration

1. Update all ID generation code
2. Create new agent beads with correct IDs
3. Migrate hook/role slots to new beads
4. Update any mail addresses
5. Delete old incorrectly-named beads

## Also from this session

Role bead slot cleanup was done - CreateAgentBead now calls bd slot set.
But legacy description parsing still exists in daemon/lifecycle.go.

## Reference
- ~/gt/docs/agent-as-bead.md
- Session 2025-12-29: Fixed role bead patterns (gt-crew-role etc)

Completed: standardized agent bead naming to prefix-rig-role-name


Merge: rictus-1767073382273

attached_args: Code review this merge request

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

REJECTED: Fix already on main (81b250ee). Branch is stale - merging would revert 10e79789 (swarm worker tracking fix) and other important commits. No action needed.


Digest: mol-refinery-patrol

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


Digest: mol-deacon-patrol

Patrol 16: routine


Digest: mol-deacon-patrol

Cycle 20: Final health check - all healthy


Digest: mol-deacon-patrol

Patrol 20: All healthy, handoff threshold


Add GUPP to non-polecat roles (Mayor, Deacon, Witness, Refinery)

GUPP (propulsion nudge after beacon) is only implemented for polecats in session/manager.go.

Other roles have different startup flows but could benefit from similar auto-propulsion:
- Mayor: mayor/manager.go or wherever mayor session starts
- Deacon: deacon startup flow
- Witness: witness startup flow
- Refinery: refinery startup flow

Each role may need role-specific propulsion message.

(Refiled from bd-8hea)

Added role-specific PropulsionNudge to Mayor, Deacon, Witness, and Refinery startup flows