Problem
crates/stella-cli/src/subagent.rs:413-415 claims a panicked child 'lands here as a refusal … Nothing is settled on this side — the child already did it, on every path.' Two defects:
- The settle block (:384-404,
pool.record_spend + push_sub_agent_spend) runs AFTER runtime.block_on (:377). A panic inside the child turn unwinds past it — real dollars spent by the child land in neither ledger. Not 'on every path'.
panic = "abort" in the workspace Cargo.toml:194 means release builds have no unwind at all: the whole process dies, and the module's 'child panics resolve to a refusal instead of unwinding the parent's turn' rationale (:69-86) is only true in debug builds.
Fix direction
Wrap the child turn in catch_unwind (the thread boundary already isolates it in debug; make the settle run in a drop guard so partially-recorded usage settles on every exit path), and either (a) fix the module docs to say what release builds actually do, or (b) if child-panic containment is a real product requirement, it needs a process boundary, not a thread. The drop-guard settle is the fix for defect 1 regardless.
Verify
Witness (debug profile): a scripted child that panics after recording spend must still fold that spend into the parent's ledger; doc claims match behavior per profile.
Constraints
Same seam as PR #1836; land after it to avoid conflicts in subagent.rs.
Problem
crates/stella-cli/src/subagent.rs:413-415claims a panicked child 'lands here as a refusal … Nothing is settled on this side — the child already did it, on every path.' Two defects:pool.record_spend+push_sub_agent_spend) runs AFTERruntime.block_on(:377). A panic inside the child turn unwinds past it — real dollars spent by the child land in neither ledger. Not 'on every path'.panic = "abort"in the workspaceCargo.toml:194means release builds have no unwind at all: the whole process dies, and the module's 'child panics resolve to a refusal instead of unwinding the parent's turn' rationale (:69-86) is only true in debug builds.Fix direction
Wrap the child turn in
catch_unwind(the thread boundary already isolates it in debug; make the settle run in a drop guard so partially-recorded usage settles on every exit path), and either (a) fix the module docs to say what release builds actually do, or (b) if child-panic containment is a real product requirement, it needs a process boundary, not a thread. The drop-guard settle is the fix for defect 1 regardless.Verify
Witness (debug profile): a scripted child that panics after recording spend must still fold that spend into the parent's ledger; doc claims match behavior per profile.
Constraints
Same seam as PR #1836; land after it to avoid conflicts in subagent.rs.