# How the Mayor Agent Functions as a Global Coordinator in Gastown

> Discover how the Mayor agent in Gastown acts as a global coordinator. Learn about its role in work dispatch, escalation management, and state visibility for efficient system operation.

- Repository: [Gas Town Hall/gastown](https://github.com/gastownhall/gastown)
- Tags: architecture
- Published: 2026-07-07

---

**The Mayor agent serves as Gastown's central orchestrator, managing work dispatch through slot-open notifications, controlling escalation pathways for stuck workers, and maintaining global state visibility while protecting critical sections during interactive debugging sessions.**

The Mayor is the central nervous system of the gastownhall/gastown distributed execution framework. As the global coordinator, it maintains a high-level view of all active workers (polecats) and pending tasks (beads), making authoritative decisions about resource allocation and exceptional condition handling. Unlike individual worker agents that handle specific computational tasks, the Mayor operates as a singleton process running in its own isolated session, ensuring centralized control without interference.

## Global Role and Session Architecture

The Mayor's authority starts with its explicit declaration as a distinct role constant. In [`internal/constants/constants.go`](https://github.com/gastownhall/gastown/blob/main/internal/constants/constants.go), the system defines `RoleMayor = "mayor"`, establishing a canonical identifier used throughout the codebase for routing decisions and role-based access control.

Session isolation ensures the Mayor operates independently from worker processes. The Mayor runs inside a dedicated tmux session named `gt-mayor`, obtained via `session.MayorSessionName()`. This isolation allows the Mayor to persist across worker lifecycles and maintain state even when individual polecats terminate.

### Slot-Open Notification Protocol

When a polecat completes its assigned bead, the Witness agent signals the Mayor through the slot-open notification system. The `notifyMayorSlotOpen` function in [`internal/witness/handlers.go`](https://github.com/gastownhall/gastown/blob/main/internal/witness/handlers.go) (lines 880-900) implements this handshake:

```go
// Inside internal/witness/handlers.go
if result.Handled {
    // Tell the Mayor a polecat slot is free.
    notifyMayorSlotOpen(workDir, rigName, payload.PolecatName, payload.Exit)
}

```

This function first attempts to nudge the Mayor's tmux session directly. If the session is unreachable, it falls back to writing a `SLOT_OPEN` channel event that the Mayor picks up immediately upon recovery. This dual-channel approach ensures the global coordinator never misses worker availability updates, even during transient session disruptions.

## Escalation Handling and Safety Guards

The Mayor functions as the ultimate authority for exceptional conditions that automated workers cannot resolve. When the Witness detects stuck or unhealthy workers, it escalates to the Mayor rather than taking unilateral action.

### Worker Escalation Pathways

According to the CLAUDE templates in [`templates/witness-CLAUDE.md`](https://github.com/gastownhall/gastown/blob/main/templates/witness-CLAUDE.md) (lines 8, 25, and 62), the system explicitly requires human-level approval for forced cleanup operations. The templates instruct:

```text
7. **Escalation**: Report stuck workers to Mayor
...
Only use `--force` after Mayor authorizes or confirms work is unrecoverable.

```

This design prevents data loss by ensuring destructive operations receive explicit coordinator approval.

### ACP Protection During Interactive Sessions

To prevent automatic cleanup during active debugging, the Mayor implements Assistant Code Prompt (ACP) protection. When the Mayor's ACP session is active, cleanup operations are suppressed. The check in [`internal/witness/handlers.go`](https://github.com/gastownhall/gastown/blob/main/internal/witness/handlers.go) (around line 1335) implements this guard:

```go
if mayorSession := session.MayorSessionName(); mayorSessionIsActive {
    // Suppress automatic cleanup to prevent data loss during interactive debugging
}

```

This mechanism ensures that when developers are interactively debugging through the Mayor session, background workers cannot accidentally terminate processes or delete intermediate states.

## Observability and Control Interfaces

The Mayor exposes its coordination state through multiple interfaces, allowing both automated systems and human operators to monitor global health.

### Dashboard Status Exposure

The web dashboard renders the Mayor's operational status through the `MayorStatus` struct defined in [`internal/web/templates.go`](https://github.com/gastownhall/gastown/blob/main/internal/web/templates.go) (lines 107-114). The dashboard handler fetches this status via:

```go
mayor, err := h.fetcher.FetchMayor()
if err != nil {
    log.Printf("dashboard: FetchMayor failed: %v", err)
}

```

The status includes critical visibility fields: `IsAttached`, `IsActive`, and `Runtime`, displayed in the convoy UI to indicate whether the global coordinator is alive and responsive.

### Mail Routing and CLI Integration

The mail routing system in [`internal/mail/router.go`](https://github.com/gastownhall/gastown/blob/main/internal/mail/router.go) (lines 260-270) treats the Mayor as a first-class recipient, routing messages addressed to `mayor/` directly to the Mayor's session. This enables other agents—Witness, Deacon, and Refinery—to nudge the coordinator without knowing its underlying session details.

CLI commands throughout `internal/cmd/*` (including [`role.go`](https://github.com/gastownhall/gastown/blob/main/role.go) and [`unsling.go`](https://github.com/gastownhall/gastown/blob/main/unsling.go)) accept `mayor` as a valid target parameter. For example:

```bash
gt nudge mayor
gt mail mayor/status
gt prime mayor

```

This integration ensures the Mayor remains reachable from any part of the system, whether through automated mail routing or explicit operator commands.

## Summary

- The Mayor agent operates as a **singleton global coordinator** in a dedicated `gt-mayor` tmux session, isolated from worker processes.
- **Slot-open notifications** via `notifyMayorSlotOpen` ensure the Mayor tracks worker availability in real-time, enabling intelligent bead dispatch.
- **Escalation pathways** route exceptional conditions through the Mayor, preventing automated systems from taking destructive actions without authorization.
- **ACP protection** suppresses automatic cleanup during interactive debugging sessions, preventing data loss while the Mayor is actively managing the system.
- **Dashboard exposure** and **mail routing** provide visibility and control interfaces, making the Mayor's coordination state observable and manageable through both web UI and CLI.

## Frequently Asked Questions

### What triggers the Mayor to dispatch new work?

The Mayor dispatches new beads when it receives **slot-open notifications** from the Witness agent. After a polecat completes its current task, the Witness calls `notifyMayorSlotOpen` in [`internal/witness/handlers.go`](https://github.com/gastownhall/gastown/blob/main/internal/witness/handlers.go), signaling that a worker slot is available. The Mayor then evaluates the pending work queue and assigns the next bead to the available worker.

### How does the Mayor prevent accidental cleanup during debugging?

The Mayor implements **ACP (Assistant Code Prompt) protection**. When `mayorSessionIsActive` evaluates to true in [`internal/witness/handlers.go`](https://github.com/gastownhall/gastown/blob/main/internal/witness/handlers.go) (around line 1335), automatic cleanup operations are suppressed. This prevents background workers from terminating processes or deleting state while a developer is interactively debugging through the Mayor session.

### What happens if the Mayor session is not running?

If the Mayor's tmux session is unreachable, the `notifyMayorSlotOpen` function falls back to a **file-based channel event** mechanism. It writes a `SLOT_OPEN` event to the channel event file, which the Mayor processes immediately upon restart. This ensures no worker state changes are lost during temporary coordinator outages.

### How do other agents communicate with the Mayor?

Agents communicate through the **mail routing system** defined in [`internal/mail/router.go`](https://github.com/gastownhall/gastown/blob/main/internal/mail/router.go) (lines 260-270), which routes messages addressed to `mayor/` to the Mayor's session. Additionally, CLI commands like `gt nudge mayor` or `gt mail mayor/status` provide direct interaction capabilities from anywhere in the system.