fix(subagent): cover the scope-disposal effect registration with setup rollback

The `childCtx.effect()` that routes scope disposal into `releaseChild` was
registered after the install loop's try/catch, so a hypothetical throw
from the registration itself (effect() rejects only on an inactive fiber,
which a live unpublished scope cannot be) would leak the just-installed
batch — neither the setup-rollback catch nor `releaseChild` would release
it. Move the registration inside the try so the existing rollback path
covers it; no observable behavior change.
This commit is contained in:
Tianyi Cui
2026-08-02 12:28:48 +08:00
parent 42ee4e22de
commit 879a623095

View File

@@ -123,6 +123,10 @@ export class SubagentActivationSetupRegistry {
// Dispose that escaped record and invalidate the provisioning batch.
if (isRemoved(registration)) this.release(installation)
}
// Register the scope-disposal release inside the same try so the
// setup-rollback catch also covers a hypothetical effect-registration
// throw; today effect() cannot reject on a live unpublished scope.
childCtx.effect(() => () => { this.releaseChild(childCtx) }, 'subagents.activationSetup()')
} catch (error: unknown) {
// Keep the installer failure authoritative, but attempt every rollback.
try {
@@ -133,7 +137,6 @@ export class SubagentActivationSetupRegistry {
}
throw error
}
childCtx.effect(() => () => { this.releaseChild(childCtx) }, 'subagents.activationSetup()')
return {
assertIntact: () => {
if (!state.invalidated) return