Skip to content

feat(server): keep live sessions running through engine rollover - #3696

Merged
reachjalil merged 5 commits into
devfrom
fix/runtime-provider-application
Aug 11, 2026
Merged

reachjalil merged 5 commits into
devfrom
fix/runtime-provider-application

Conversation

@reachjalil

@reachjalil reachjalil commented Aug 11, 2026 •

Copy link
Copy Markdown
Member

Problem

Provider, plugin, agent, permission, and other build-time OpenCode configuration changes currently dispose the managed engine. Deferring those updates while work is active protects live sessions, but leaves new configuration unavailable until every run has finished.

Change

  • add opt-in managed-engine rollover with one primary and at most one draining generation
  • pin live session and permission/question traffic to the draining generation while new sessions use the fresh primary
  • merge session status, pending prompts, and event streams across live generations
  • retire the old engine after its sessions become idle, with bounded drain and abort behavior
  • expose the rollover capability and add a persisted Desktop Continuous engine updates preview
  • allow provider and runtime-config reload paths to roll immediately when the pool is available
  • add focused lifecycle coverage and an opt-in Testkit acceptance tape

Verification

  • apps/server: 667 passed, 8 skipped
  • apps/app: 707 passed
  • desktop runtime tests: 19 passed
  • server, app, and eval TypeScript checks
  • focused post-rebase rollover, streaming, provider-sync, and desktop checks: 39 passed
  • Testkit acceptance tape collects successfully; the real-provider run remains opt-in via OPENWORK_EVAL_ENGINE_ROLLOVER_SPEC

@vercel

vercel Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-app Ready Ready Preview Aug 11, 2026 3:42pm
openwork-den Ready Ready Preview Aug 11, 2026 3:42pm
openwork-den-worker-proxy Ready Ready Preview Aug 11, 2026 3:42pm
openwork-diagnostics Ready Ready Preview Aug 11, 2026 3:42pm
openwork-landing Ready Ready Preview, v0 Aug 11, 2026 3:42pm

diff-warden[bot]
diff-warden Bot previously approved these changes Aug 11, 2026

@diff-warden diff-warden Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warden security clearance: clear. No blocking findings (security or desktop↔den sync) in this diff (48c27744bc1e7e49eb82bc47e37c67c3fbf09e8a). Automated clearance satisfies the required-review gate only — a human still reviews and merges. Analysis run

diff-warden[bot]
diff-warden Bot previously approved these changes Aug 11, 2026

@diff-warden diff-warden Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warden security clearance: clear. No blocking findings (security or desktop↔den sync) in this diff (8d4e4242012f6034c96e4595d47d18b4c5c37957). Automated clearance satisfies the required-review gate only — a human still reviews and merges. Analysis run

A provider sync pass disposes the managed engine when provider config
changes, because the engine only reads provider config (models, npm,
options.baseURL) from OPENCODE_CONFIG when it builds an instance. If a
pass reported a change on unchanged upstream state, that dispose would
repeat on every 5-minute interval and tear down whatever is running.

The existing coverage only exercised an empty provider list and a single
follow-up pass. Extend it: materialize a provider carrying the full
config surface, then assert five further passes over a byte-identical
snapshot report "noop", perform no additional dispose, and do not
re-deliver the credential (the auth push is fingerprint-guarded).

Also record why a provider config delta still reloads at all. Credentials
reach a live engine through PUT /auth/{providerID}, but provider config
has no live path: PATCH /config, the only endpoint accepting it, performs
the same instance dispose as POST /instance/dispose. Verified against
opencode 1.18.15 — PATCH /config and POST /instance/dispose both drop an
open /event stream, while GET /config and PUT /auth/{id} leave it intact.
A reload that lands while sessions are running has only had bad options:
dispose and abort the runs, or defer and leave config stale until the
engine idles. Provider config in particular cannot be applied any other
way -- the engine reads it when it builds an instance.

Add an opt-in third option. When a reload is needed and the engine is
busy, spawn a standby with the new config, point the server at it once it
answers, and keep the old engine alive only until its runs finish. Idle
engines still reload in place, so steady state stays one process.

- ServerConfig.engineRollover (env OPENWORK_ENGINE_ROLLOVER), off by default
- engine-pool.ts: generations, config fingerprint so a repeated no-op
  reload never spawns, single-flight with latest-wins coalescing, standby
  readiness probe before any flip, synchronous pointer flip, drain monitor
  that closes the old engine once idle, and a grace period after which
  remaining sessions are aborted
- Cap of one primary plus one draining engine: changes arriving mid-drain
  coalesce rather than stacking processes
- reloadOpencodeEngine dispatches to the pool when enabled; the existing
  in-place dispose is unchanged and still the default

Tunable via OPENWORK_ENGINE_DRAIN_TIMEOUT_MS, _DRAIN_POLL_MS,
_MIN_SPAWN_INTERVAL_MS, _ABORT_SETTLE_MS.

@diff-warden diff-warden Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warden security clearance: clear. No blocking findings (security or desktop↔den sync) in this diff (139c70c4fa0e496340231ebd4a7b984db1db80e7). Automated clearance satisfies the required-review gate only — a human still reviews and merges. Analysis run

@reachjalil
reachjalil merged commit a973f4a into dev Aug 11, 2026
28 checks passed

This branch was successfully deployed

5 active deployments
Preview – openwork-den — 139c70c4 Deployed Aug 11, 2026 by vercel[bot]
Preview – openwork-den-worker-proxy — 139c70c4 Deployed Aug 11, 2026 by vercel[bot]
Preview – openwork-landing — 139c70c4 Deployed Aug 11, 2026 by vercel[bot]
Preview – openwork-app — 139c70c4 Deployed Aug 11, 2026 by vercel[bot]
Preview – openwork-diagnostics — 139c70c4 Deployed Aug 11, 2026 by vercel[bot]
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.

1 participant