Skip to content

fix(harness): move base to OpenCode 1.18.18 - #1393

Merged
marcusrbrown merged 2 commits into
mainfrom
chore/opencode-1.18.18
Aug 14, 2026
Merged

fix(harness): move base to OpenCode 1.18.18#1393
marcusrbrown merged 2 commits into
mainfrom
chore/opencode-1.18.18

Conversation

@marcusrbrown

Copy link
Copy Markdown
Collaborator

Sessions with history older than 2026-08-14 silently stopped responding. A prompt would be accepted, no error surfaced, and the model was never called. The logs showed loop step=0 followed immediately by exiting loop, with no stream line.

Cause

OpenCode message IDs pack Date.now() * 0x1000 + counter into a serialized field, but only the low 6 bytes are written. That value needs 53 bits and the field holds 48, so the timestamp wraps every 2^36 ms — about 795 days. The most recent wrap was 2026-08-14T11:19:55Z.

After a wrap, newly generated IDs sort lexically below every earlier one. The agent loop's exit guard compared lastUser.id < lastAssistant.id, which became permanently true for any session holding a pre-wrap assistant message, so the loop exited before dispatching to the model.

Fix

Upstream fixed the ordering in anomalyco/opencode#40990 and #40991, replacing the lexical comparison with a structural parent check and making "latest message" resolve by creation time. Both merged to dev on 2026-08-07 — two days after the v1.18.14 tag we were pinned to, which is why we were exposed.

Moving base_version to 1.18.18 picks up both. I confirmed by ancestry that each merge commit is contained in the v1.18.18 tag and absent from v1.18.14, and verified the resulting source carries the isAfter() helper in session/message-v2.ts and the parent-based guard in session/prompt.ts, with the old comparison gone.

No new integration refs are needed and no session data has to be migrated.

Carry set

Unchanged. I checked all twelve carried refs against 1.18.18: four are still open upstream (#19961, #31859, #31638, #33713) and eight are closed without merging, so none has been superseded by the new base.

DEFAULT_OPENCODE_VERSION is deliberately untouched — sync-default-version moves it once a release produces a real integration SHA, and inventing a +harness.<sha> suffix that no build emitted would be wrong. FALLBACK_VERSION and the @opencode-ai/sdk dependency pin track separately and stay as they are.

Verification

check-types, lint, and the harness suite (231 passing) all green against the new base.

Known gap

Upstream fixed the ordering but not the truncation, so the field still wraps. The next occurrence is around 2028-10-17. Widening it is a separate upstream change and is not part of this PR.

Sessions with history older than 2026-08-14 silently stopped responding.
OpenCode message IDs pack a timestamp into a 48-bit field, so the value
wraps every 795 days; the most recent wrap was 2026-08-14T11:19:55Z.
After it, new IDs sort below every earlier one, which made the agent
loop's exit guard permanently true — prompts were accepted and never
sent to the model, with no error surfaced.

Upstream fixed the ordering in anomalyco/opencode#40990 and #40991,
merged two days after the 1.18.14 tag we were pinned to. Moving the base
to 1.18.18 picks both up; no new integration refs are needed, and no
session data has to be migrated.

All twelve carried refs remain open or unmerged upstream, so the carry
set is unchanged. DEFAULT_OPENCODE_VERSION stays put — sync-default-version
moves it once a release produces a real integration SHA.

The underlying truncation is still present upstream, so the wrap recurs
around 2028-10-17.
The read-only clones under .slim/clonedeps/repos/ track the harness
base_version so a source check reflects what we actually ship. They were
still at 1.18.14 after the base moved.

This staleness had teeth: a search of the 1.18.14 tree for the message-ID
ordering bug found nothing and looked like evidence the bug was unreported,
when upstream had already fixed it in 1.18.18. The re-pinned tree now shows
the isAfter() helper in session/message-v2.ts and the structural parent
guard in session/prompt.ts, with the old lexical comparison gone.

@fro-bot fro-bot left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Verdict: PASS

This is a clean base-version bump from OpenCode 1.18.14 → 1.18.18. All six edits are internally consistent and correctly scoped; the deliberately-untouched pins are well-justified. I verified the coherence of every changed surface and confirmed the config-guarding test was updated.

What I verified

  • base_version1.18.18 (packages/harness/harness.config.json:4) is the authoritative pin, and every dependent surface tracks it: .slim/clonedeps.json (ref: v1.18.18, both entries), AGENTS.md clone-source notes, docs/reference/carry-ledger.md ("absent from stock through 1.18.18"), and the Renovate cap (allowedVersions: '<=1.18.18', renovate.json5:188).
  • cli.test.ts:16getProvenance() reads the live harness.config.json, so expect(p.baseVersion).toBe('1.18.18') genuinely guards the pin. This is the only test asserting the base literal, and it was correctly updated; without it the suite would fail. Good coverage discipline.
  • Deliberately-untouched pins are correct: DEFAULT_OPENCODE_VERSION and FALLBACK_VERSION (1.18.14), the @opencode-ai/sdk pins, and the eval baselines (u1.json, u1.test.ts) all still reference 1.18.14+harness.202732ae. This matches the two-stage version model — base_version is the source of truth for the next integration build, while DEFAULT_OPENCODE_VERSION tracks the last published build and is moved by sync-default-version only once a real integration SHA exists. Inventing a +harness.<sha> suffix here would be wrong.
  • Carry set unchanged (12 refs), correctly. Per the ledger's own rule, an unmerged upstream PR is not grounds to drop a carry; the PR description's re-gauge against 1.18.18 (4 open, 8 closed-unmerged, none superseded) is the right analysis.

Blocking issues

None.

Non-blocking concerns

  • Bun cap left at <=1.3.14 unverified against the new base. The harness build gate requires an exact match with upstream anomalyco/opencode's packageManager field at the base version (renovate.json5:191-196). A base bump can move that field. If 1.18.18 declares a newer Bun, the build would fail the gate. The PR doesn't claim a Bun change, so this is likely fine — but it's the one dimension the config-only diff doesn't attest to. Worth a one-line confirmation that 1.18.18's packageManager is still bun@1.3.14.
  • Upstream source-level claims not independently verifiable here. The PR description asserts the isAfter() helper in session/message-v2.ts, the parent-based guard in session/prompt.ts, and the removal of the old lexical comparison. The .slim/clonedeps/repos/ clones are metadata-tracked and not materialized in this CI checkout, so I could not re-check them. These are validated by the maintainer during the actual harness integrate/build run (where the merge and CLI build/verify gate execute), not by this config PR — so this is a note, not a gap in this change.

Missing tests

None. The base-version pin is the only new behavioral assertion, and it is covered by cli.test.ts:16. No other test needed updating; the eval baselines correctly continue to pin the last-published build rather than the config base.

Risk assessment (LOW):

Config/documentation-only change (+11/-11 across 6 files) with no runtime code path touched. The actually-shipped binary is produced and verified in the separate maintainer-gated harness release workflow, not by merging this PR — so blast radius on merge is nil. The only latent risk is the unverified Bun/packageManager match, which surfaces as a hard build-gate failure (fail-closed, not silent) at the next release dispatch. Regression likelihood: low. Security exposure: none.


Run Summary
Field Value
Event pull_request
Repository fro-bot/agent
Run ID 31849119088
Cache hit
Session ses_ffd77eb12ffekI8Xh2dmkkcxhF

@marcusrbrown
marcusrbrown merged commit 8f78fe6 into main Aug 14, 2026
15 checks passed
@marcusrbrown
marcusrbrown deleted the chore/opencode-1.18.18 branch August 14, 2026 23:24
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.

2 participants