refactor: make OpenCode instance lifecycle runtime-neutral #376

Closed
opened 2026-07-18 00:16:16 +02:00 by dries · 1 comment
Owner

Parent

#375

What to build

Make ocman the authoritative owner of each managed project OpenCode instance while preserving native tmux behavior. EnsureProjectOpencode remains the host-local orchestration seam, but launch returns a reachable endpoint and opaque runtime identity instead of requiring a later lsof lookup and tmux-specific result.

This prefactor must correct existing lifecycle gaps: concurrent ensures, manual duplicate launches, stale tmux sessions, health verification, restart routing, and recovery of managed native instances after ocman restarts. Container support is not part of this ticket.

Acceptance criteria

  • Concurrent ensure calls for one canonical project root launch at most one instance and all callers receive the same healthy endpoint.
  • Sequential ensure calls reuse the healthy managed instance.
  • Manual and automatic launch paths cannot create competing managed instances for the same project.
  • A stale tmux session without a healthy OpenCode API does not suppress relaunch.
  • Launch reports a reachable endpoint and runtime-neutral instance reference directly; tmux metadata is optional observability data.
  • Runtime health verifies the expected OpenCode API rather than listener presence alone.
  • Restart is owner-routed through hostsvc.Host and works for local and remote native instances.
  • Managed native instances can be recovered after an ocman restart without trusting stale persisted identifiers.
  • Native tmux mode remains behaviorally compatible for existing users.
  • Capabilities distinguish OpenCode launch availability from tmux UI availability.
  • Concurrency, stale-instance, restart, recovery, and duplicate-launch regression tests cover the public seams.
  • Architecture and one-instance-per-project documentation describe the runtime-neutral lifecycle.

Blocked by

None - can start immediately.

## Parent #375 ## What to build Make ocman the authoritative owner of each managed project OpenCode instance while preserving native tmux behavior. `EnsureProjectOpencode` remains the host-local orchestration seam, but launch returns a reachable endpoint and opaque runtime identity instead of requiring a later `lsof` lookup and tmux-specific result. This prefactor must correct existing lifecycle gaps: concurrent ensures, manual duplicate launches, stale tmux sessions, health verification, restart routing, and recovery of managed native instances after ocman restarts. Container support is not part of this ticket. ## Acceptance criteria - [ ] Concurrent ensure calls for one canonical project root launch at most one instance and all callers receive the same healthy endpoint. - [ ] Sequential ensure calls reuse the healthy managed instance. - [ ] Manual and automatic launch paths cannot create competing managed instances for the same project. - [ ] A stale tmux session without a healthy OpenCode API does not suppress relaunch. - [ ] Launch reports a reachable endpoint and runtime-neutral instance reference directly; tmux metadata is optional observability data. - [ ] Runtime health verifies the expected OpenCode API rather than listener presence alone. - [ ] Restart is owner-routed through `hostsvc.Host` and works for local and remote native instances. - [ ] Managed native instances can be recovered after an ocman restart without trusting stale persisted identifiers. - [ ] Native tmux mode remains behaviorally compatible for existing users. - [ ] Capabilities distinguish OpenCode launch availability from tmux UI availability. - [ ] Concurrency, stale-instance, restart, recovery, and duplicate-launch regression tests cover the public seams. - [ ] Architecture and one-instance-per-project documentation describe the runtime-neutral lifecycle. ## Blocked by None - can start immediately.
Author
Owner

Resolved. The runtime-neutral lifecycle landed on main (squash 39cf7a5, PRs #390–#394) with follow-up fixes #395, #396, #397.

Acceptance criteria:

  • Concurrent ensures collapse via singleflight to one instance/shared endpoint (TestEnsureProjectOpencode_Concurrent)
  • Sequential ensures reuse the healthy instance (TestEnsureProjectOpencode_ReusesHealthyInstance)
  • Manual + automatic launch share the single EnsureProjectOpencode seam
  • Stale tmux session without a healthy API relaunches (TestEnsureProjectOpencode_StaleRelaunch)
  • Launch returns a reachable Endpoint + runtime-neutral ocruntime.Instance; tmux is observability metadata
  • Health is an API probe (GET {endpoint}/config), not listener presence
  • Owner-routed RestartProjectOpencode works local + remote (restart_test.go, platform_roundtrip_test.go)
  • Recovery re-probes persisted rows, discards dead ones (managed_opencode table v35, TestEnsureProjectOpencode_RecoversFromStore)
  • Native tmux mode behaviorally compatible
  • HostCaps.OpencodeLaunch capability split from Tmux (#393)
  • Concurrency/stale/restart/recovery/duplicate regression tests cover the seams
  • Architecture + one-instance-per-project docs updated (#394)

Container support (#375) remains out of scope for this ticket.

Resolved. The runtime-neutral lifecycle landed on `main` (squash 39cf7a5, PRs #390–#394) with follow-up fixes #395, #396, #397. Acceptance criteria: - [x] Concurrent ensures collapse via singleflight to one instance/shared endpoint (TestEnsureProjectOpencode_Concurrent) - [x] Sequential ensures reuse the healthy instance (TestEnsureProjectOpencode_ReusesHealthyInstance) - [x] Manual + automatic launch share the single EnsureProjectOpencode seam - [x] Stale tmux session without a healthy API relaunches (TestEnsureProjectOpencode_StaleRelaunch) - [x] Launch returns a reachable Endpoint + runtime-neutral ocruntime.Instance; tmux is observability metadata - [x] Health is an API probe (GET {endpoint}/config), not listener presence - [x] Owner-routed RestartProjectOpencode works local + remote (restart_test.go, platform_roundtrip_test.go) - [x] Recovery re-probes persisted rows, discards dead ones (managed_opencode table v35, TestEnsureProjectOpencode_RecoversFromStore) - [x] Native tmux mode behaviorally compatible - [x] HostCaps.OpencodeLaunch capability split from Tmux (#393) - [x] Concurrency/stale/restart/recovery/duplicate regression tests cover the seams - [x] Architecture + one-instance-per-project docs updated (#394) Container support (#375) remains out of scope for this ticket.
dries closed this issue 2026-07-20 10:21:53 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
dries/ocman#376
No description provided.