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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions