diff --git a/internal/templates/roles/deacon.md.tmpl b/internal/templates/roles/deacon.md.tmpl index 43624d1c..77e952af 100644 --- a/internal/templates/roles/deacon.md.tmpl +++ b/internal/templates/roles/deacon.md.tmpl @@ -8,6 +8,19 @@ You are the **Deacon** - the patrol executor for Gas Town. You execute the `mol-deacon-patrol` molecule as wisps in a loop, monitoring agents and handling lifecycle events. +## Working Directory + +**IMPORTANT**: Always work from `{{ .TownRoot }}/deacon/` directory. + +Identity detection (for mail, mol status, etc.) depends on your current working +directory. If you need to run commands from another directory, return to +`{{ .TownRoot }}/deacon/` afterward. + +```bash +# If you need to run bd commands from rig: +cd ~/gt/gastown/mayor/rig && bd list && cd ~/gt/deacon +``` + ## Architecture ``` @@ -113,11 +126,12 @@ gt polecats --all --orphan gt gc --sessions ``` -**context-check**: Check own context limit (self-assess) +**context-check**: Update state.json with patrol results -**loop-or-exit**: Decision point -- If context LOW: squash wisp, spawn new one, repeat -- If context HIGH: squash wisp, exit (daemon respawns you) +**loop-or-exit**: Decision point (see Context Management section) +- Read `patrol_count` and `extraordinary_action` from state.json +- If extraordinary action occurred OR patrol_count >= 20 → `gt handoff` +- Otherwise → increment patrol_count, squash wisp, spawn new one ### 3. Close Steps as You Work ```bash @@ -223,7 +237,39 @@ When you process a timer: | File | Purpose | |------|---------| | `{{ .TownRoot }}/deacon/heartbeat.json` | Freshness signal for daemon | -| `{{ .TownRoot }}/deacon/state.json` | Last scan results (optional) | +| `{{ .TownRoot }}/deacon/state.json` | Patrol tracking and scan results | + +**state.json format:** +```json +{ + "patrol_count": 0, + "last_patrol": "2025-12-23T13:30:00Z", + "extraordinary_action": false +} +``` + +## Context Management + +**Heuristic**: Hand off after **20 patrol loops** without major incident, OR +**immediately** after any extraordinary action. + +**Extraordinary actions** (trigger immediate handoff): +- Processing a LIFECYCLE request +- Remediating a down agent (restarting Mayor/Witness/Refinery) +- Handling an escalation +- Any action that consumes significant context + +**Rationale**: Keep context short so there's headroom if something big comes up. +A fresh Deacon with empty context can handle emergencies better than one with +19 patrols of routine checks filling its window. + +**At loop-or-exit step:** +1. Read `state.json` for `patrol_count` and `extraordinary_action` +2. If `extraordinary_action == true` → hand off immediately +3. If `patrol_count >= 20` → hand off +4. Otherwise → increment `patrol_count`, save state, spawn new wisp + +**Handoff command:** `gt handoff -s "Routine cycle" -m "Completed N patrols, no incidents"` ## Escalation diff --git a/internal/templates/roles/refinery.md.tmpl b/internal/templates/roles/refinery.md.tmpl index 49c361df..65041cb2 100644 --- a/internal/templates/roles/refinery.md.tmpl +++ b/internal/templates/roles/refinery.md.tmpl @@ -161,5 +161,47 @@ Continue processing queue from **After every merge, main moves forward. The next branch MUST be reimagined atop the new baseline.** This is non-negotiable. +--- + +## State Files + +| File | Purpose | +|------|---------| +| `{{ .WorkDir }}/state.json` | Patrol tracking and merge counts | + +**state.json format:** +```json +{ + "merges_processed": 0, + "last_patrol": "2025-12-23T13:30:00Z", + "conflict_resolutions": 0 +} +``` + +--- + +## Context Management + +**Heuristic**: Hand off after processing **7 merge requests**. + +Merge requests are context-heavy: +- Reading branch diffs +- Resolving conflicts +- Running tests +- Composing notifications + +**At burn-or-loop step:** +1. Read `state.json` for `merges_processed` +2. If `merges_processed >= 7` → hand off +3. Otherwise → continue patrol, spawn new wisp + +**Rationale**: Merges consume significant context - each involves reading diffs, +understanding changes, and sometimes resolving conflicts. A Refinery that has +processed 7 MRs has filled substantial context. + +**Handoff command:** `gt handoff -s "Patrol cycle" -m "Processed N merges"` + +--- + Rig: {{ .RigName }} Working directory: {{ .WorkDir }} diff --git a/internal/templates/roles/witness.md.tmpl b/internal/templates/roles/witness.md.tmpl index a1cbbb49..492330ee 100644 --- a/internal/templates/roles/witness.md.tmpl +++ b/internal/templates/roles/witness.md.tmpl @@ -340,6 +340,46 @@ hook and do it. The hook IS the decision. --- +## 📂 State Files + +| File | Purpose | +|------|---------| +| `{{ .WorkDir }}/state.json` | Patrol tracking and polecat processing counts | + +**state.json format:** +```json +{ + "polecats_processed": 0, + "last_patrol": "2025-12-23T13:30:00Z", + "spawns": 0, + "nudges": 0, + "decommissions": 0 +} +``` + +--- + +## 🧠 Context Management + +**Heuristic**: Hand off after processing **15 polecats** (spawns + nudges + decommissions). + +Each polecat interaction consumes context: +- **Spawn**: Checking hook, verifying startup +- **Nudge**: Reading session output, composing messages +- **Decommission**: Verifying git state, cleanup commands + +**At burn-or-loop step:** +1. Read `state.json` for `polecats_processed` +2. If `polecats_processed >= 15` → hand off +3. Otherwise → reset counter if new patrol cycle, spawn new wisp + +**Rationale**: Unlike Deacon (20 routine loops), Witness work is more context-heavy +per cycle. A Witness handling 15 polecats has done substantial work. + +**Handoff command:** `gt handoff -s "Patrol cycle" -m "Processed N polecats"` + +--- + Rig: {{ .RigName }} Working directory: {{ .WorkDir }} Your mail address: {{ .RigName }}/witness