fix(molecules): cascade-close child wisps on molecule completion (gt-zbnr)
When deacon patrol molecules completed, their child step wisps were not being closed automatically. This caused orphan wisp accumulation - 143+ orphaned wisps were found in one cleanup session. The fix ensures that when a molecule completes (via gt done or gt mol step done), all descendant step issues are recursively closed before the molecule itself. Changes: - done.go: Added closeDescendants() call in updateAgentStateOnDone before closing the attached molecule - molecule_step.go: Added closeDescendants() call in handleMoleculeComplete for all roles (not just polecats) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -53,13 +53,13 @@ func init() {
|
||||
|
||||
// StepDoneResult is the result of a step done operation.
|
||||
type StepDoneResult struct {
|
||||
StepID string `json:"step_id"`
|
||||
MoleculeID string `json:"molecule_id"`
|
||||
StepClosed bool `json:"step_closed"`
|
||||
NextStepID string `json:"next_step_id,omitempty"`
|
||||
StepID string `json:"step_id"`
|
||||
MoleculeID string `json:"molecule_id"`
|
||||
StepClosed bool `json:"step_closed"`
|
||||
NextStepID string `json:"next_step_id,omitempty"`
|
||||
NextStepTitle string `json:"next_step_title,omitempty"`
|
||||
Complete bool `json:"complete"`
|
||||
Action string `json:"action"` // "continue", "done", "no_more_ready"
|
||||
Complete bool `json:"complete"`
|
||||
Action string `json:"action"` // "continue", "done", "no_more_ready"
|
||||
}
|
||||
|
||||
func runMoleculeStepDone(cmd *cobra.Command, args []string) error {
|
||||
@@ -162,9 +162,10 @@ func runMoleculeStepDone(cmd *cobra.Command, args []string) error {
|
||||
// extractMoleculeIDFromStep extracts the molecule ID from a step ID.
|
||||
// Step IDs have format: mol-id.N where N is the step number.
|
||||
// Examples:
|
||||
// gt-abc.1 -> gt-abc
|
||||
// gt-xyz.3 -> gt-xyz
|
||||
// bd-mol-abc.2 -> bd-mol-abc
|
||||
//
|
||||
// gt-abc.1 -> gt-abc
|
||||
// gt-xyz.3 -> gt-xyz
|
||||
// bd-mol-abc.2 -> bd-mol-abc
|
||||
func extractMoleculeIDFromStep(stepID string) string {
|
||||
// Find the last dot
|
||||
lastDot := strings.LastIndex(stepID, ".")
|
||||
@@ -388,14 +389,26 @@ func handleMoleculeComplete(cwd, townRoot, moleculeID string, dryRun bool) error
|
||||
}
|
||||
|
||||
if dryRun {
|
||||
fmt.Printf("[dry-run] Would close child steps of %s\n", moleculeID)
|
||||
fmt.Printf("[dry-run] Would unpin work for %s\n", agentID)
|
||||
fmt.Printf("[dry-run] Would send POLECAT_DONE to witness\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unpin the molecule bead (set status to open, will be closed by gt done or manually)
|
||||
// BUG FIX (gt-zbnr): Close child steps before unpinning/completing.
|
||||
// Deacon patrol molecules have child step wisps that were being orphaned
|
||||
// when the patrol completed. Now we cascade-close all descendants first.
|
||||
workDir, err := findLocalBeadsDir()
|
||||
if err == nil {
|
||||
b := beads.New(workDir)
|
||||
childrenClosed := closeDescendants(b, moleculeID)
|
||||
if childrenClosed > 0 {
|
||||
fmt.Printf("%s Closed %d child step issues\n", style.Bold.Render("✓"), childrenClosed)
|
||||
}
|
||||
}
|
||||
|
||||
// Unpin the molecule bead (set status to open, will be closed by gt done or manually)
|
||||
if workDir, err := findLocalBeadsDir(); err == nil {
|
||||
b := beads.New(workDir)
|
||||
pinnedBeads, err := b.List(beads.ListOptions{
|
||||
Status: beads.StatusPinned,
|
||||
|
||||
Reference in New Issue
Block a user