refactor(swarm): remove idle polecat reuse logic (self-cleaning model)
The swarm dispatch command now always spawns fresh polecats instead of searching for idle ones to reuse. With the self-cleaning model, polecats self-nuke when done - there are no idle polecats to reuse. Closes: gt-h4yc3 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -131,11 +131,12 @@ Transitions the swarm from 'created' to 'active' state.`,
|
||||
|
||||
var swarmDispatchCmd = &cobra.Command{
|
||||
Use: "dispatch <epic-id>",
|
||||
Short: "Assign next ready task to an idle worker",
|
||||
Long: `Dispatch the next ready task from an epic to an available worker.
|
||||
Short: "Assign next ready task to a fresh polecat",
|
||||
Long: `Dispatch the next ready task from an epic to a new polecat.
|
||||
|
||||
Finds the first unassigned task in the epic's ready front and slings it
|
||||
to an idle polecat in the rig.
|
||||
Finds the first unassigned task in the epic's ready front and spawns a
|
||||
fresh polecat to work on it. Self-cleaning model: polecats are always
|
||||
fresh - there are no idle polecats to reuse.
|
||||
|
||||
Examples:
|
||||
gt swarm dispatch gt-abc # Dispatch next task from epic gt-abc
|
||||
@@ -458,49 +459,15 @@ func runSwarmDispatch(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Find idle polecats (no hooked work)
|
||||
polecatGit := git.NewGit(foundRig.Path)
|
||||
polecatMgr := polecat.NewManager(foundRig, polecatGit)
|
||||
polecats, err := polecatMgr.List()
|
||||
if err != nil {
|
||||
return fmt.Errorf("listing polecats: %w", err)
|
||||
}
|
||||
|
||||
// Check which polecats have no hooked work
|
||||
var idlePolecats []string
|
||||
for _, p := range polecats {
|
||||
// Check if polecat has hooked work by querying beads
|
||||
hookCheckCmd := exec.Command("bd", "list", "--status=hooked", "--assignee", fmt.Sprintf("%s/polecats/%s", foundRig.Name, p.Name), "--json")
|
||||
hookCheckCmd.Dir = foundRig.BeadsPath()
|
||||
var hookOut bytes.Buffer
|
||||
hookCheckCmd.Stdout = &hookOut
|
||||
if err := hookCheckCmd.Run(); err == nil {
|
||||
var hooked []interface{}
|
||||
if err := json.Unmarshal(hookOut.Bytes(), &hooked); err == nil && len(hooked) == 0 {
|
||||
idlePolecats = append(idlePolecats, p.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(idlePolecats) == 0 {
|
||||
fmt.Println("No idle polecats available")
|
||||
fmt.Printf("\nUnassigned ready tasks:\n")
|
||||
for _, task := range unassigned {
|
||||
fmt.Printf(" ○ %s: %s\n", task.ID, task.Title)
|
||||
}
|
||||
fmt.Printf("\nCreate a new polecat or wait for one to become idle.\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Dispatch first unassigned task to first idle polecat
|
||||
// Self-cleaning model: Always spawn fresh polecats for work.
|
||||
// There are no "idle" polecats - polecats self-nuke when done.
|
||||
// Just sling to the rig and let gt sling spawn a fresh polecat.
|
||||
task := unassigned[0]
|
||||
worker := idlePolecats[0]
|
||||
target := fmt.Sprintf("%s/%s", foundRig.Name, worker)
|
||||
|
||||
fmt.Printf("Dispatching %s to %s...\n", task.ID, target)
|
||||
fmt.Printf("Dispatching %s to fresh polecat in %s...\n", task.ID, foundRig.Name)
|
||||
|
||||
// Use gt sling to assign the task
|
||||
slingCmd := exec.Command("gt", "sling", task.ID, target)
|
||||
// Use gt sling to spawn a fresh polecat and assign the task
|
||||
slingCmd := exec.Command("gt", "sling", task.ID, foundRig.Name)
|
||||
slingCmd.Dir = townRoot
|
||||
slingCmd.Stdout = os.Stdout
|
||||
slingCmd.Stderr = os.Stderr
|
||||
@@ -509,15 +476,12 @@ func runSwarmDispatch(cmd *cobra.Command, args []string) error {
|
||||
return fmt.Errorf("slinging task: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("%s Dispatched %s: %s → %s\n", style.Bold.Render("✓"), task.ID, task.Title, target)
|
||||
fmt.Printf("%s Dispatched %s: %s → fresh polecat\n", style.Bold.Render("✓"), task.ID, task.Title)
|
||||
|
||||
// Show remaining tasks and workers
|
||||
// Show remaining tasks
|
||||
if len(unassigned) > 1 {
|
||||
fmt.Printf("\n%d more ready tasks available\n", len(unassigned)-1)
|
||||
}
|
||||
if len(idlePolecats) > 1 {
|
||||
fmt.Printf("%d more idle polecats available\n", len(idlePolecats)-1)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user