Summary
bd mol wisp gc --age 1h --force deletes the still-blocked sibling steps of a molecule that is currently hooked and in progress. When the agent then closes its current step, the molecule auto-closes as "completed" even though the vast majority of its steps were never executed.
Environment
- gastown 1.1.0 (Homebrew), macOS (darwin 25.5)
- Observed on a Deacon running
mol-deacon-patrol (26 steps)
Reproduction (as observed 2026-07-03)
gt sling mol-deacon-patrol deacon — molecule hq-wisp-8g7 poured with 26 steps (1 ready, 25 blocked).
- Execute step 1 (heartbeat), close it. Hook shows 1/26 done, 24 blocked.
- Step 2 ("Handle callbacks from agents") itself prescribes running:
bd mol wisp gc --closed --force
bd mol wisp gc --age 1h --force
- The
--age 1h pass deleted 73 wisps — including the molecule's own 24 blocked pending steps.
- Closing step 2 then produced:
✓ Auto-closed completed molecule hq-wisp-8g7 — mol-deacon-patrol at 2/26 steps executed.
Net effect: every patrol cycle silently truncates after the gc step, skipping async-gate evaluation, convoy checks, test-pollution cleanup, orphan-process cleanup, etc. The truncation is invisible unless you compare the step count before and after.
Why the blocked steps looked "abandoned"
Blocked steps of an in-progress molecule are open, unassigned, and have no activity, so an age-based abandonment heuristic sweeps them. (It's possible timestamp handling contributes — the steps were minutes old at gc time but were still swept.)
Expected
bd mol wisp gc should never delete steps belonging to a molecule that is hooked or has any step in progress. Blocked-but-reachable steps of a live molecule are not abandoned.
Workarounds we applied
- Raised the formula's gc age from 1h to 24h in
mol-deacon-patrol.formula.toml (mitigation only; a long-running molecule would still be vulnerable).
- Note
--exclude-type is not a viable guard: wisp steps are untyped.
Prior art
#2768 was the same failure class (gc deleting live agent-identity beads); this is the molecule-step variant.
Tracked locally as bead hq-0az.
Summary
bd mol wisp gc --age 1h --forcedeletes the still-blocked sibling steps of a molecule that is currently hooked and in progress. When the agent then closes its current step, the molecule auto-closes as "completed" even though the vast majority of its steps were never executed.Environment
mol-deacon-patrol(26 steps)Reproduction (as observed 2026-07-03)
gt sling mol-deacon-patrol deacon— molecule hq-wisp-8g7 poured with 26 steps (1 ready, 25 blocked).--age 1hpass deleted 73 wisps — including the molecule's own 24 blocked pending steps.✓ Auto-closed completed molecule hq-wisp-8g7 — mol-deacon-patrolat 2/26 steps executed.Net effect: every patrol cycle silently truncates after the gc step, skipping async-gate evaluation, convoy checks, test-pollution cleanup, orphan-process cleanup, etc. The truncation is invisible unless you compare the step count before and after.
Why the blocked steps looked "abandoned"
Blocked steps of an in-progress molecule are open, unassigned, and have no activity, so an age-based abandonment heuristic sweeps them. (It's possible timestamp handling contributes — the steps were minutes old at gc time but were still swept.)
Expected
bd mol wisp gcshould never delete steps belonging to a molecule that is hooked or has any step in progress. Blocked-but-reachable steps of a live molecule are not abandoned.Workarounds we applied
mol-deacon-patrol.formula.toml(mitigation only; a long-running molecule would still be vulnerable).--exclude-typeis not a viable guard: wisp steps are untyped.Prior art
#2768 was the same failure class (gc deleting live agent-identity beads); this is the molecule-step variant.
Tracked locally as bead hq-0az.