From b414a74c2640da23c7cd90cccb0c8ccf96712b55 Mon Sep 17 00:00:00 2001 From: Dai Ha Date: Fri, 14 Aug 2026 20:56:16 +0200 Subject: [PATCH] CB-559: drop .claude/settings.local.json from the default parity overlay --- .../ltms/bridged/config/BridgedConfig.java | 8 ++++- .../bridged/config/BridgedConfigTest.java | 35 +++++++++++++++++++ .../session/WorktreeSessionManagerTest.java | 4 +-- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/bridged/src/main/java/dev/ltms/bridged/config/BridgedConfig.java b/bridged/src/main/java/dev/ltms/bridged/config/BridgedConfig.java index 236c675..547edc9 100644 --- a/bridged/src/main/java/dev/ltms/bridged/config/BridgedConfig.java +++ b/bridged/src/main/java/dev/ltms/bridged/config/BridgedConfig.java @@ -210,8 +210,14 @@ public record BridgedConfig( // worker the primary's IDE servers, which are bound to the primary's checkout — so its // navigation returned paths outside its own worktree. GitWorktrees now neutralizes that // file instead; a worker's tools are whatever its launcher mounts. + // .claude/settings.local.json is the sibling that was left behind: it pre-approves tools + // (mcp__context7__*, mcp__jetbrains, mcp__intellij-index, Workflow(code-review)) a worker + // must never hold, and enables MCP servers by name. Its grants are currently INERT because + // GitWorktrees.isolateToolSurface strips every worktree's server map to empty — the named + // servers do not exist there to be enabled. This is defence in depth, not a live fix: the + // worker stays isolated only because this separate mechanism already removes the servers. parityOverlay = (parityOverlay == null || parityOverlay.isEmpty()) - ? List.of(".claude/settings.local.json", ".env", ".envrc") + ? List.of(".env", ".envrc") : List.copyOf(parityOverlay); // gitTokenEnv stays null when unset (opt-in). gitHostEnv defaults so operators enabling // checkpoints need only set gitTokenEnv; it is injected only alongside a resolved token. diff --git a/bridged/src/test/java/dev/ltms/bridged/config/BridgedConfigTest.java b/bridged/src/test/java/dev/ltms/bridged/config/BridgedConfigTest.java index 49a853a..9475e69 100644 --- a/bridged/src/test/java/dev/ltms/bridged/config/BridgedConfigTest.java +++ b/bridged/src/test/java/dev/ltms/bridged/config/BridgedConfigTest.java @@ -1167,6 +1167,41 @@ class BridgedConfigTest { "a profile without the key stays off-subscription (the default)"); } + @Test + void parityOverlayDefaultsToEnvFilesOnly(@TempDir Path dir) throws Exception { + Path f = dir.resolve("no-overlay.yaml"); + Files.writeString(f, """ + bind: + port: 8080 + profiles: + gx10: + baseUrl: http://gx10.gw:8000 + """); + + BridgedConfig cfg = BridgedConfig.load(f); + assertEquals(List.of(".env", ".envrc"), + cfg.profiles().get("gx10").parityOverlay(), + "the default parity overlay is the env files; settings.local.json is no longer copied by default"); + } + + @Test + void parityOverlayExplicitListIsPreservedVerbatim(@TempDir Path dir) throws Exception { + Path f = dir.resolve("explicit-overlay.yaml"); + Files.writeString(f, """ + bind: + port: 8080 + profiles: + gx10: + baseUrl: http://gx10.gw:8000 + parityOverlay: [".claude/settings.local.json", ".env"] + """); + + BridgedConfig cfg = BridgedConfig.load(f); + assertEquals(List.of(".claude/settings.local.json", ".env"), + cfg.profiles().get("gx10").parityOverlay(), + "an operator's explicit list survives verbatim — the default only changes when unset"); + } + // ── CB-542: subscription:true must not smuggle an unguarded endpoint via env: ─────────────── @Test diff --git a/bridged/src/test/java/dev/ltms/bridged/session/WorktreeSessionManagerTest.java b/bridged/src/test/java/dev/ltms/bridged/session/WorktreeSessionManagerTest.java index ad99305..421b968 100644 --- a/bridged/src/test/java/dev/ltms/bridged/session/WorktreeSessionManagerTest.java +++ b/bridged/src/test/java/dev/ltms/bridged/session/WorktreeSessionManagerTest.java @@ -94,12 +94,12 @@ class WorktreeSessionManagerTest { FakeWorktrees.OverlayCall overlay = worktrees.lastOverlay(); assertNotNull(overlay); assertEquals("/repo", overlay.repoRoot()); - assertEquals(List.of(".claude/settings.local.json", ".env", ".envrc"), + assertEquals(List.of(".env", ".envrc"), overlay.requested(), "default parity overlay is used when unset"); assertFalse(overlay.requested().contains(".mcp.json"), "CB-525: replicating the primary's MCP config gives a worker the primary's IDE " + "servers, which navigate its edits out of its own worktree"); - assertEquals(List.of(".claude/settings.local.json", ".envrc"), overlay.copied(), + assertEquals(List.of(".envrc"), overlay.copied(), "existing paths are copied; missing paths are skipped"); assertEquals(List.of(".envrc"), overlay.skipWorktree(), "tracked copied paths are --skip-worktree'd");