From 4b8b4441337954272501319cbcf61b308b64778a Mon Sep 17 00:00:00 2001 From: chumbucket Date: Sun, 4 Jan 2026 14:22:20 -0800 Subject: [PATCH] docs: document polecat lifecycle (session/sandbox/slot layers) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clarifies the three distinct lifecycle layers to prevent confusion: - Session (Claude context): ephemeral, cycles per step - Sandbox (worktree): persistent until nuke - Slot (name from pool): persistent until nuke Addresses anti-patterns like "idle polecats" and misunderstanding what recycling means. (gt-bc6gm) πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- docs/polecat-lifecycle.md | 225 +++++++++++++++++++++++++++++++++ docs/understanding-gas-town.md | 2 +- templates/polecat-CLAUDE.md | 3 + 3 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 docs/polecat-lifecycle.md diff --git a/docs/polecat-lifecycle.md b/docs/polecat-lifecycle.md new file mode 100644 index 00000000..79483013 --- /dev/null +++ b/docs/polecat-lifecycle.md @@ -0,0 +1,225 @@ +# Polecat Lifecycle + +> Understanding the three-layer architecture of polecat workers + +## Overview + +Polecats have three distinct lifecycle layers that operate independently. Confusing +these layers leads to heresies like "idle polecats" and misunderstanding when +recycling occurs. + +## The Three Layers + +| Layer | Component | Lifecycle | Persistence | +|-------|-----------|-----------|-------------| +| **Session** | Claude (tmux pane) | Ephemeral | Cycles per step/handoff | +| **Sandbox** | Git worktree | Persistent | Until nuke | +| **Slot** | Name from pool | Persistent | Until nuke | + +### Session Layer + +The Claude session is **ephemeral**. It cycles frequently: + +- After each molecule step (via `gt handoff`) +- On context compaction +- On crash/timeout +- After extended work periods + +**Key insight:** Session cycling is **normal operation**, not failure. The polecat +continues workingβ€”only the Claude context refreshes. + +``` +Session 1: Steps 1-2 β†’ handoff +Session 2: Steps 3-4 β†’ handoff +Session 3: Step 5 β†’ gt done +``` + +All three sessions are the **same polecat**. The sandbox and slot persist throughout. + +### Sandbox Layer + +The sandbox is the **git worktree**β€”the polecat's working directory: + +``` +~/gt/gastown/polecats/Toast/ +``` + +This worktree: +- Exists from `gt sling` until `gt polecat nuke` +- Survives all session cycles +- Contains uncommitted work, staged changes, branch state +- Is independent of other polecat sandboxes + +The Witness never destroys sandboxes mid-work. Only `nuke` removes them. + +### Slot Layer + +The slot is the **name allocation** from the polecat pool: + +```bash +# Pool: [Toast, Shadow, Copper, Ash, Storm...] +# Toast is allocated to work gt-abc +``` + +The slot: +- Determines the sandbox path (`polecats/Toast/`) +- Maps to a tmux session (`gt-gastown-Toast`) +- Appears in attribution (`gastown/polecats/Toast`) +- Is released only on nuke + +## Correct Lifecycle + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ gt sling β”‚ +β”‚ β†’ Allocate slot from pool (Toast) β”‚ +β”‚ β†’ Create sandbox (worktree on new branch) β”‚ +β”‚ β†’ Start session (Claude in tmux) β”‚ +β”‚ β†’ Hook molecule to polecat β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Work Happens β”‚ +β”‚ β”‚ +β”‚ Session cycles happen here: β”‚ +β”‚ - gt handoff between steps β”‚ +β”‚ - Compaction triggers respawn β”‚ +β”‚ - Crash β†’ Witness respawns β”‚ +β”‚ β”‚ +β”‚ Sandbox persists through ALL session cycles β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ gt done β”‚ +β”‚ β†’ Polecat signals completion to Witness β”‚ +β”‚ β†’ Session exits (no idle waiting) β”‚ +β”‚ β†’ Witness receives POLECAT_DONE event β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Witness: gt polecat nuke β”‚ +β”‚ β†’ Verify work landed (merged or in MQ) β”‚ +β”‚ β†’ Delete sandbox (remove worktree) β”‚ +β”‚ β†’ Kill tmux session β”‚ +β”‚ β†’ Release slot back to pool β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## What "Recycle" Means + +**Session cycling**: Normal. Claude restarts, sandbox stays, slot stays. + +```bash +gt handoff # Session cycles, polecat continues +``` + +**Sandbox recreation**: Repair only. Should be rare. + +```bash +gt polecat repair Toast # Emergency: recreate corrupted worktree +``` + +Session cycling happens constantly. Sandbox recreation should almost never happen +during normal operation. + +## Anti-Patterns + +### Idle Polecats + +**Myth:** Polecats wait between tasks in an idle state. + +**Reality:** Polecats don't exist without work. The lifecycle is: +1. Work assigned β†’ polecat spawned +2. Work done β†’ polecat nuked +3. There is no idle state + +If you see a polecat without work, something is broken. Either: +- The hook was lost (bug) +- The session crashed before loading context +- Manual intervention corrupted state + +### Manual State Transitions + +**Anti-pattern:** +```bash +gt polecat done Toast # DON'T: external state manipulation +gt polecat reset Toast # DON'T: manual lifecycle control +``` + +**Correct:** +```bash +# Polecat signals its own completion: +gt done # (from inside the polecat session) + +# Only Witness nukes polecats: +gt polecat nuke Toast # (from Witness, after verification) +``` + +Polecats manage their own session lifecycle. The Witness manages sandbox lifecycle. +External manipulation bypasses verification. + +### Sandboxes Without Work + +**Anti-pattern:** A sandbox exists but no molecule is hooked. + +This means: +- The polecat was spawned incorrectly +- The hook was lost during crash +- State corruption occurred + +**Recovery:** +```bash +# From Witness: +gt polecat nuke Toast # Clean slate +gt sling gt-abc gastown # Respawn with work +``` + +### Confusing Session with Sandbox + +**Anti-pattern:** Thinking session restart = losing work. + +```bash +# Session ends (handoff, crash, compaction) +# Work is NOT lost because: +# - Git commits persist in sandbox +# - Staged changes persist in sandbox +# - Molecule state persists in beads +# - Hook persists across sessions +``` + +The new session picks up where the old one left off via `gt prime`. + +## Session Lifecycle Details + +Sessions cycle for these reasons: + +| Trigger | Action | Result | +|---------|--------|--------| +| `gt handoff` | Voluntary | Clean cycle to fresh context | +| Context compaction | Automatic | Forced by Claude Code | +| Crash/timeout | Failure | Witness respawns | +| `gt done` | Completion | Session exits, Witness takes over | + +All except `gt done` result in continued work. Only `gt done` signals completion. + +## Witness Responsibilities + +The Witness monitors polecats but does NOT: +- Force session cycles (polecats self-manage via handoff) +- Interrupt mid-step (unless truly stuck) +- Recycle sandboxes between steps + +The Witness DOES: +- Respawn crashed sessions +- Nudge stuck polecats +- Nuke completed polecats (after verification) +- Handle escalations + +## Related Documentation + +- [Understanding Gas Town](understanding-gas-town.md) - Role taxonomy and architecture +- [Polecat Wisp Architecture](polecat-wisp-architecture.md) - Molecule execution +- [Propulsion Principle](propulsion-principle.md) - Why work triggers immediate execution diff --git a/docs/understanding-gas-town.md b/docs/understanding-gas-town.md index f73b4540..e9fc0027 100644 --- a/docs/understanding-gas-town.md +++ b/docs/understanding-gas-town.md @@ -37,7 +37,7 @@ These roles do actual project work: | Role | Description | Lifecycle | |------|-------------|-----------| -| **Polecat** | Ephemeral worker with own worktree | Transient, Witness-managed | +| **Polecat** | Ephemeral worker with own worktree | Transient, Witness-managed ([details](polecat-lifecycle.md)) | | **Crew** | Persistent worker with own clone | Long-lived, user-managed | | **Dog** | Deacon helper for infrastructure tasks | Ephemeral, Deacon-managed | diff --git a/templates/polecat-CLAUDE.md b/templates/polecat-CLAUDE.md index a2c66b40..f6545904 100644 --- a/templates/polecat-CLAUDE.md +++ b/templates/polecat-CLAUDE.md @@ -182,6 +182,9 @@ to the merge queue. Without this step: ## Self-Managed Session Lifecycle +> See [Polecat Lifecycle](docs/polecat-lifecycle.md) for the full three-layer architecture +> (session/sandbox/slot). + **You own your session cadence.** The Witness monitors but doesn't force recycles. ### Closing Steps (for Activity Feed)