Fully remove gt spawn from the codebase: - Delete spawn.go, create polecat_spawn.go with just sling helpers - Remove all gt spawn references from docs and CLAUDE.md - Update code comments to reference gt sling gt sling now handles ALL work dispatch: - Existing agents: gt sling <bead> mayor/crew/witness - Auto-spawn: gt sling <bead> <rig> - No-tmux: gt sling <bead> <rig> --naked - With args: gt sling <bead> --args "..." 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.5 KiB
Deacon Plugins
Town-level plugins that run during the Deacon's patrol loop.
Overview
The Deacon's patrol includes a plugin-run step. Rather than hardcoding what
runs, we use directory-based discovery at ~/gt/plugins/. Each plugin
directory contains enough information for the Deacon to decide whether to run
it and what to do.
Plugins are not pre-validated by tooling. The Deacon reads each plugin's metadata and instructions, decides if the gate is open, and executes accordingly.
Directory Structure
~/gt/plugins/
├── beads-cleanup/
│ ├── plugin.md # Gate info + instructions (combined)
│ └── state.json # Auto-managed runtime state
├── health-report/
│ ├── plugin.md
│ └── state.json
└── wisp-pressure/
├── plugin.md
└── state.json
Each plugin is a directory. If the directory exists, the plugin exists.
Plugin Metadata (plugin.md)
The plugin.md file contains YAML frontmatter for gate configuration,
followed by markdown instructions for the Deacon.
---
gate: cooldown
interval: 24h
parallel: true
---
# Beads Cleanup
Clean up old wisps daily.
## Actions
1. Run `bd cleanup --wisp --force`
2. Run `bd doctor` to verify health
3. Log summary of cleaned items
Frontmatter Fields
| Field | Required | Description |
|---|---|---|
gate |
Yes | Gate type: cooldown, cron, condition, event |
interval |
For cooldown | Duration: 1h, 24h, 5m, etc. |
schedule |
For cron | Cron expression: 0 9 * * * |
check |
For condition | Command that outputs a number |
operator |
For condition | Comparison: gt, lt, eq, ge, le |
threshold |
For condition | Numeric threshold |
trigger |
For event | Event name: startup, heartbeat |
cooldown |
Optional | Min time between runs (for condition gates) |
parallel |
Optional | If true, can run concurrently with other plugins |
Gate Types
Cooldown
Run at most once per interval since last successful run.
---
gate: cooldown
interval: 24h
---
Cron
Run on a schedule (standard cron syntax).
---
gate: cron
schedule: "0 9 * * *" # 9am daily
---
Condition
Run when a command's output crosses a threshold.
---
gate: condition
check: "bd count --type=wisp"
operator: gt
threshold: 50
cooldown: 30m # Don't spam even if condition stays true
---
The check command must output a single number. The Deacon compares it
against threshold using operator.
Event
Run in response to specific events.
---
gate: event
trigger: startup # Run once when daemon starts
---
Triggers: startup, heartbeat (every patrol), mail (when inbox has items).
State Management
The Deacon maintains state.json in each plugin directory:
{
"lastRun": "2025-12-21T10:00:00Z",
"lastResult": "success",
"runCount": 42,
"nextEligible": "2025-12-22T10:00:00Z"
}
This is auto-managed. Plugins don't need to touch it.
Parallel Execution
Plugins marked parallel: true can run concurrently. During plugin-run,
the Deacon:
- Scans
~/gt/plugins/for plugins with open gates - Groups them: parallel vs sequential
- Launches parallel plugins using Task tool subagents
- Runs sequential plugins one at a time
- Waits for all to complete before continuing patrol
Sequential plugins (default) run in directory order. Use sequential for plugins that modify shared state or have ordering dependencies.
Example Plugins
beads-cleanup (daily maintenance)
---
gate: cooldown
interval: 24h
parallel: true
---
# Beads Cleanup
Daily cleanup of wisp storage.
## Actions
1. Run `bd cleanup --wisp --force` to remove old wisps
2. Run `bd doctor` to check for issues
3. Report count of cleaned items
wisp-pressure (condition-triggered)
---
gate: condition
check: "bd count --type=wisp"
operator: gt
threshold: 100
cooldown: 1h
parallel: true
---
# Wisp Pressure Relief
Triggered when wisp count gets too high.
## Actions
1. Run `bd cleanup --wisp --age=4h` (remove wisps > 4h old)
2. Check `bd count --type=wisp`
3. If still > 50, run `bd cleanup --wisp --age=1h`
4. Report final count
health-report (scheduled)
---
gate: cron
schedule: "0 9 * * *"
parallel: false
---
# Morning Health Report
Generate daily health summary for the overseer.
## Actions
1. Run `gt status` to get overall health
2. Run `bd stats` to get metrics
3. Check for stale agents (no heartbeat > 1h)
4. Send summary: `gt mail send --human -s "Morning Report" -m "..."`
startup-check (event-triggered)
---
gate: event
trigger: startup
parallel: false
---
# Startup Verification
Run once when the daemon starts.
## Actions
1. Verify `gt doctor` passes
2. Check all rigs have healthy Witnesses
3. Report any issues to Mayor inbox
Patrol Integration
The mol-deacon-patrol step 3 (plugin-run) works as follows:
## Step: plugin-run
Execute registered plugins whose gates are open.
1. Scan `~/gt/plugins/` for plugin directories
2. For each plugin, read `plugin.md` frontmatter
3. Check if gate is open (based on type and state.json)
4. Collect eligible plugins into parallel and sequential groups
5. For parallel plugins:
- Use Task tool to spawn subagents for each
- Each subagent reads the plugin's instructions and executes
- Wait for all to complete
6. For sequential plugins:
- Execute each in order
- Read instructions, run actions, update state
7. Update state.json for each completed plugin
8. Log summary: "Ran N plugins (M parallel, K sequential)"
Limitations
-
No polecat spawning: Plugins cannot spawn polecats. If a plugin tries to use
gt sling, behavior is undefined. This may change in the future. -
No cross-plugin dependencies: Plugins don't declare dependencies on each other. If ordering matters, mark both as
parallel: false. -
No plugin-specific state API: Plugins can write to their own directory if needed, but there's no structured API for plugin state beyond what the Deacon auto-manages.
CLI Commands (Future)
gt plugins list # Show all plugins, gates, status
gt plugins check # Show plugins with open gates
gt plugins show <name> # Detail view of one plugin
gt plugins run <name> # Force-run (ignore gate)
These commands are not yet implemented. The Deacon reads the directory structure directly during patrol.