fix(molecules): cascade-close child wisps on molecule completion (gt-zbnr)
Some checks failed
CI / Check for .beads changes (push) Has been skipped
CI / Check embedded formulas (push) Failing after 18s
CI / Coverage Report (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Integration Tests (push) Has been cancelled
Windows CI / Windows Build and Unit Tests (push) Has been cancelled
CI / Test (push) Has been cancelled
Some checks failed
CI / Check for .beads changes (push) Has been skipped
CI / Check embedded formulas (push) Failing after 18s
CI / Coverage Report (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Integration Tests (push) Has been cancelled
Windows CI / Windows Build and Unit Tests (push) Has been cancelled
CI / Test (push) Has been cancelled
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:
@@ -608,11 +608,21 @@ func updateAgentStateOnDone(cwd, townRoot, exitType, _ string) { // issueID unus
|
||||
// has attached_molecule pointing to the wisp. Without this fix, gt done
|
||||
// only closed the hooked bead, leaving the wisp orphaned.
|
||||
// Order matters: wisp closes -> unblocks base bead -> base bead closes.
|
||||
//
|
||||
// BUG FIX (gt-zbnr): Close child wisps BEFORE closing the molecule itself.
|
||||
// Deacon patrol molecules have child step wisps that were being orphaned
|
||||
// when the patrol completed. Now we cascade-close all descendants first.
|
||||
attachment := beads.ParseAttachmentFields(hookedBead)
|
||||
if attachment != nil && attachment.AttachedMolecule != "" {
|
||||
if err := bd.Close(attachment.AttachedMolecule); err != nil {
|
||||
moleculeID := attachment.AttachedMolecule
|
||||
// Cascade-close all child wisps before closing the molecule
|
||||
childrenClosed := closeDescendants(bd, moleculeID)
|
||||
if childrenClosed > 0 {
|
||||
fmt.Printf(" Closed %d child step issues\n", childrenClosed)
|
||||
}
|
||||
if err := bd.Close(moleculeID); err != nil {
|
||||
// Non-fatal: warn but continue
|
||||
fmt.Fprintf(os.Stderr, "Warning: couldn't close attached molecule %s: %v\n", attachment.AttachedMolecule, err)
|
||||
fmt.Fprintf(os.Stderr, "Warning: couldn't close attached molecule %s: %v\n", moleculeID, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -645,7 +655,7 @@ func updateAgentStateOnDone(cwd, townRoot, exitType, _ string) { // issueID unus
|
||||
if _, err := bd.Run("agent", "state", agentBeadID, "awaiting-gate"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Warning: couldn't set agent %s to awaiting-gate: %v\n", agentBeadID, err)
|
||||
}
|
||||
// ExitCompleted and ExitDeferred don't set state - observable from tmux
|
||||
// ExitCompleted and ExitDeferred don't set state - observable from tmux
|
||||
}
|
||||
|
||||
// ZFC #10: Self-report cleanup status
|
||||
|
||||
Reference in New Issue
Block a user