From f4af2a1c22ef226b994b61bd02cc41feb219762f Mon Sep 17 00:00:00 2001 From: Kevin Nguyen Date: Wed, 29 Jul 2026 22:48:58 +0700 Subject: [PATCH] =?UTF-8?q?Roadmap:=20CB-402=20Stage=20B=20live-dogfooded?= =?UTF-8?q?=20=E2=80=94=20issue=20#7=20closed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spawn -> CB-306 readiness gate -> bridge_send -> structured bridge_reply -> teardown, verified end to end against opencode 1.18.5. The schema-drift risk did not materialise: the adapter was designed against 1.1.31 and its generated OPENCODE_CONFIG still validates unchanged. Provider question resolved without credentials — opencode's gateway serves free-tier models, so no key was needed and no guard entry applies. --- 8-Roadmap.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/8-Roadmap.md b/8-Roadmap.md index dfe1c21..87a3fda 100644 --- a/8-Roadmap.md +++ b/8-Roadmap.md @@ -116,7 +116,7 @@ Compact scope; expand into detailed tickets when a stage starts (as Stage 1 is b |---|---| | **2** | `CB-201` envelope schema + codec · `CB-202` worker `bridge_reply` tool + reviewer skill · `CB-203` reply rendezvous (corr match; resolve on reply *or* the `working→idle` edge) · `CB-204` subscription guard via `ccs env` + allowlist · `CB-205` blocked-worker path (`bridge_ask`) | | **3** | `CB-301` ✅ session manager (spawn/reuse/recycle) · `CB-301-ext` ✅ per-worker git worktree + config-parity overlay (`97ecc71`) · `CB-302` ✅ worker checkpoint — **shipped as commit→push→**_**worker-opened PR**_ (`64e70ef`: repo-scoped forge-token injection + the implementer skill), which **supersedes** this row's original `STATE.md`-file framing; see `docs/Worker-Git-Workflow.md` · `CB-303` ✅ `idle_ttl`/`context_cap`/drain · `CB-304` ✅ `bridge_list` roster+live (`9fe04bf`) · `CB-305` ✅ multi-profile routing | -| **4** | `CB-401` ✅ PeerLauncher SPI Stage A — extracted in-tree, one adapter (`ClaudeCodeLauncher`), core uses the `PeerLauncher` interface, main @ `3aa69a9`. `CB-402` ✅ **Stage B landed** (`ded226a`) — `OpenCodeLauncher` as the SPI-proving second adapter: shares none of Claude's private seams (no `ANTHROPIC_BASE_URL`, no `SubscriptionGuard`), mounts the bridge MCP via a generated `OPENCODE_CONFIG`, and is routed by `kind:` through `CompositePeerLauncher`. ⚠️ **Code-complete but not yet live-dogfooded** — see the note below. Stage C — dynamic external plugin loading, future, gated by trust/capability model. | +| **4** | `CB-401` ✅ PeerLauncher SPI Stage A — extracted in-tree, one adapter (`ClaudeCodeLauncher`), core uses the `PeerLauncher` interface, main @ `3aa69a9`. `CB-402` ✅ **Stage B complete** (`ded226a`, dogfooded 2026-07-29) — `OpenCodeLauncher` as the SPI-proving second adapter: shares none of Claude's private seams (no `ANTHROPIC_BASE_URL`, no `SubscriptionGuard`), mounts the bridge MCP via a generated `OPENCODE_CONFIG`, and is routed by `kind:` through `CompositePeerLauncher`. Live spawn→send→`bridge_reply`→teardown verified against opencode 1.18.5. Stage C — dynamic external plugin loading, future, gated by trust/capability model. | | **5** | ✅ **All landed.** `CB-501` bearer auth + non-loopback-bind fail-fast (TLS at a proxy, not in-JVM — see `docs/CB-5xx-Hardening.md` D3) · `CB-502` `/metrics` (zero-dependency Prometheus renderer, D4) + `/healthz` · `CB-503` mock-socket CI (`.gitea/workflows/ci.yml`) · `CB-504` launchd agent + systemd unit + herdr-socket startup wait · `CB-505` per-session authz table + audit log | ## CB-401 — Peer Launcher SPI (Stage 4) @@ -128,16 +128,17 @@ Stage A has landed on main: - ✅ **Core decoupled** — `session.SessionManager` now depends on the `PeerLauncher` interface and keys its registry on `PeerHandle.id()` (equal to herdr `paneId` for the Claude adapter, so no value change). - ✅ **Behaviour-preserving** — full green gate on main @ `3aa69a9`, **183 tests**. -**Stage B / CB-402 — landed on main (`ded226a`), with one caveat:** +**Stage B / CB-402 — landed on main (`ded226a`) and live-dogfooded 2026-07-29 (issue #7 closed):** - ✅ `HerdrPeerLauncher` base extracted; `OpenCodeLauncher` implements the three divergent hooks. - ✅ `kind:` discriminator on worker profiles; `CompositePeerLauncher` routes spawn/stop/reap/list by kind. - ✅ The SPI is proven provider-neutral: opencode uses **none** of Claude Code's private launch seams. -- ⚠️ **Not live-dogfooded.** Every prior ticket (CB-306/307/108) was gated on a live run; this one - merged with the dogfood deferred ("needs a running-daemon restart + a resolved Gemini provider"). - `opencode` is not installed on the dev host and the provider question - (CB-402 §7 Q1) is still open. **This is the one known-unverified item carried into the - cross-host stage** — gitea issue #7 stays open until the §5 checklist runs. +- ✅ **Live dogfood complete.** Spawn → CB-306 readiness gate → `bridge_send` → structured + `bridge_reply` (`replySource: "reply"`, not the completion fallback) → teardown, all through the + REST surface against opencode **1.18.5**. The schema-drift risk did not materialise: the adapter + was designed against 1.1.31 and its generated `OPENCODE_CONFIG` still validates unchanged. + Provider question resolved — opencode's gateway serves **free-tier models with zero credentials**, + so no key was needed and no `guard` entry applies. Full run: `docs/CB-402-OpenCode-Adapter.md` §8. **Stage C (future):** dynamic external plugin loading (`ServiceLoader`/jar discovery). Gated by a trust/capability model — a launcher runs at daemon privilege and can inject env/tokens into peers, so third-party plugins are not enabled without that model.