Skip to content

[Gastown] PR 8.5: Mayor Tools — Cross-Rig Delegation#347

Merged
jrf0110 merged 2 commits into204-gt-prop-dfrom
339-mayor-tools
Feb 19, 2026
Merged

[Gastown] PR 8.5: Mayor Tools — Cross-Rig Delegation#347
jrf0110 merged 2 commits into204-gt-prop-dfrom
339-mayor-tools

Conversation

@jrf0110
Copy link
Copy Markdown
Contributor

@jrf0110 jrf0110 commented Feb 19, 2026

Summary

  • Add 5 mayor-specific tools (gt_sling, gt_list_rigs, gt_list_beads, gt_list_agents, gt_mail_send) so the Mayor agent can delegate work across rigs
  • New /api/mayor/:townId/tools/* worker routes with townId-scoped JWT auth (no rigId restriction)
  • Detailed mayor system prompt with tool documentation, GUPP principle, and delegation best practices
  • Conditional plugin loading: GASTOWN_AGENT_ROLE=mayor loads mayor tools, otherwise rig tools

Closes #339

Architecture

User → Mayor Chat → MayorDO → Container (kilo serve + Gastown plugin)
                                    ↓ GASTOWN_AGENT_ROLE=mayor
                              MayorGastownClient
                                    ↓
                        /api/mayor/:townId/tools/*
                                    ↓
                    mayorAuthMiddleware (townId JWT validation)
                                    ↓
              ┌─── GastownUserDO (list rigs)
              └─── RigDO (sling, beads, agents, mail)

Changes

Worker (cloudflare-gastown/src/)

  • handlers/mayor-tools.handler.ts (new) — 5 handlers: handleMayorSling, handleMayorListRigs, handleMayorListBeads, handleMayorListAgents, handleMayorSendMail
  • middleware/mayor-auth.middleware.ts (new) — JWT middleware that validates townId match (cross-rig, no rigId constraint)
  • prompts/mayor-system.prompt.ts (new) — buildMayorSystemPrompt() with role, tool docs, conversational model, GUPP
  • gastown.worker.ts — 5 new routes under /api/mayor/:townId/tools/*
  • dos/Mayor.do.ts — Uses buildMayorSystemPrompt(), passes GASTOWN_AGENT_ROLE=mayor, GASTOWN_TOWN_ID, GASTOWN_API_URL env vars to container

Plugin (cloudflare-gastown/container/plugin/)

  • mayor-tools.ts (new) — createMayorTools() with 5 tools for cross-rig delegation
  • client.tsMayorGastownClient class + createMayorClientFromEnv() for town-scoped API calls
  • types.tsRig, SlingResult, MayorGastownEnv types; fixed BeadStatus to include 'failed'
  • index.ts — Conditional tool loading based on GASTOWN_AGENT_ROLE; guarded prime/checkpoint for mayor

Testing

  • Both worker and container typechecks pass clean
  • All 34 existing plugin tests pass

Add mayor-specific tools so the Mayor agent can delegate work across rigs,
transforming it from a chatbot into the town coordinator described in the
Gastown architecture spec.

Worker:
- New /api/mayor/:townId/tools/* routes (sling, rigs, beads, agents, mail)
- mayorAuthMiddleware validates townId-scoped JWT (no rigId restriction)
- Handlers fan out to GastownUserDO (list rigs) and RigDO (sling, beads, agents, mail)

Plugin:
- MayorGastownClient for town-scoped HTTP operations
- 5 mayor tools (gt_sling, gt_list_rigs, gt_list_beads, gt_list_agents, gt_mail_send)
- Conditional loading: GASTOWN_AGENT_ROLE=mayor loads mayor tools, otherwise rig tools
- Guarded prime/checkpoint hooks (mayor has no rig-scoped prime)

MayorDO:
- Passes GASTOWN_AGENT_ROLE, GASTOWN_TOWN_ID, GASTOWN_API_URL env vars to container
- Uses buildMayorSystemPrompt() with detailed tool docs and delegation instructions

Closes #339
Comment thread cloudflare-gastown/src/handlers/mayor-tools.handler.ts Outdated
Comment thread cloudflare-gastown/src/handlers/mayor-tools.handler.ts
Comment thread cloudflare-gastown/src/middleware/mayor-auth.middleware.ts Outdated
@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot Bot commented Feb 19, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

All 3 issues from the previous review have been addressed in commit d2b6273:

  • handleMayorListRigs dev-mode 401 → fixed via resolveUserId() with query param fallback
  • ✅ No rig-to-town validation → fixed via verifyRigBelongsToTown() in all rig-scoped handlers
  • ✅ Unused AgentJWTPayload import → removed

The implementation is clean, follows existing patterns (auth middleware, client/handler structure), and properly separates mayor (town-scoped) from rig-scoped concerns.

Files Reviewed (9 files)
  • cloudflare-gastown/container/plugin/client.ts — new MayorGastownClient class + createMayorClientFromEnv()
  • cloudflare-gastown/container/plugin/index.ts — bifurcation between mayor and rig agent plugin modes
  • cloudflare-gastown/container/plugin/mayor-tools.ts — new mayor tool definitions (sling, list_rigs, list_beads, list_agents, mail_send)
  • cloudflare-gastown/container/plugin/types.ts — new types (Rig, SlingResult, MayorGastownEnv), added failed to BeadStatus
  • cloudflare-gastown/src/dos/Mayor.do.ts — env vars for mayor session, system prompt refactor
  • cloudflare-gastown/src/gastown.worker.ts — mayor tool route registration with auth middleware
  • cloudflare-gastown/src/handlers/mayor-tools.handler.ts — 5 handler functions with proper validation
  • cloudflare-gastown/src/middleware/mayor-auth.middleware.ts — townId-scoped JWT auth middleware
  • cloudflare-gastown/src/prompts/mayor-system.prompt.ts — extracted mayor system prompt

…llback, unused import

- Add verifyRigBelongsToTown() to all handlers that accept a rig_id,
  preventing cross-town rig access
- Add resolveUserId() with query param fallback for dev mode (where
  mayorAuthMiddleware is skipped and agentJWT is unset)
- Remove unused AgentJWTPayload import from mayor-auth.middleware.ts
@jrf0110 jrf0110 merged commit 49d0c36 into 204-gt-prop-d Feb 19, 2026
1 check passed
@jrf0110 jrf0110 deleted the 339-mayor-tools branch February 19, 2026 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant