Skip to content

[Gastown] PR 8.5: Mayor Tools — Cross-Rig Delegation (P0 — #1 Priority) #339

@jrf0110

Description

@jrf0110

Parent: #204 | Phase 1

⚠️ This is the single highest-priority remaining issue. Without tools, the Mayor is a chatbot that can't do anything. The entire chat-first product vision depends on the Mayor being able to delegate work via gt_sling. Until this lands, the product doesn't function.

Goal

Give the Mayor agent tools to delegate work across rigs. Without tools, the mayor is just a chatbot. With tools, it becomes the town coordinator described in the Gastown spec.

Tools

Tool Description Proxies to
gt_sling Sling a task to a polecat in a specific rig RigDO.slingBead(rigId, ...)
gt_list_rigs List all rigs in the town GastownUserDO.listRigs(townId)
gt_list_beads List beads in a rig (filterable by status) RigDO.listBeads(filter)
gt_list_agents List agents in a rig RigDO.listAgents(filter)
gt_mail_send Send mail to an agent in any rig RigDO.sendMail(...)

(gt_convoy_create deferred until convoy system lands in #220)

Implementation

The Mayor runs as a kilo serve session in the container. It needs the Gastown plugin loaded with mayor-specific tools. Two approaches:

Option A: Extend the existing plugin (Recommended)

The Gastown plugin at container/plugin/ already loads for all agents. Add mayor-specific tools that are only registered when GASTOWN_AGENT_ROLE=mayor env var is set. The tools call the Gastown worker API using the Mayor's JWT (which has townId scope, not rigId scope).

Option B: Separate mayor plugin

A second plugin loaded only for the mayor. More isolation but more packaging complexity.

Worker-side: Mayor tool routes

New handler file src/handlers/mayor-tools.handler.ts:

POST /api/mayor/:townId/tools/sling      → creates bead in target rig, assigns polecat
GET  /api/mayor/:townId/tools/rigs        → lists all rigs in the town
GET  /api/mayor/:townId/tools/beads       → lists beads (cross-rig fan-out)
GET  /api/mayor/:townId/tools/agents      → lists agents (cross-rig fan-out)
POST /api/mayor/:townId/tools/mail        → sends mail to agent in any rig

Auth: Mayor JWT validated by townId match. No rigId constraint (mayor is cross-rig).

Mayor System Prompt

The system prompt must:

  1. Describe the mayor's role as town coordinator (reference Gastown architecture)
  2. List available rigs, their repos, and their purposes
  3. Describe each tool with input/output schemas and when to use it
  4. Explain the conversational model: respond directly for questions, delegate via gt_sling for work
  5. Instruct non-blocking delegation: when slinging work, respond immediately to the user ("I've assigned Toast to work on that") — don't wait for the polecat to finish
  6. Follow the Propulsion Principle (GUPP)

Dependencies

Acceptance Criteria

  • Mayor-specific tools in the Gastown plugin (gt_sling, gt_list_rigs, gt_list_beads, gt_list_agents, gt_mail_send)
  • Worker routes for mayor tool endpoints with cross-rig fan-out
  • Mayor system prompt with tool descriptions and delegation instructions
  • Mayor JWT auth scoped to townId (no rigId restriction)
  • End-to-end: user sends message → Mayor calls gt_sling → polecat dispatched → user sees result in dashboard
  • Mayor responds conversationally about delegation (non-blocking UX)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions