Reproduction
The retained start path creates an environment before detached dispatch.
If provider.create succeeds and environment.dispatch rejects, startRetainedRun propagates the dispatch error and does not call environment.destroy.
A focused injected-provider reproduction measured created=1, dispatched=1, destroyed=0 against @tangle-network/agent-runtime 0.132.6.
The missing cleanup is in the post-create path of startRetainedRun in src/runtime/retained-run-start.ts.
Impact
Each failed dispatch can leave one paid cloud environment alive until its external lifetime expires.
Braid hit the adjacent public path on 2026-08-12. Sandbox creation succeeded, dispatch returned HTTP 404, and only the external proof cleanup prevented a leak.
Required behavior
Wrap detached dispatch and exact-reference validation in cleanup.
Call environment.destroy when any post-create step fails before a RetainedRunHandle is returned.
Preserve the original error and include cleanup failure in an AggregateError.
Do not destroy an environment after a valid handle has crossed the admission boundary.
Completion proof
- A dispatch rejection destroys exactly one created environment.
- An invalid control reference destroys exactly one created environment.
- A destroy failure preserves both errors.
- A successful retained start does not destroy the environment.
- The real Tangle Sandbox failure path leaves zero owned resources.
Reproduction
The retained start path creates an environment before detached dispatch.
If provider.create succeeds and environment.dispatch rejects, startRetainedRun propagates the dispatch error and does not call environment.destroy.
A focused injected-provider reproduction measured created=1, dispatched=1, destroyed=0 against @tangle-network/agent-runtime 0.132.6.
The missing cleanup is in the post-create path of startRetainedRun in src/runtime/retained-run-start.ts.
Impact
Each failed dispatch can leave one paid cloud environment alive until its external lifetime expires.
Braid hit the adjacent public path on 2026-08-12. Sandbox creation succeeded, dispatch returned HTTP 404, and only the external proof cleanup prevented a leak.
Required behavior
Wrap detached dispatch and exact-reference validation in cleanup.
Call environment.destroy when any post-create step fails before a RetainedRunHandle is returned.
Preserve the original error and include cleanup failure in an AggregateError.
Do not destroy an environment after a valid handle has crossed the admission boundary.
Completion proof