Skip to content

OpenCode Desktop — Harness Hardening

Choose a tag to compare

@kianwoon kianwoon released this 28 Aug 19:45
· 539 commits to main since this release

OpenCode Desktop — Harness Hardening

Follows v1.18.25-fork.1 · Commits 08f1250f18..0b8be202fd

This release ships the fixes from a full three-way code review of the
harness enhancements (workflow engine, Phase 3 core, plugins/schema), plus a
root-cause investigation of reviewer-subagent aborts. The build contains all
harness enhancements from fork.1 — summarized below — now hardened by review.

Harness Enhancements in This Build

Everything implemented across the enhancement plan (phases 0–3) is in this
binary — this is the complete current state of the fork's harness:

⚡ Workflow DAG Engine (default ON)

Multi-step pipeline orchestration: the workflow tool, event-driven parallel
scheduling with a concurrency cap (experimental.workflow_concurrency, default
4), failure propagation to dependents, deadlock detection, and
PLAN → ORCHESTRATE → REACT system guidance so the model recognizes
pipeline-shaped goals automatically. Disable with
OPENCODE_EXPERIMENTAL_WORKFLOWS=false.

🧠 Task Profile Assessor + Effort Governor (plugin)

Every task boundary is assessed by cheap heuristics (complexity hints, risk
domains, simple-task signals). Complex tasks start at medium reasoning effort,
complex+risky at high — no wasted turns discovering difficulty; the model can
still escalate via request_effort. Risky tasks get a "verify blast radius"
system notice. Never lowers user-pinned effort.

🗜️ Context Optimizer (plugin, always-on)

KV-cache-aware pruning: budget gate keeps the provider cache prefix
byte-identical under cap; tail-backward minimal prune when over; reasoning
always stripped; CJK-aware token estimation with live cache telemetry
(~90% hit rate, 676k+ tokens saved to date).

✅ Automatic Verification Gate (opt-in)

After a task finishes, a pure risk detector (sensitive paths, destructive
prompts, broad refactors) can trigger one reviewer subagent pass whose findings
are injected back before the session goes idle. Enable with
OPENCODE_EXPERIMENTAL_VERIFICATION=true.

⏰ Followup Delivery Mode (V2 sessions)

delivery: "followup" + deliverAt: durably admitted input that stays pending
until its time passes, then promotes at the idle boundary like queue.
SessionExecution.schedule wakes the session at the due time.

💾 Durable Background Job Records

Background job lifecycle transitions persist to a background_job table
(best-effort, never breaks live work). Restarts sweep stale "running" rows to
cancelled ("interrupted by restart"); list/get merge live entries over
recorded history.

Investigation: reviewer-subagent cancellations

Reviewer subagents were observed aborting mid-run. Root cause: user-initiated
cancels
(ESC / stop on the parent or child session), correctly propagated by
the task tool's interrupt chain — verified via DB error classes
(MessageAbortedError for parent cancels, stream-level abort for child-session
cancels), log timelines, and the absence of any timeout/provider error. Not a
harness bug. The real defect was cosmetic: cancels were reported as
Subagent failed: The operation was aborted.

Fixes from the Review

Workflow engine

  • Admission failure no longer poisons the session — a rejected
    WorkflowPart (bad step count, unknown agent, cycle) was re-collected from
    history forever, so every later prompt re-dispatched and re-threw instead of
    reaching the model. The dispatcher now settles a terminal assistant message
    with the admission error before throwing (the task-consumption boundary).
    Regression-tested: the follow-up prompt reaches the model.
  • 8 e2e tests restored (the AGENTS-mandated acceptance gate): deadlock-free
    dispatch, correctable tool errors with retry, soft-fail summaries carrying
    real error reasons, upstream-result bounding + step metadata, dispatch-side
    step-cap and unknown-agent admission, plannedBy provenance, and the
    system-guidance content check.

Durable job records

  • Transition serialization — a slow running record can no longer overwrite
    a terminal completed/error row (CASE-guarded upsert). Regression-tested.
  • Process-global startup sweep — sweeps run once per process, so a second
    instance sharing the database can no longer cancel another instance's live
    jobs.

Plugins

  • Effort router — per-session state map is now FIFO-bounded (1000), so
    long-lived processes don't grow it without limit.
  • Task tool — user-initiated subagent cancels now report
    Subagent cancelled, matching what actually happened.

Verification

  • 154 tests green across 9 suites (prompt loop, workflow e2e + unit, tool,
    verification gate, background jobs, effort router); typecheck clean in
    schema, core, and opencode
  • CLI binary 0.0.0-main-202608281938 (smoke-tested)
  • Desktop assets packaged via the full OPENCODE_CHANNEL=prod chain with the
    acceptance gate passing:
    ✅ Verified prod build: node-CpUNE8Or.js embeds channel "prod" and uses opencode.db

Downloads (macOS arm64, prod channel)

  • opencode-desktop-mac-arm64.dmg
  • opencode-desktop-mac-arm64.zip