the fork blocker was a missing credential, not an upstream bug

Andre said his terminal opencode reaches paid zen models and suggested it was simply not set
up here. Correct, and my second wrong call on this page.

The new /api pipeline has its own credential store — /api/integration and /api/credential —
separate from auth.json, which is what the CLI, opencode run and the legacy /session surface
read. Ours had none connected, so it fell back to what needs no credential: the free tier.
One POST to /api/integration/opencode/connect/key fixes it, and it survives a serve restart.
sonnet and haiku both run on the new pipeline now.

The tell I had and did not use: the configured default is big-pickle, and a session with no
model ran on ling-3.0-tiny-free INSTEAD of the default. A pipeline ignoring its configured
default cannot use it — a credential symptom, sitting in /config/providers the whole time.

So steer, queue, interrupt and the resumable per-session SSE are all available with real
models. alpha needs the same one-time connect, and the sidecar should do it at boot rather
than depend on someone having run it by hand.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 17:37:07 +01:00
co-authored by Claude Opus 5
parent 6e9a8ee42f
commit ecb9025f8f
2 changed files with 44 additions and 3 deletions
+43 -2
View File
@@ -5,7 +5,8 @@
> The conclusion is reversed below. The mistake is written up rather than deleted, because the shape of
> it is the useful part.
**Decision: the fork is worth taking. Not started, and gated on one open question.**
**Decision: the fork is worth taking, and it is no longer blocked.** Not started; the blocker turned out
to be a missing credential and is fixed — see RESOLVED below.
---
@@ -41,7 +42,47 @@ Steer and queue are exactly the two features we hand-built for Claude and that A
changer. Having them as primitives, plus a resumable per-session cursor that mirrors officer's durable
replay, is a strong argument for migrating.
## The blocker, now characterised: only free models run
## RESOLVED — it was a missing credential, not a bug
Andre said he had a paid Zen key working in his terminal and suggested it simply was not set up here. He
was right, and this is the second wrong conclusion I reached on this page.
**The new pipeline has its own credential store, separate from `auth.json`.** `opencode run`, the CLI and
the legacy `/session` surface all read `~/.local/share/opencode/auth.json`, which holds the Zen key — so
they reach paid models. The `/api/*` surface reads integrations instead (`/api/integration`,
`/api/credential`), and ours had **none connected**. With no credential it silently fell back to what
needs none, which is exactly the free tier.
The fix was one call, and it persists across a serve restart (verified — a paid model still ran after
`pm2 restart officer-opencode`):
```
POST /api/integration/opencode/connect/key { "key": "<zen key>", "label": "…" } → 204
```
Afterwards `claude-sonnet-4-6` and `claude-haiku-4-5` both run on the new pipeline. **The fork is
unblocked**, and everything the table above promises — steer, queue, interrupt, resumable per-session
SSE — is available with real models.
Two consequences worth carrying:
- **alpha needs the same one-time connect** before it can use the new pipeline.
- The sidecar should do this itself at boot rather than relying on someone having run it by hand, since
a missing credential degrades to "only free models work" with no error anywhere.
### What the evidence looked like while I was getting it wrong
Recorded because the shape repeats: the failure was **silent and total** for paid models, and the cost
table drew a perfect line — every cost-0 model ran, every cost>0 model did not. I read that as a billing
boundary inside a broken pipeline. It was a billing boundary caused by an absent credential, which is a
far more ordinary explanation and one Andre reached from knowing his own setup rather than from the API.
The tell I had and did not use: the configured default is `opencode/big-pickle`, and a session created
with no model ran on `ling-3.0-tiny-free` **instead of the default**. A pipeline ignoring its configured
default is a pipeline that cannot use it — that is a credential symptom, and it was sitting in the
`/config/providers` output the whole time.
## The original diagnosis, kept for the record: only free models run
It is not sonnet, and it is not `variant`. Swept four models through `POST /api/session/{id}/model`
followed by a prompt:
+1 -1
View File
@@ -91,7 +91,7 @@ is gone. What remains is bucket 1 — capabilities Claude has and OpenCode does
visible ones (token streaming, mid-turn injection, background tasks, interrupt-without-teardown) are
downstream of `stdin: 'ignore'` and therefore of the Phase 2 fork.
**The fork is REOPENED and worth taking.** The serve publishes a newer `/api/session/*` surface offering
**The fork is REOPENED, unblocked, and worth taking.** The serve publishes a newer `/api/session/*` surface offering
those capabilities natively, and on 1.18.16 **`delivery: "steer"` and `delivery: "queue"` are both
verified working** — mid-turn injection and queueing, as primitives, plus `/interrupt` and a resumable
per-session event stream. One blocker remains: `claude-sonnet-4-6` silently does not run on that surface