Skip to content

feat: three-prong session lifecycle fuse for opencode adapter#145

Merged
c-h- merged 4 commits intomainfrom
feat/opencode-lifecycle-fuse
Mar 13, 2026
Merged

feat: three-prong session lifecycle fuse for opencode adapter#145
c-h- merged 4 commits intomainfrom
feat/opencode-lifecycle-fuse

Conversation

@c-h-
Copy link
Copy Markdown
Collaborator

@c-h- c-h- commented Mar 13, 2026

Closes #144

Problem

opencode run (non-interactive mode) doesn't write session files to opencode's native storage directory. This makes sessions launched via agentctl launch --matrix invisible to agentctl list, events(), and the supervisor.

Discovered during autonomous implementation runs: agents did real work but died before pushing/opening PRs, and the supervisor was never notified because no session.stopped events were emitted.

Solution: Three-Prong Fuse

When agentctl launches an opencode session, three signals race. First to fire cancels the others via AbortController:

  1. Exit file — wrapper writes exit code to .exit file → detected on next poll cycle (≤15s)
  2. PID deathkill(pid, 0) poll every 15s with PID recycling protection via startTime
  3. Master timeout — configurable (default 3h), emits session.timeout (does NOT kill the process — supervisor decides)

Changes

  • src/adapters/opencode.ts — Fuse registration, bootstrap from meta dir, three-prong check loop, dedup via firedFuseIds, pending events for pre-resolved sessions
  • src/core/types.ts — Added session.timeout event type
  • src/utils/session-meta.ts — Extended meta with cwd, model, prompt, masterTimeoutMs fields
  • src/adapters/opencode.test.ts — Integration tests for all three signals + dedup
  • src/adapters/opencode-fuse.test.ts — Unit tests for fuse cancellation, PID recycling, timeout
  • src/utils/session-meta.test.ts — Tests for extended session meta

Test Plan

  • npm run lint
  • npm run typecheck
  • npm run build
  • npm test — 571 passing ✅
  • E2E: launch opencode via matrix, verify session.stopped fires within 15s of process exit

Doink (OpenClaw) and others added 4 commits March 12, 2026 21:07
Implement a first-signal-wins fuse pattern for opencode sessions:

1. Wrapper script captures exit code to a .exit file (primary signal)
2. PID death polling via kill(pid,0) with recycling protection (secondary)
3. Configurable master timeout (default 3h) emits session.timeout (tertiary)

Each signal cancels the others via AbortController. Sessions launched via
agentctl remain visible in list()/discover()/events() through the meta-dir
even when opencode native storage lacks a session file.

Also adds listSessionMeta() and updateSessionMeta() utilities.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement three-signal fuse pattern for detecting opencode session
completion. Previously, sessions launched via agentctl were invisible
because opencode's run mode doesn't write native session files.

Three signals, first to fire cancels the others (AbortController):
1. Exit file: wrapper writes exit code to .exit file on completion
2. PID death: poll kill(pid,0) every 15s with PID recycling detection
3. Master timeout: configurable (default 3h), emits session.timeout

Also fixes:
- list() now enumerates from meta dir as primary source
- bootstrapFusesFromMeta emits pending events for pre-resolved sessions
- firedFuseIds prevents legacy poll from duplicating fuse events
- session.timeout added as new lifecycle event type

Closes #144
Remove lifecycle fuse tests from opencode.test.ts since they already
exist in opencode-fuse.test.ts and opencode-launch.test.ts. Keeps
opencode.test.ts focused on adapter core functionality.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The lifecycle fuse tests were already comprehensively covered in
opencode-fuse.test.ts. The copies in opencode.test.ts had timing
issues causing 5s timeouts in CI. Remove them and keep only the
meta-dir list() tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@c-h- c-h- force-pushed the feat/opencode-lifecycle-fuse branch from 8daea1c to e35af53 Compare March 13, 2026 04:07
@c-h- c-h- merged commit 476b555 into main Mar 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: three-prong session lifecycle fuse for opencode adapter

1 participant