Commit graph

5 commits

Author SHA1 Message Date
Pascal André
6a6367b560
chore(opencode): retire adaptations for runtimes and events OpenCode V2 no longer produces (#1034)
## Summary
This PR removes OpenCode compatibility code that nothing can reach any
more:
- Code that was already dead at the former 2.0.27 minimum, and is still
dead at the current 2.1.0 minimum (#1029).
- Handlers for events and data shapes that OpenCode V2 never produces.

Each item was checked against the upstream 2.0.27 and 2.1.0 sources
before removal.

Kept on purpose:
- Workarounds for upstream bugs or limits that are still present in
2.1.0.
- Code that reads conversations written by older runtimes: V1-migrated
tool names and metadata, `workspaceID` data, task summary titles,
`session-legacy` replay.
- Code that recognises and upgrades old CLIs and live older daemons: 1.x
replacement, beta recognition, 2.0.11 service discovery, 2.0.15 native
upgrade, `/api/status` and `/api/health` identification.

## Removed or changed
**Server**
- Negotiation: one "not modern → `canonical_api`" rule replaces the
pre-2.0.4 legacy schema recognition, and runs before #1029's
`native_contract` check.
- The transport no longer rewrites `/api/status`.
- Desktop skills no longer send the pre-2.0.4 `location` and `slash`
fields.
- The legacy `auth.json` usage fallback for daemons without
`credential.list` (pre-2.0.20) is removed, along with its UI reason and
the i18n key in 10 locales. A missing endpoint still fails safely.
- Workspace selectors are rejected up front, without a native resolution
request.
- CLI service probes try `/api/info` first. An admitted daemon no longer
costs two authenticated 404s on every check.

**UI**
- Remaining V1 `session.idle`/`session.status` branches: Missions store,
pending discovery (UI and server), `eventAffectsMessages`.
- `server.instance.disposed` and the now-unused `rehydrateInstance`.
- The V1 `worktree.ready` envelope (the handler now reads the V2 shape).
- V1 tool-state titles and the `success` status alias.
- Part `time.start` and `time.end`.
- Text stored as objects or segment arrays.
- `deriveMessageStatus`.
- The V1 `error.data.message` shape.
- `projectID` and `location` fallbacks on `session.created`.
- The replay-only `session.message.content.updated`.
- The unreachable `output.answers` fallback.

**Fixtures, Missions and docs**
- Legacy branches removed from the location, fork, families, pruning and
automation native fixtures. The WSL setup fixture now compares against
the reported version instead of 2.0.11.
- Unused 2.0.21 launch helpers removed.
- The Missions native and trajectory fixtures also run on the minimum
lane.
- The capability proof checks the reported version.
- Stale 2.0.2x labels now say "as of the 2.1.0 minimum".

**Follow-ups from the #1029 post-merge review**
- Test fixtures no longer send the ignored `recent: ""` compaction field
(18 sites).
- The manual compaction-isolation fixture accepts any published version
at or above the minimum.
- `CONTRIBUTING.md` wording updated.

114 files, +319 / −1117: source +90 / −487, tests/fixtures/CI +214 /
−604, i18n −10, docs +15 / −16.

## Validation (rebased on dev with #1029)
**Typechecks:** server and UI pass.

**Server tests**
- Touched areas: 480/480.
- Full server CI step: 2430 pass, 0 fail, 7 skipped, 1 cancelled. The
cancelled test is the `index.test.ts` real-process shutdown test; it hit
its 5 s timeout under load. It passes alone (4/4), and that file is
unchanged versus dev.

**UI unit tests**
- Touched files: 230/230.
- CI steps: 574/574, 200/200 and 519/519.

**Browser suites**, one at a time:
- Provider and service usage: provider-usage 13/13, service-usage 3/3.
- Missions: mission-visibility 3/3, mission-control-feedback 5/5,
mission-lifecycle-revision 10/10, mission-lifecycle-navigation 10/10,
mission-current-passage 1/1, mission-native-family 11/11.
- Transcript and rendering: compaction-responsiveness 5/5,
session-rendering 47/47, reasoning-collapse 3/3, render-cost 17/17,
tool-images 4/4, system-messages 10/10.
- Other: search-highlight 11 pass (1 skipped by its env gate),
panel-extensions 13/13.

**Native fixtures on an isolated 2.1.0 CLI:** location, session-fork,
automation, session-pruning, missions native, missions trajectory,
provider-usage, Missions capability proof and compaction-isolation all
pass. The WSL setup fixture was not run (it needs a WSL distro with a
Linux CLI).

## Left for later
- `RuntimeIdentity.discovery` is now write-only.
- `ownsLocation` has an unused `_client` parameter (about 30 callers).
- A test-only V1 translation in `auto-accept-manager.test.ts`.
- Out of scope: HTML-entity decoding (a product decision), the
`MutableHashMap` loop, the pruning-UI import-order workaround, unused
log-based Missions readers, and the unshipped managed-owner module with
its 2.0.24-pinned test.

Oversized source files touched: `stores/instances.ts` ~2,209,
`message-block.tsx` ~1,601, `workspaces/manager.ts` ~1,104,
`tool-call.css` ~1,047, `tool-call.tsx` ~865, `opencode-data.ts` ~865,
`api-types.ts` ~784, `session-events.ts` ~606,
`recurring-day-fixture.ts` ~535.
2026-10-20 19:19:47 +02:00
Pascal André
d6a890fba7
chore(opencode): qualify 2.1.0 and adopt its native contracts (#1029)
Adopt the OpenCode 2.1 native replay and compaction contracts, align client/plugin pins and set minimum and recommended runtime to 2.1.0. Preserve authenticated contract recognition for future/custom runtimes and explicit installation/restart boundaries.

Preserve historical conversations through official projection-based pruning revisions and independently checked migrations from 2.0.3, beta-19271 and 2.0.32. Retain ownership, execution claims, stale-selection checks and transaction fences. Update setup, help and qualification evidence.

Isolated Windows native qualification and integration checks cover pruning UI, historical reimport, Compare/Wayfinder, recurring Missions, builds and typechecks. Document broad-suite limitations and outstanding platform/package/mobile acceptance; this merge does not publish CodeNomad 1.0.0.
2026-10-20 16:46:38 +02:00
Pascal André
00029c8b04
fix(pending): stop cold-worktree recovery fallback; qualify OpenCode 2.0.24 (#865)
## Summary

- Qualify and pin the generated client/plugin at OpenCode **2.0.24**,
recommended independently of the unchanged **2.0.7** technical minimum.
- **On every runtime version**, automatic Form/permission recovery uses
only the authenticated loaded-only broker. Missing capacity stops
recovery non-authoritatively; it never falls back to ordinary lists
across historical/inactive worktrees.
- Retain known requests and editor drafts through unavailable/partial
recovery and rehydration, and show a localized recovery-incomplete
status even when no request is known. Only explicit settlement
reconciliation may use ordinary lists at the attempted request's
authorized location. Keep mutation fences and settlement tombstones.
- **Remove the private reader's runtime and Effect version allowlist.**
An untested/custom/prerelease/missing version label no longer disables
recovery. Registration checks the real native RPC capability; each read
validates graph, existing-only lease, queue, codec and identity
contracts. These checks fail safely without mass-loading fallback.
Tested versions remain evidence, not grounds for blocking other
versions.

## Contract audit

The authenticated isolated 2.0.24 daemon exposes 117 native OpenAPI
paths vs 116 on 2.0.22. The new `/api/vcs/init` is not exposed by
CodeNomad. Of 167 structural schema changes, most add declared
`LocationNotFoundError` failures to location-sensitive routes; other
changes add optional `ServerInfo.capabilities.persistentPty`,
WorktreeError's literal `_tag` and the VCS-init error. Published
declaration changes: 11/30 client files (+service-probe), 3/60 plugin,
8/36 protocol and 3/102 schema files (three retired IDE/question
declarations removed). No removed declaration is imported by CodeNomad;
no consumed dependency establishes a higher minimum.

The upstream source audit leaves LocationServiceMap, Form, Permission
and RPC contracts unchanged; the Location-services wrapper changes only
its TypeScript error parameter. Effect remains rc.112. The published
native implementation chunks are hash-checked against separate receipts
before each isolated fixture run.

Native SDK service contender/probe/PTY handoff internals change, but
CodeNomad retains its selected-CLI lifecycle adapter and bounded
authenticated registration fallback rather than using
`Service.ensure/stop`. **No shared daemon restart, storage mutation or
OpenCode PR is part of this change.**

The source audit also covers compaction-agent model/budget selection,
ChatGPT's temporary remote-model synchronization removal, local-provider
discovery/cache sharing, text-capable default selection, bounded MCP
connection/catalog retries and OAuth callback timing, Windows
instruction ancestry, skill frontmatter, subagent text boundaries and
PTY runtime storage/availability. These remain native-owned; no
CodeNomad adapter change is justified by the consumed contracts.
`dev-docs/OPENCODE_V2_COMPATIBILITY.md` records the consequences and
limits: synthetic account tests are not real OAuth/provider
certification, compaction isolation does not exhaust alternate
summarizer configurations, and no desktop terminal-survival test across
service restart is claimed.

## Native loaded-only evidence

### Follow-up: unjustified version lock removed

At the user's explicit direction, remove both
`PENDING_SNAPSHOT_NATIVE_VERSIONS` and the Effect-version equality
check, as well as all version checks in registration and reader
execution. The reader no longer accepts or consults an executing-version
argument. Regression coverage registers across 2.0.7–2.0.24,
newer/custom/prerelease/missing labels and a context whose `app` getter
throws if accessed. Actual malformed/missing contracts, unsafe data,
eviction/disposal races and timeouts remain non-authoritative. The rule
against blocking untested versions is recorded in `AGENTS.md`.

The source comparison across published tags 2.0.7–2.0.24 finds an
unchanged LocationServiceMap and existing-only lookup, RPC contracts and
queue-list interfaces. Changes in older releases affect Form
cancellation feedback/state and permission rejection feedback, not queue
listing. All these tags use Effect rc.112. This is source evidence, not
a claim that all eighteen releases have passed native fixtures.

After gate removal, **29/29 reader/broker/admission tests pass**, as do
server typecheck and pruning build. Fresh published native fixtures on
**2.0.23 and 2.0.24 pass**, recovering permissions/global Forms with 100
cold candidates (three actual Git worktrees), four native boots
before/after and zero cold constructions. The fresh bounded
**full-server run on the follow-up passes: 888 passed, 0 failed, 6
skipped (894 tests, 76 suites)**. Receipts: `no-gate-server.log`,
`no-gate-native-23/receipt.json`, `no-gate-native-24/receipt.json`,
`matrix-source-inventory.json`, `server-all-no-gate-final.log`.

The follow-up also records the distinction between pinned build
dependencies and an independently updated external service in
`AGENTS.md`; no README changes. Independent read-only gatekeeper review
of the **full diff**
`1abeba78043fc6ec1fac4eb57eb6c82a541cf66e..e159068bc0a37a668814c1c5a031115dea38ed28`:
**APPROVE, 0 findings**, 59 independent targeted tests passed plus an
isolated reactive check. The review is published separately on this PR;
it is an agent review, not human approval or deployment acceptance. At
the pre-merge CI inspection, runtime contracts (minimum/latest),
OpenCode compatibility (Linux/Windows/macOS) and native pruning
(Linux/macOS) passed; general tests, native pruning on Windows and Tauri
tests were still in progress. Earlier cancelled/skipped runs are not
passes. The user explicitly requested an admin merge after zero
gatekeeper findings; no all-green CI claim is made.

The committed Bun fixture now uses the same managed `.ts` plugin
discovery shape as production, not configured-package directory
resolution. It uses an authenticated unmodified published HTTP router
in-process, with an in-memory database, private discovery paths, no
listener/service discovery and no external provider.

| Published runtime | Preloaded Locations | Locations after recovery |
Native boot logs before/after | Cold candidates | Cold constructed |
|---|---:|---:|---:|---:|---:|
| 2.0.22 | 4 | 4 | 4 / 4 | 100 (three actual Git worktrees) | 0 |
| 2.0.24 | 4 | 4 | 4 / 4 | 100 (three actual Git worktrees) | 0 |

Both runs recover three permissions, six Forms including three global
Forms. They exercise absent/present backend presence, two backends
retaining registration, expiry, return and final disposal, coexistence
with the existing Promise pruning RPC, authenticated 401 rejection,
schema limits and non-authoritative failures. The boot-log assertion
also detects briefly constructed Locations even if they later disappear
from the map.

Short-fixture RSS: 2.0.24 460,599,296 → 461,824,000 bytes; 2.0.22
463,929,344 → 461,701,120 bytes. These are receipts, **not a memory
profile or comparable deployment soak**, and do not attribute the
reported 10 GiB to this fallback.

## Validation

Environment: Windows, Node **25.2.1**, Bun **1.3.14**. All native checks
use owned processes, synthetic providers/configuration/data and explicit
isolated CLI paths; never the shared daemon or user database.

- `bun scripts/test-pending-snapshot-native.mjs <qualified-packages>
<fresh-output>`: passes separately on published 2.0.22 and 2.0.24.
- 2.0.24 native automation, pruning parent runner,
Location/worktree/proxy/event relay, environment, fork, aside, degraded
Git, prompt skills, provider usage/accounts, permission receipts and
blank-session cleanup: **12 suites pass**.
- Minimum 2.0.7 with the same 2.0.24 client/plugin dependencies: **nine
isolated suites pass** (automation, pruning,
Location/worktree/proxy/relay, environment, fork, aside, degraded Git,
prompt skills and blank-session cleanup). Operation-specific
usage/account/receipt checks do not establish a new global minimum.
- `test-compaction-isolation-native.mjs <2.0.24-cli> --context-mib 2`:
passes with native compaction and outline enabled; the second session
completes before releasing the first session's provider gate.
- Focused UI pending recovery, compaction, Forms and permission
lifecycle: **37/37 pass**. Coverage includes 100 cold worktrees on
unsupported capability, reconnection, request retention, per-kind
mutation fences, settlement reconciliation, late supported/unsupported
responses and compaction admission.
- Final browser dock/selection/mobile regressions: **44/44 pass**. The
incomplete status appears with no known request at 393 px, has no
horizontal overflow, preserves a typed answer on repeated unavailable
recovery and disappears only after full recovery. Real-shell provenance,
recursive interruptions, Android keyboards and per-conversation drafts
remain covered.
- Server/UI typechecks and shared server/UI/plugin builds: pass.
- Final full server unit run after dependency reinstall, `node --import
tsx --test --test-concurrency=2 'packages/server/src/**/*.test.ts'`:
**888 pass, 0 fail, 6 skipped** (894 tests, 76 suites). An earlier
unbounded parallel run exceeded the existing 30-second pending-broker
deadline; the bounded rerun passes without changing that deadline.
- Broad UI unit tests: **1189 pass, 2 fail**. Both failures are
reproduced from unmodified base `1abeba78` sources in an extracted tree:
`classic-dark-surfaces.test.ts` expects a removed accent-hover override;
`tool-content.test.ts` expects copy text where the renderer returns
none. These paths use OpenCode types only, no runtime client import.
This suite is **not green**; unrelated UI corrections are intentionally
not included.
- `git diff --check`: pass. Lockfile retains unrelated package
versions/integrities; npm peer metadata recalculation remains.
- Lockfile reproducibility: `npm ci --ignore-scripts --no-audit
--no-fund` passes after browser fixtures release the Windows esbuild
executable. An earlier attempt during those fixtures encountered
`EPERM`; a simultaneously launched server rerun was invalidated by
dependency removal and is not counted as product evidence.

Detailed local receipts/logs are retained under
`C:\Users\Admin\AppData\Local\Temp\opencode\q224`:
`pending-native-final/receipt.json`, `pending-native-22/receipt.json`,
`schema-audit.log`, `*-declarations.diff`,
`server-all-bounded-final.log`, `ui-pending-final.log`,
`ui-all-final.log`, `ui-unrelated-baseline.log`,
`browser-interruption-final.log`, native-suite logs and
`compaction-2mib-final.log`.

## Deployment acceptance and limits

Not deployed to the active user service. After authorized deployment,
compare passive-recovery Location boot/eviction counts and process
RSS/private memory over a comparable observation window, separating
explicit user actions. Accumulated pre-fix Locations are not
automatically evicted. Only an explicitly confirmed shared-service
restart may release them. The separate Usage-flicker work is not a
substitute for this fix.

Unknown requests cannot be exhaustively recovered on a daemon without
the capability; known requests and live events remain usable. Existing
bootstrap warming, bounded coverage, compaction admission and ownership
constraints remain documented in
`dev-docs/OPENCODE_V2_COMPATIBILITY.md`.

File-size signal: `packages/ui/src/stores/instances.ts` remains
approximately 2,300 lines; no threshold-only refactor is included.
2026-10-06 23:06:50 +02:00
Pascal André
a9e624baf5
fix(opencode): qualify 2.0.22 and fence parent session creation (#830)
## Summary

Qualify **OpenCode 2.0.22**, align server/UI client and plugin pins, and
recommend this release. Keep the demonstrated **2.0.7** global minimum
and **2.0.20** Codex Usage feature-local requirement.

Block the new native `parentID` create variant in the workspace proxy:
upstream ignores the supplied location and inherits the parent's
directory. Require inspectable JSON objects to close opaque-body
bypasses. Root creation and the existing authorized fork route remain
available.

Started at `dev@0983db3c` (#828 Windows test harness), then integrated
`dev@97c361c3` (#789 Code Mode presentation). Conversation remains
attached to `D:\CodeNomad`; all work and tests use explicit separate
paths and synthetic data.

## Upstream audit: 2.0.21 → 2.0.22

- Authenticated native OpenAPI retains **116 paths**, with **11 schema
differences**: session creation gains optional `parentID`,
parent-not-found response/description; provider settings gain optional
`headerTimeout` and `chunkTimeout=false`; configured model capability
overrides become partial. No new proxy route or consumed mandatory API.
- Published declarations: **4/30 client, 2/60 plugin, 3/36 protocol,
4/102 schema** files change. Plugin session domains expose `remove` and
`compact`; CodeNomad does not add calls to them. Identifier namespace
export is additive.
- An isolated native fixture proves parent creation inherits the parent
location despite a different supplied directory. Mock and
production-proxy fixtures reject owned/foreign parents; malformed values
and opaque content types are covered before any native request. Owned
root creation stays available.
- Runtime changes include HTTP header/chunk/whole-response timeout
handling and bounded timeout retries, provider cache/error/tool-history
fixes, model capability defaults, and legacy MCP shutdown cleanup.
- Lock changes are limited to six `@opencode` packages and two workspace
entries. Integrity/dependency metadata matches independently installed
published packages; clean `npm ci --ignore-scripts` passes. Optional
OpenTUI peers are not installed by CodeNomad.

## Isolated local qualification

**Windows / Node 24.20.0**, isolated profiles, databases, services and
synthetic providers/credentials. No shared-daemon or personal-history
mutations.

- Previous **2.0.21 dependencies + runtime 2.0.22**: native
pruning/history/proxy acceptance passes.
- New **2.0.22 dependencies + runtimes 2.0.7 and 2.0.22**: seven suites
pass (automation, pruning/history/navigation, per-send environment,
inclusive forks, idle/busy side questions, blank-session cleanup,
Git-degraded recovery), plus explicit native proxy suites.
- Native/UI pruning acceptance passes through the committed parent
runner, with completion and actual child exit verified. This uses #828's
early dependency-import workaround, not the old late-import order. No
claim that underlying Windows heap corruption is repaired.
- Current compaction-isolation acceptance passes: session B progresses
while session A's provider response is held; bounded outline reads
retain daemon heartbeats. Fixture runtime selection is extended to
include 2.0.22; its assertions are unchanged. This supplemental fixture
was not qualified on 2.0.7 (explicit runtime selector rejects it).
- Native Codex Usage passes on 2.0.22 with synthetic OAuth/key
credentials and mocked quota HTTP; not a live-account/WSL test.
- Native migrations **2.0.3 → 2.0.22** and **beta-19271 → 2.0.22**
preserve full history/forks/inbox/provider selection.
- Packed standalone pruning plugin installed outside the repository
passes native acceptance.
- Native npm upgrade **2.0.15 → 2.0.22** passes; authenticated daemon
remains **2.0.15 / PID 43876** before and after.
- Full server run: **794 passed / 6 skipped / 0 failed**. Final guard
revision separately passes **68 focused server tests** and native proxy
suites on minimum/current. Aggregate runs use `--test-force-exit`.
- Targeted client/store/reducer/usage UI: **63/63** with
`--conditions=browser`, `--test-force-exit`, bounded timeout. Initial
broad UI run used the wrong Node conditions and hung at
`prioritized-read.test.ts`; only its owned processes were stopped. That
incomplete run is **not green**. The same prioritized-read tests pass
under the browser condition used by CI. No production fix is inferred
from this launch correction.
- **41 browser scenarios** pass: setup/install, auth recovery, tool
images, rendered Codex Usage and compaction responsiveness. Browser
tests do not use forced exit.
- Server/UI/Electron typechecks and production server/UI/plugin builds
pass. Revalidation after #789 integration and independent gatekeeper are
reported separately below.

Local results do not certify all real providers, Linux/macOS/WSL, or
installed Electron/Tauri hosts. Historical Windows import and Git
cleanup failures remain limitations, not repaired by this upgrade.
Remote CI is not continuously monitored and no global CI-green claim is
made.

Size note: existing `packages/server/src/server/http-server.ts` is
~2,359 lines;
`packages/server/src/server/__tests__/instance-proxy.test.ts` is ~1,139
lines. Changes are narrowly scoped; no unrelated size-driven refactor.

## Independent gatekeeper

Review launched on exact head `0a7615476034eabbff54967aacc8a93ab0e6ab12`
against `dev@97c361c33f6fa7de30be5dde31c0e26e12bab574`; verdict will be
published before any admin merge. Findings will be corrected and
reviewed again until zero actionable findings.
2026-10-02 15:47:14 +02:00
Pascal André
f6a18d00bd
fix: reduce compaction and cross-session responsiveness stalls
Aggregate compaction fragments before reactive SDK reduction while advancing
revision fences immediately and preserving native terminal and snapshot
authority. Keep task-tool shells keyed across payload updates and rescan bounded
membership so removals and replacements cannot leave phantom tools.

Isolate SSE callbacks and decode/dispatch diagnostics. Subscriber-local teardown
no longer destroys the healthy shared native client. Install HTTP cancellation
before preflight and fence late continuations without replaying or interrupting
already-admitted mutations. Preserve ownership and environment admission checks.

Move HTTP password derivation to async scrypt with serialized password changes
and login-authority fencing. Yield cooperatively in both structural-index phases
without changing snapshot/digest protocols; an individual SQLite step stays sync.

Add isolated red/green regressions, bounded browser/native qualification scripts,
independent reviews, source fingerprints and performance evidence for issue #824.
Synchronize the Git focus assertion with its async contract and make the opt-in
trace self-contained instead of serializing a tsx helper into the browser.

Validation includes 793 passing server tests and 6 skips after replay, UI/server/
Electron typechecks, UI/server/plugin builds, and private Windows native 2.0.21
fixtures. Renderer fixture median main-thread cost is 324.57 to 16.94 ms.
The latest full browser run remains 358 pass, 1 fail, 1 skip: its trace failure
was subsequently reproduced and corrected with a minimal Chromium check, but
the full suite has not been rerun. Store assertions use force-exit; natural
cleanup and Linux Electron to Windows LAN/HTTP with 2.0.19 remain unqualified.

Publish as a draft for review, not a universal resolution or issue-closing fix.
Refs #824.
2026-10-02 00:40:45 +02:00