Eradicate hook files, use pinned beads only (gt-rgd9x)

- Remove hook functions from internal/wisp/io.go (WriteSlungWork, ReadHook, BurnHook, etc.)
- Remove hook types from internal/wisp/types.go (SlungWork, Wisp, etc.)
- Update up.go to query pinned beads instead of reading hook files
- Remove SlungWork field from molecule_status.go
- Remove hook-*.json pattern from .beads/.gitignore
- Delete live hook file /Users/stevey/gt/deacon/.beads/hook-deacon.json

Work is now tracked exclusively via pinned beads (status=pinned, assignee=agent).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-26 16:46:39 -08:00
parent 3c0208fc02
commit 1a1ab4842b
5 changed files with 21 additions and 275 deletions

View File

@@ -10,7 +10,6 @@ import (
"github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/beads"
"github.com/steveyegge/gastown/internal/style"
"github.com/steveyegge/gastown/internal/wisp"
"github.com/steveyegge/gastown/internal/workspace"
)
@@ -39,8 +38,6 @@ type MoleculeStatusInfo struct {
IsWisp bool `json:"is_wisp"`
Progress *MoleculeProgressInfo `json:"progress,omitempty"`
NextAction string `json:"next_action,omitempty"`
// SlungWork is set when there's a wisp hook file (from gt hook/sling/handoff)
SlungWork *wisp.SlungWork `json:"slung_work,omitempty"`
}
// MoleculeCurrentInfo contains info about what an agent should be working on.
@@ -258,9 +255,6 @@ func runMoleculeStatus(cmd *cobra.Command, args []string) error {
HasWork: len(pinnedBeads) > 0,
}
// Note: Hook files are deprecated. Work is now tracked via pinned beads only.
// The SlungWork field is kept for backward compatibility but will be nil.
if len(pinnedBeads) > 0 {
// Take the first pinned bead (agents typically have one pinned bead)
status.PinnedBead = pinnedBeads[0]
@@ -445,35 +439,7 @@ func outputMoleculeStatus(status MoleculeStatusInfo) error {
return nil
}
// Show slung work (wisp hook file) if present
if status.SlungWork != nil {
fmt.Printf("%s %s\n", style.Bold.Render("🎯 SLUNG WORK:"), status.SlungWork.BeadID)
if status.SlungWork.Subject != "" {
fmt.Printf(" Subject: %s\n", status.SlungWork.Subject)
}
if status.SlungWork.Context != "" {
fmt.Printf(" Context: %s\n", status.SlungWork.Context)
}
if status.SlungWork.Args != "" {
fmt.Printf(" Args: %s\n", style.Bold.Render(status.SlungWork.Args))
}
fmt.Printf(" Slung by: %s at %s\n",
status.SlungWork.CreatedBy,
status.SlungWork.CreatedAt.Format("2006-01-02 15:04:05"))
// Show bead details
fmt.Println()
fmt.Println(style.Bold.Render("Bead details:"))
cmd := exec.Command("bd", "show", status.SlungWork.BeadID)
cmd.Stdout = os.Stdout
cmd.Run()
fmt.Println()
fmt.Println(style.Bold.Render("→ PROPULSION: Work is on your hook. RUN IT."))
return nil
}
// Show pinned bead info (legacy beads pinned field)
// Show pinned bead info
if status.PinnedBead == nil {
fmt.Printf("%s\n", style.Dim.Render("Work indicated but no bead found"))
return nil

View File

@@ -1,7 +1,6 @@
package cmd
import (
"encoding/json"
"fmt"
"os"
"os/exec"
@@ -10,12 +9,12 @@ import (
"time"
"github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/beads"
"github.com/steveyegge/gastown/internal/config"
"github.com/steveyegge/gastown/internal/daemon"
"github.com/steveyegge/gastown/internal/refinery"
"github.com/steveyegge/gastown/internal/style"
"github.com/steveyegge/gastown/internal/tmux"
"github.com/steveyegge/gastown/internal/wisp"
"github.com/steveyegge/gastown/internal/workspace"
)
@@ -39,7 +38,7 @@ spawned on demand by the Mayor or Witnesses.
Use --restore to also start:
• Crew - Per rig settings (settings/config.json crew.startup)
• Polecats - Those with hooks (work attached)
• Polecats - Those with pinned beads (work attached)
Running 'gt up' multiple times is safe - it only starts services that
aren't already running.`,
@@ -144,9 +143,9 @@ func runUp(cmd *cobra.Command, args []string) error {
}
}
// 7. Polecats with hooks (if --restore)
// 7. Polecats with pinned work (if --restore)
for _, rigName := range rigs {
polecatsStarted, polecatErrors := startPolecatsWithHooks(t, townRoot, rigName)
polecatsStarted, polecatErrors := startPolecatsWithWork(t, townRoot, rigName)
for _, name := range polecatsStarted {
printStatus(fmt.Sprintf("Polecat (%s/%s)", rigName, name), true, fmt.Sprintf("gt-%s-polecat-%s", rigName, name))
}
@@ -512,9 +511,9 @@ func ensureCrewSession(t *tmux.Tmux, sessionName, crewPath, rigName, crewName st
return nil
}
// startPolecatsWithHooks starts polecats that have hook files (work attached).
// startPolecatsWithWork starts polecats that have pinned beads (work attached).
// Returns list of started polecat names and map of errors.
func startPolecatsWithHooks(t *tmux.Tmux, townRoot, rigName string) ([]string, map[string]error) {
func startPolecatsWithWork(t *tmux.Tmux, townRoot, rigName string) ([]string, map[string]error) {
started := []string{}
errors := map[string]error{}
@@ -536,24 +535,16 @@ func startPolecatsWithHooks(t *tmux.Tmux, townRoot, rigName string) ([]string, m
polecatName := entry.Name()
polecatPath := filepath.Join(polecatsDir, polecatName)
// Check if this polecat has a hook file
// Check if this polecat has a pinned bead (work attached)
agentID := fmt.Sprintf("%s/polecats/%s", rigName, polecatName)
hookPath := filepath.Join(polecatPath, ".beads", wisp.HookFilename(agentID))
hookData, err := os.ReadFile(hookPath)
if err != nil {
// No hook file - skip
continue
}
// Verify hook has work
var hook wisp.SlungWork
if err := json.Unmarshal(hookData, &hook); err != nil {
continue
}
if hook.BeadID == "" {
// Empty hook - skip
b := beads.New(polecatPath)
pinnedBeads, err := b.List(beads.ListOptions{
Status: beads.StatusPinned,
Assignee: agentID,
Priority: -1,
})
if err != nil || len(pinnedBeads) == 0 {
// No pinned beads - skip
continue
}