Deprecate hook files, use pinned beads for propulsion (gt-rgd9x)

Replace hook file mechanism with discovery-based pinned beads:
- gt hook: now runs bd update <bead> --status=pinned
- gt sling: same, plus nudge to target
- gt handoff: same when bead ID provided
- gt prime: checks pinned beads instead of hook files
- gt mol status: no longer checks hook files

Key changes:
- outputAttachmentStatus: extended to all roles (was Crew/Polecat only)
- checkSlungWork: now queries pinned beads instead of reading hook files
- wisp/io.go functions: marked deprecated with migration notes

This follows Gas Town discovery over explicit state principle.
Hook files are kept for backward compatibility but no longer written.

🤖 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 15:54:07 -08:00
parent 2dcb3d9971
commit 8131052207
7 changed files with 126 additions and 179 deletions
+14
View File
@@ -35,6 +35,10 @@ func HookPath(root, agent string) string {
}
// WriteSlungWork writes a slung work hook to the agent's hook file.
//
// Deprecated: Hook files are deprecated. Use bd update --status=pinned instead.
// Work is now tracked via pinned beads (discoverable via query) rather than
// explicit hook files. This function is kept for backward compatibility.
func WriteSlungWork(root, agent string, sw *SlungWork) error {
dir, err := EnsureDir(root)
if err != nil {
@@ -47,6 +51,9 @@ func WriteSlungWork(root, agent string, sw *SlungWork) error {
// ReadHook reads the slung work from an agent's hook file.
// Returns ErrNoHook if no hook file exists.
//
// Deprecated: Hook files are deprecated. Query pinned beads instead.
// Use beads.List with Status=pinned and Assignee=agent.
func ReadHook(root, agent string) (*SlungWork, error) {
path := HookPath(root, agent)
@@ -71,6 +78,9 @@ func ReadHook(root, agent string) (*SlungWork, error) {
}
// BurnHook removes an agent's hook file after it has been picked up.
//
// Deprecated: Hook files are deprecated. Work is tracked via pinned beads
// which don't need burning - just unpin with bd update --status=open.
func BurnHook(root, agent string) error {
path := HookPath(root, agent)
err := os.Remove(path)
@@ -81,6 +91,8 @@ func BurnHook(root, agent string) error {
}
// HasHook checks if an agent has a hook file.
//
// Deprecated: Hook files are deprecated. Query pinned beads instead.
func HasHook(root, agent string) bool {
path := HookPath(root, agent)
_, err := os.Stat(path)
@@ -88,6 +100,8 @@ func HasHook(root, agent string) bool {
}
// ListHooks returns a list of agents with active hooks.
//
// Deprecated: Hook files are deprecated. Query pinned beads instead.
func ListHooks(root string) ([]string, error) {
dir := filepath.Join(root, WispDir)
entries, err := os.ReadDir(dir)
+14 -4
View File
@@ -1,12 +1,22 @@
// Package wisp provides hook file support for Gas Town agents.
//
// Hooks are used to attach work to an agent for restart-and-resume:
// - hook-<agent>.json files track what bead is assigned to an agent
// DEPRECATED: Hook files are deprecated in favor of pinned beads.
// Work is now tracked via beads with status=pinned and assignee=agent,
// which can be discovered via query rather than explicit file management.
//
// Commands like `gt hook`, `gt sling`, `gt handoff` now use:
//
// bd update <bead> --status=pinned --assignee=<agent>
//
// On session start, agents query for pinned beads rather than reading hook files.
// This follows Gas Town's "discovery over explicit state" principle.
//
// The hook file functions are kept for backward compatibility but are deprecated.
// Old hook files:
// - hook-<agent>.json files tracked what bead was assigned to an agent
// - Created by `gt hook`, `gt sling`, `gt handoff`
// - Read on session start to restore work context
// - Burned after pickup
//
// Hook files live in .beads/ alongside other beads data.
package wisp
import (