CB-402: live dogfood complete — Stage B verified against opencode 1.18.5
Closes the one known-unverified item before cross-host. CB-402 merged in
ded226a with increment 5 (the §5 live checklist) deferred; it has now run.
Provider question (§7 Q1) resolved with no credentials needed: opencode's own
gateway serves free-tier models. `opencode auth list` reports 0 credentials,
yet `opencode run -m opencode/north-mini-code-free` answers. Distinct from the
primary's subscription by construction, and needs no guard entry — opencode
carries no ANTHROPIC_BASE_URL, so SubscriptionGuard never applies to it.
The schema-drift risk was the real one and it did not bite. The adapter was
designed against opencode 1.1.31; installed is 1.18.5. The generated config
still validates unchanged (type:"remote" + instructions:[path]), and
`OPENCODE_CONFIG=… opencode mcp list` reports the bridge connected. Pinned as
a verified fact for 1.18.5.
Full lifecycle through REST: spawn (201, kind-routed to OpenCodeLauncher) ->
CB-306 gate passed ~0.6s -> ready -> send -> {"replySource":"reply"} (a
STRUCTURED bridge_reply, not the CB-115 completion fallback) -> delete (204,
tolerant teardown).
Unplanned cross-validation with CB-501: the audit trail recorded the reply as
role=WORKER actor=worker:term_657c… — connection-based identity classified an
opencode process as a worker with no opencode-specific handling. The identity
model is peer-kind-agnostic, which is what CB-308 needs when the roster
stretches across hosts.
Stage 5 verified live on the same run: /workers (CB-304) answers where the
13-day-old daemon 404'd, /metrics counted the delegation
(sends_total{outcome=replied} 1, replies_total{path=rendezvous} 1,
inbox_depth 0), and the audit log captured SPAWN/SEND/REPLY with correct roles.
Adds the opencode-free dogfood profile to the local bridged.yaml (gitignored;
recorded here for reproducibility) and docs/CB-402 §8 as-built.
This commit is contained in:
@@ -1,11 +1,8 @@
|
||||
# CB-402 — Second peer adapter: opencode (Stage B of the Peer Launcher SPI)
|
||||
|
||||
**Status:** ✅ **implemented and merged** (`ded226a`) — increments 1–4 of §4 all landed
|
||||
(`HerdrPeerLauncher` base, `kind:` discriminator, `OpenCodeLauncher`, `CompositePeerLauncher`).
|
||||
⚠️ **Increment 5 — the live dogfood (§5) — has NOT run.** It was deferred at merge time pending a
|
||||
daemon restart and a resolved provider, and §7 Q1 (which provider this host has credentials for) is
|
||||
still open; `opencode` is not installed on the dev host. Gitea issue #7 stays open until the §5
|
||||
checklist is executed. This is the single known-unverified item going into the cross-host stage.
|
||||
**Status:** ✅ **complete — implemented, merged (`ded226a`), and live-dogfooded 2026-07-29.**
|
||||
All five increments of §4 are done, including increment 5 (the §5 live checklist). See
|
||||
[§8 As-built](#8-as-built--live-dogfood-2026-07-29) for the run. Gitea issue #7 closed.
|
||||
**Depends on:** CB-401 Stage A (`PeerLauncher` SPI, merged `3aa69a9`)
|
||||
**Stage:** 4 (Pluggable peers) · Stage B
|
||||
**Owner action:** design-note → file issue → delegate → primary-verify (per CB-401/306/307)
|
||||
@@ -258,10 +255,51 @@ until it is "major" (Stage-B whole), per the CB-401 bar.
|
||||
|
||||
## 7. Open questions for the lead
|
||||
|
||||
1. **Provider for the opencode dogfood profile** — which provider/model does this host have
|
||||
credentials for that is distinct from the primary's subscription?
|
||||
2. **Charter carrier** — generated `OPENCODE_CONFIG` `instructions` (recommended) vs an
|
||||
`AGENTS.md` in the worktree?
|
||||
3. **Merge cadence** — hold the whole Stage B on a feature branch to merge as one "major"
|
||||
unit (per CB-401), or land the behaviour-preserving base-extraction (increment 1) to `main`
|
||||
first to shrink the branch?
|
||||
1. ✅ **Provider — resolved 2026-07-29.** None was needed. opencode's own gateway serves
|
||||
**free-tier models with zero credentials** (`opencode auth list` → *0 credentials*, yet
|
||||
`opencode run -m opencode/north-mini-code-free` answers). The dogfood profile uses
|
||||
`opencode/north-mini-code-free`. It is distinct from the primary's Anthropic subscription by
|
||||
construction, and needs no `guard` entry — opencode carries no `ANTHROPIC_BASE_URL`, so the
|
||||
`SubscriptionGuard` does not apply to it at all.
|
||||
2. ✅ **Charter carrier — confirmed as designed:** generated `OPENCODE_CONFIG` `instructions`.
|
||||
Verified working against the installed version.
|
||||
3. ✅ **Merge cadence — resolved as it happened:** Stage B landed as one unit (`ded226a`).
|
||||
|
||||
---
|
||||
|
||||
## 8. As-built — live dogfood (2026-07-29)
|
||||
|
||||
Run against `bridged` on `127.0.0.1:8766` at main `19cdf8d`, with opencode **1.18.5** installed
|
||||
via Homebrew. Every §5 risk is now a verified fact rather than an assumption.
|
||||
|
||||
**The version-drift risk was the real one, and it did not bite.** This adapter was designed against
|
||||
opencode **1.1.31**; the installed version is **1.18.5**. The generated config schema still
|
||||
validates unchanged — `mcp.<name>.type: "remote"`, `url`, `enabled`, and `instructions: [path]` are
|
||||
all accepted, and `OPENCODE_CONFIG=… opencode mcp list` reports `✓ bridge connected`. Pinned here
|
||||
as a dogfood-verified fact for 1.18.5.
|
||||
|
||||
| §5 risk | Result |
|
||||
|---|---|
|
||||
| opencode TUI ⇄ herdr injection; CB-306 gate | ✅ `peer pane=wD:p3 reached injectable state` ~0.6s after `agent.start` |
|
||||
| Bridge MCP visible + `bridge_reply` callable | ✅ MCP `initialize` from `Implementation[name=opencode, version=1.18.5]`; worker replied through the tool |
|
||||
| Config schema drift (1.1.31 → 1.18.5) | ✅ unchanged, see above |
|
||||
| Provider credentials | ✅ free tier, zero credentials |
|
||||
|
||||
Full lifecycle exercised through the REST surface:
|
||||
|
||||
1. `POST /workers?profile=opencode-free` → `201`, routed by `kind:` through `CompositePeerLauncher`
|
||||
to `OpenCodeLauncher` (`spawning opencode profile=opencode-free`), pane `wD:p3`.
|
||||
2. Readiness: `{"ready":true,"status":"idle"}`, roster state `ready`.
|
||||
3. `POST /sessions/{id}/message` → **`{"replySource":"reply","reply":"391"}`** — a *structured*
|
||||
`bridge_reply`, not the CB-115 completion-fallback transcript scrape. The clean path.
|
||||
4. `DELETE /workers/wD:p3` → `204`, roster empty, tolerant teardown (`tab_not_found` ignored —
|
||||
opencode had already closed its own tab).
|
||||
|
||||
**Unplanned cross-validation with CB-501.** The audit trail recorded the worker's reply as
|
||||
`role: WORKER, actor: worker:term_657c1dad2b9731e, action: REPLY, outcome: allowed`. Connection-based
|
||||
identity (loopback peer PID → herdr pane) classified an **opencode** process as a worker with no
|
||||
opencode-specific handling — confirming the identity model is peer-kind-agnostic, which is exactly
|
||||
what CB-308 needs when it stretches the roster across hosts.
|
||||
|
||||
CB-502 counters for the same run: `bridged_sends_total{outcome="replied"} 1`,
|
||||
`bridged_replies_total{path="rendezvous"} 1`, `bridged_inbox_depth{...} 0`.
|
||||
|
||||
+1
-1
Submodule wiki updated: ef3e68a400...f4af2a1c22
Reference in New Issue
Block a user