Repository navigation
OpenCode 2 plugin layer: shared-bridge kill on timeout, subagent misclassification, and smaller issues #646
Description
AFT: code references at v0.61.0 (packages/aft-bridge, packages/opencode-plugin). OpenCode 2, no daemon. Our sessions run many background subagents, all inheriting the lead's folder, so they share one bridge per root.
1. Two timeouts with no child output kill the shared bridge and every in-flight call
aft-bridge/src/bridge.ts:1183-1215 and handleTimeout (~:1979-2013): a request that times out when consecutiveTimeouts >= hangThreshold (default 2) and the child has produced no output since it was sent SIGKILLs the bridge; all pending requests fail with "bridge killed during sibling timeout". With subagents sharing the root's bridge, one slow call can cancel every running shell call across them. aft-bridge/src/command-timeouts.ts gives 60 s only to callgraph/trace/inspect/grep/glob/search/semantic_search; ast_search, ast_replace, outline, zoom (with call-graph annotations), import and safety get the 30 s default, so a slow ast_search over a large repo while the bridge is busy is the likely trigger. (We haven't seen a kill in our logs; the "no child activity" guard makes it rarer.)
Suggestion: add those commands to the long table, and on timeout reject only the timed-out request when others are pending. Related: #317 (closed) for Inspect.
2. A slow subagent lookup marks the session as primary for 30 s
opencode-plugin/src/subagent-detect.ts:117-140: a lookup that fails or takes over 1 s is cached as "primary" for 30 s. That changes shell behaviour (bash.ts:642) and skips the stop handler (v2-session-lifecycle.ts:253), so a stopped subagent's background tasks aren't killed. The V2 lookup (subagent-detect.ts:221-245) has no Effect.timeout (unlike session-directory.ts:225), and the losing race leaves the fiber running. Many subagents starting together makes 1 s easy to miss. Suggestion: timeout the lookup, cache failures as "unknown" and retry.
3. Tool output that is JSON with "success": false becomes a tool error
opencode-plugin/src/tools/definitions/v2.ts:190-209,429-430 treats any text result that parses as JSON with success:false as a failure envelope and throws its message, including read of a JSON fixture and curl … | jq output in shell. Suggestion: apply the check only to results the AFT engine produced.
4. Smaller items
- Failed completion ack is never retried.
runtime-consumer.ts:288-295admits the wake, then sendsbash_ack_completions; if that throws, the completion is held, and on re-routesession-delivery.ts:70sees it as already admitted and returns before acking. The task likely stays outstanding (blocks idle eviction, reappears in drains).admittedCompletionsalso grows without bound. - Unbounded per-session maps.
v2-session-lifecycle.ts:36-52(SessionWatchesper session, dropped only on Location dispose),:96(task kill closures for primary sessions),sync-watch-abort.ts:24,permissions.ts:143,session-delivery.ts:61, andsessionBgStates(bg-notifications.ts:1924) pinned by tasks whose completion never arrives. - Silent failures.
server-runtime.mjs:219wrapsbootLocationinEffect.promise; a rejection becomes a defect swallowed byEffect.ignoreCause(comment :201-204), leaving AFT absent for that Location with no error.v2-session-lifecycle.ts:223runs the event consumer inEffect.forever(pull…); if the stream ends, subagent-stop cleanup stops with no log. - Live shell progress never reaches OpenCode 2.
bash.ts:737callsmetadata({output, description})with flat keys, butdefinitions/v2.ts:335-343forwards onlyupdate.metadataandupdate.title; same inbash_watch.ts:174,220,224. Each chunk also runsEffect.runPromise(progress({}))without a catch. - Overrides keyed by the main checkout.
server-runtime.mjs:91,98acquires the pool bylocation.project?.canonical, andlocation-lifecycle.ts:243-271stores overrides under it, while bridges are keyed by the session's own directory (the worktree, after OpenCode 2: a session in a linked git worktree reads and runs commands in the main checkout #387).configByRoot.get(worktree)misses, so a session rooted in a linked worktree may losestorage_dir/bash_permissionsoverrides (not verified end to end).
Activity
mason: retire confirmed wakes and release settled watch tasks (#633)
mason: retire confirmed wakes and release settled watch tasks (#633)
mason: kill bridge-owned tasks when an OpenCode 2 session is deleted
mason: drop OpenCode 2 completions for deleted sessions, still acknow…
mason: retire confirmed wakes and release settled watch tasks (#633)
mason: retire confirmed wakes and release settled watch tasks (#633)
mason: fix OpenCode 2 plugin layer issues from issue cortexkit#646
mason: retire confirmed wakes and release settled watch tasks (#633)
mason: retire confirmed wakes and release settled watch tasks (#633)
mason: retire confirmed wakes and release settled watch tasks (#633)
mason: retire confirmed wakes and release settled watch tasks (#633)
mason: retire confirmed wakes and release settled watch tasks (#633)
mason: retire confirmed wakes and release settled watch tasks (#633)