diff --git a/docs/architecture.md b/docs/architecture.md index 69466ca1..9bda594a 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -186,13 +186,17 @@ Created by `gt rig add `: ``` gastown/ # Rig = container (NOT a git clone) ├── config.json # Rig configuration (git_url, beads prefix) -├── .beads/ → refinery/rig/.beads # Symlink to canonical beads in refinery +├── .beads/ → mayor/rig/.beads # Symlink to canonical beads in Mayor │ -├── refinery/ # Refinery agent -│ ├── rig/ # Authoritative "main" clone +├── mayor/ # Mayor's per-rig presence +│ ├── rig/ # CANONICAL clone (beads authority) │ │ └── .beads/ # Canonical rig beads (prefix: gt-, etc.) │ └── state.json │ +├── refinery/ # Refinery agent (merge queue processor) +│ ├── rig/ # Refinery's clone (for merge operations) +│ └── state.json +│ ├── witness/ # Witness agent (per-rig pit boss) │ └── state.json # No clone needed (monitors polecats) │ @@ -200,15 +204,15 @@ gastown/ # Rig = container (NOT a git clone) │ └── / # Workspace (full git clone) │ └── polecats/ # Worker directories (git worktrees) - ├── Nux/ # Worktree from refinery (faster than clone) - └── Toast/ # Worktree from refinery + ├── Nux/ # Worktree from Mayor's clone + └── Toast/ # Worktree from Mayor's clone ``` **Beads architecture:** -- Refinery's clone holds the canonical `.beads/` for the rig -- Rig root symlinks `.beads/` → `refinery/rig/.beads` -- All agents (crew, polecats) inherit beads via parent directory lookup -- Polecats are git worktrees, not full clones (much faster) +- Mayor's clone holds the canonical `.beads/` for the rig +- Rig root symlinks `.beads/` → `mayor/rig/.beads` +- All agents (crew, polecats, refinery) inherit beads via parent lookup +- Polecats are git worktrees from Mayor's clone (much faster than full clones) **Key points:** - The rig root has no `.git/` - it's not a repository @@ -271,15 +275,21 @@ For reference without mermaid rendering: │ ├── gastown/ # RIG (container, NOT a git clone) │ ├── config.json # Rig configuration -│ ├── .beads/ → refinery/rig/.beads # Symlink to canonical beads +│ ├── .beads/ → mayor/rig/.beads # Symlink to Mayor's canonical beads │ │ -│ ├── refinery/ # Refinery agent -│ │ ├── rig/ # Canonical "main" clone +│ ├── mayor/ # Mayor's per-rig presence +│ │ ├── rig/ # CANONICAL clone (beads + worktree base) │ │ │ ├── .git/ │ │ │ ├── .beads/ # CANONICAL rig beads (gt-* prefix) │ │ │ └── │ │ └── state.json │ │ +│ ├── refinery/ # Refinery agent (merge queue) +│ │ ├── rig/ # Refinery's clone (for merges) +│ │ │ ├── .git/ +│ │ │ └── +│ │ └── state.json +│ │ │ ├── witness/ # Witness agent (pit boss) │ │ └── state.json # No clone needed │ │ @@ -289,9 +299,9 @@ For reference without mermaid rendering: │ │ └── │ │ │ ├── polecats/ # Worker directories (worktrees) -│ │ ├── Nux/ # Git worktree from refinery +│ │ ├── Nux/ # Git worktree from Mayor's clone │ │ │ └── # (inherits beads from rig) -│ │ └── Toast/ # Git worktree from refinery +│ │ └── Toast/ # Git worktree from Mayor's clone │ │ │ └── plugins/ # Optional plugins │ └── merge-oracle/ @@ -300,18 +310,19 @@ For reference without mermaid rendering: │ └── wyvern/ # Another rig (same structure) ├── config.json - ├── .beads/ → refinery/rig/.beads - ├── polecats/ + ├── .beads/ → mayor/rig/.beads + ├── mayor/ ├── refinery/ ├── witness/ - └── crew/ + ├── crew/ + └── polecats/ ``` **Key changes from earlier design:** - Town beads (`gm-*`) hold Mayor mail instead of JSONL files -- Rig `.beads/` symlinks to refinery's canonical beads -- Polecats use git worktrees (not full clones) for speed -- No `mayor/rig/` in each rig (Mayor works from town level) +- Mayor has per-rig clone that's canonical for beads and worktrees +- Rig `.beads/` symlinks to Mayor's canonical beads +- Polecats are git worktrees from Mayor's clone (fast) ### Why Decentralized? diff --git a/internal/polecat/manager.go b/internal/polecat/manager.go index 3d892a47..dfc41c47 100644 --- a/internal/polecat/manager.go +++ b/internal/polecat/manager.go @@ -65,18 +65,18 @@ func (m *Manager) Add(name string) (*Polecat, error) { return nil, fmt.Errorf("creating polecats dir: %w", err) } - // Use refinery clone as the base for worktrees - refineryPath := filepath.Join(m.rig.Path, "refinery", "rig") - refineryGit := git.NewGit(refineryPath) + // Use Mayor's clone as the base for worktrees (Mayor is canonical for the rig) + mayorPath := filepath.Join(m.rig.Path, "mayor", "rig") + mayorGit := git.NewGit(mayorPath) - // Verify refinery clone exists - if _, err := os.Stat(refineryPath); os.IsNotExist(err) { - return nil, fmt.Errorf("refinery clone not found at %s (run 'gt rig add' to set up rig structure)", refineryPath) + // Verify Mayor's clone exists + if _, err := os.Stat(mayorPath); os.IsNotExist(err) { + return nil, fmt.Errorf("mayor clone not found at %s (run 'gt rig add' to set up rig structure)", mayorPath) } // Create worktree with new branch // git worktree add -b polecat/ - if err := refineryGit.WorktreeAdd(polecatPath, branchName); err != nil { + if err := mayorGit.WorktreeAdd(polecatPath, branchName); err != nil { return nil, fmt.Errorf("creating worktree: %w", err) } @@ -95,7 +95,7 @@ func (m *Manager) Add(name string) (*Polecat, error) { // Save state if err := m.saveState(polecat); err != nil { // Clean up worktree on failure - refineryGit.WorktreeRemove(polecatPath, true) + mayorGit.WorktreeRemove(polecatPath, true) return nil, fmt.Errorf("saving state: %w", err) } @@ -120,12 +120,12 @@ func (m *Manager) Remove(name string, force bool) error { } } - // Use refinery to remove the worktree properly - refineryPath := filepath.Join(m.rig.Path, "refinery", "rig") - refineryGit := git.NewGit(refineryPath) + // Use Mayor's clone to remove the worktree properly + mayorPath := filepath.Join(m.rig.Path, "mayor", "rig") + mayorGit := git.NewGit(mayorPath) // Try to remove as a worktree first (use force flag for worktree removal too) - if err := refineryGit.WorktreeRemove(polecatPath, force); err != nil { + if err := mayorGit.WorktreeRemove(polecatPath, force); err != nil { // Fall back to direct removal if worktree removal fails // (e.g., if this is an old-style clone, not a worktree) if removeErr := os.RemoveAll(polecatPath); removeErr != nil { @@ -134,7 +134,7 @@ func (m *Manager) Remove(name string, force bool) error { } // Prune any stale worktree entries - refineryGit.WorktreePrune() + mayorGit.WorktreePrune() return nil }