spawn: use town-level beads for Witness notification
The SPAWN notification to Witness was going to rig-level beads, but gt mail inbox checks town-level first. This caused messages to get lost. Fixes part of gt-c6b. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -378,7 +378,7 @@
|
||||
{"id":"gt-wav5","title":"Merge: gt-a95","description":"branch: polecat/Ace\ntarget: main\nsource_issue: gt-a95\nrig: gastown","status":"closed","priority":1,"issue_type":"merge-request","created_at":"2025-12-19T14:53:30.210304-08:00","updated_at":"2025-12-19T18:26:14.103104-08:00","closed_at":"2025-12-19T18:26:14.103106-08:00"}
|
||||
{"id":"gt-wpg","title":"Replaceable notifications via Claude Code queue","description":"Leverage Claude Code's ability to replace queued text for notifications that supersede previous ones.\n\n## Problem\n\nIf daemon sends 10 heartbeats while agent is busy, agent returns to see 10 stacked messages. Wasteful and noisy.\n\n## Solution\n\nUse Claude Code's queue replacement for:\n- Heartbeat messages (only latest matters)\n- Status updates that supersede previous\n- Progress notifications\n\n## Implementation\n\nNotifications get a 'slot' identifier. New notification in same slot replaces old one:\n- Slot: 'heartbeat' → only one heartbeat queued at a time\n- Slot: 'status-\u003crig\u003e' → latest status per rig\n- No slot → stacks normally (for unique messages)\n\n## Research Needed\n\n- How does Claude Code expose queue replacement?\n- tmux send-keys behavior with pending input\n- Alternative: clear + resend pattern","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-18T14:19:29.821949-08:00","updated_at":"2025-12-18T14:19:29.821949-08:00","dependencies":[{"issue_id":"gt-wpg","depends_on_id":"gt-99m","type":"blocks","created_at":"2025-12-18T14:19:46.656972-08:00","created_by":"daemon"}]}
|
||||
{"id":"gt-wusk","title":"Layered context onboarding pattern","description":"Pattern from handoff discussion:\n\n## Pattern: Layered Context Onboarding\n\nTown CLAUDE.md (user/org) -\u003e Rig CLAUDE.md (project) -\u003e Role priming\n\n## Ultra-compressed HOP for workers (no reveal)\n\n- Permanent record: All work tracked. Outcomes matter.\n- Quality gates: Molecule steps exist for a reason.\n- Attribution: Completions build your track record.\n- Handoff clean: Leave state any worker can continue.\n\n## Recommendation\n\nCreate Town @AGENTS.md for shared worker context that all workers see.\nThis provides common behavioral guidance without revealing full HOP context.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-20T00:55:11.984103-08:00","updated_at":"2025-12-20T00:55:11.984103-08:00"}
|
||||
{"id":"gt-x2cx","title":"gt handoff: Deadlock bug in runHandoff","notes":"Running 'gt handoff' from a polecat causes a deadlock:\n\nStack trace shows:\n- goroutine 1 [select (no cases)] in runHandoff\n- File: internal/cmd/handoff.go:125\n\nThe command successfully sends the shutdown request but then hangs with 'fatal error: all goroutines are asleep - deadlock!'","status":"open","priority":1,"issue_type":"bug","created_at":"2025-12-20T08:01:33.827354-08:00","updated_at":"2025-12-20T08:01:41.159683-08:00"}
|
||||
{"id":"gt-x2cx","title":"gt handoff: Deadlock bug in runHandoff","notes":"Running 'gt handoff' from a polecat causes a deadlock:\n\nStack trace shows:\n- goroutine 1 [select (no cases)] in runHandoff\n- File: internal/cmd/handoff.go:125\n\nThe command successfully sends the shutdown request but then hangs with 'fatal error: all goroutines are asleep - deadlock!'","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-20T08:01:33.827354-08:00","updated_at":"2025-12-20T08:47:47.599975-08:00","closed_at":"2025-12-20T08:47:47.599975-08:00","close_reason":"Fixed: replaced empty select{} with signal handling to avoid Go runtime deadlock detection"}
|
||||
{"id":"gt-xicq","title":"Work on ga-lue: Implement Witness as Claude agent. Conver...","description":"Work on ga-lue: Implement Witness as Claude agent. Convert from shell script to Claude agent that monitors polecats, nudges idle ones, handles escalations. When done, submit MR (not PR) to integration branch for Refinery.","status":"closed","priority":2,"issue_type":"task","assignee":"gastown/nux","created_at":"2025-12-19T22:58:08.310674-08:00","updated_at":"2025-12-19T23:24:36.692209-08:00","closed_at":"2025-12-19T23:24:36.692209-08:00","close_reason":"Implemented Witness as Claude agent with enhanced template, startup protocol, lifecycle processing, nudge/escalation protocols"}
|
||||
{"id":"gt-xkbm","title":"Merge: gt-g44u.1","description":"branch: polecat/Ace\ntarget: main\nsource_issue: gt-g44u.1\nrig: gastown","status":"closed","issue_type":"merge-request","created_at":"2025-12-19T16:04:14.367493-08:00","updated_at":"2025-12-19T17:35:38.210747-08:00","closed_at":"2025-12-19T17:35:38.210747-08:00"}
|
||||
{"id":"gt-xpq","title":"Add gt crew rename command","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-18T19:45:32.599846-08:00","updated_at":"2025-12-18T19:46:17.780981-08:00","closed_at":"2025-12-18T19:46:17.780981-08:00"}
|
||||
|
||||
@@ -340,6 +340,8 @@ func runSpawn(cmd *cobra.Command, args []string) error {
|
||||
// Notify Witness about the spawn - Witness will monitor startup and nudge when ready
|
||||
// Note: If Witness is down, Deacon's health check will wake it and Witness will
|
||||
// process the SPAWN message from its inbox on startup.
|
||||
// Use town-level beads for cross-agent mail (gt-c6b: mail coordination uses town-level)
|
||||
townRouter := mail.NewRouter(townRoot)
|
||||
witnessAddr := fmt.Sprintf("%s/witness", rigName)
|
||||
sender := detectSender()
|
||||
spawnNotification := &mail.Message{
|
||||
@@ -361,7 +363,7 @@ in the tmux session), send a nudge to start working:
|
||||
The polecat has a work assignment in its inbox.`, polecatName, assignmentID, sessMgr.SessionName(polecatName), sender, sessMgr.SessionName(polecatName)),
|
||||
}
|
||||
|
||||
if err := router.Send(spawnNotification); err != nil {
|
||||
if err := townRouter.Send(spawnNotification); err != nil {
|
||||
fmt.Printf(" %s\n", style.Dim.Render(fmt.Sprintf("Warning: could not notify witness: %v", err)))
|
||||
} else {
|
||||
fmt.Printf(" %s\n", style.Dim.Render("Witness notified to monitor startup"))
|
||||
|
||||
Reference in New Issue
Block a user