diff --git a/bridged/src/main/java/dev/ltms/bridged/worker/OpenCodeLauncher.java b/bridged/src/main/java/dev/ltms/bridged/worker/OpenCodeLauncher.java index a93d5b1..b2757e4 100644 --- a/bridged/src/main/java/dev/ltms/bridged/worker/OpenCodeLauncher.java +++ b/bridged/src/main/java/dev/ltms/bridged/worker/OpenCodeLauncher.java @@ -247,6 +247,21 @@ public final class OpenCodeLauncher extends HerdrPeerLauncher { ObjectNode root = JSON.createObjectNode(); root.put("$schema", "https://opencode.ai/config.json"); + // CB-523, opencode side: a worker that runs out of context dies mid-turn, and its reply + // — the entire point of the turn — is lost with it. Auto-compaction is therefore not an + // operator preference for a bridged worker, it is a condition of the turn contract. + // + // Stated deliberately even though it is redundant today: OPENCODE_CONFIG is MERGED over + // ~/.config/opencode/config.json rather than replacing it, so a worker already inherits + // an `auto: true` set at home. We do not want that inheritance to be what the guarantee + // rests on — the home file is outside this repo, differs per machine, and is not ours. + // + // Know the cost before removing it: this key WINS over the home config (verified — an + // OPENCODE_CONFIG value overrides the home value, it does not defer to it), so an + // operator who sets `compaction.auto: false` at home cannot turn it off for bridged + // workers. That is the intended trade for peers we spawn and whose turns we must land; + // if per-profile control is ever wanted, add a profile knob rather than dropping this. + root.putObject("compaction").put("auto", true); if (cfg.hasMcp()) { Path charter = dir.resolve("reply-charter.md"); diff --git a/bridged/src/test/java/dev/ltms/bridged/worker/OpenCodeLauncherTest.java b/bridged/src/test/java/dev/ltms/bridged/worker/OpenCodeLauncherTest.java index 3d93939..bf42fd1 100644 --- a/bridged/src/test/java/dev/ltms/bridged/worker/OpenCodeLauncherTest.java +++ b/bridged/src/test/java/dev/ltms/bridged/worker/OpenCodeLauncherTest.java @@ -74,6 +74,8 @@ class OpenCodeLauncherTest { // Assert on parsed structure, not substrings: the generated config is real JSON and its // whitespace is the formatter's business, not the contract's. JsonNode json = new ObjectMapper().readTree(Path.of(cfgPath).toFile()); + assertTrue(json.path("compaction").path("auto").asBoolean(), + "spawned opencode peers explicitly enable automatic compaction"); JsonNode bridge = json.path("mcp").path("bridge"); assertEquals("remote", bridge.path("type").asText(), "bridge is mounted as a remote MCP server"); assertEquals("http://127.0.0.1:8765/mcp", bridge.path("url").asText(),