diff --git a/claude_bottle/backend/docker/launch.py b/claude_bottle/backend/docker/launch.py index dc98195..f8e559c 100644 --- a/claude_bottle/backend/docker/launch.py +++ b/claude_bottle/backend/docker/launch.py @@ -278,7 +278,7 @@ def _run_agent_container(plan: DockerBottlePlan, internal_network: str) -> str: docker_args.extend(["-e", name]) # PRD 0013: read-only current-config mount so the agent can read - # routes.json / allowlist / Dockerfile before composing a + # routes.yaml / allowlist / Dockerfile before composing a # supervise tool-call proposal. Mounted from the per-bottle # stage_dir/current-config/ populated at prepare time. if plan.supervise_plan is not None: diff --git a/claude_bottle/supervise.py b/claude_bottle/supervise.py index 08a05ab..dbf37c4 100644 --- a/claude_bottle/supervise.py +++ b/claude_bottle/supervise.py @@ -425,7 +425,13 @@ def sha256_hex(content: str) -> str: # Filenames inside the per-bottle current-config dir. The agent reads # these (read-only) from CURRENT_CONFIG_DIR_IN_AGENT and proposes # modified versions back via the three MCP tools. -CURRENT_CONFIG_ROUTES = "routes.json" +# Filename of the staged egress-proxy routes file inside the agent's +# read-only current-config mount. JSON content under a `.yaml` +# extension to match the live file the egress-proxy sidecar reads +# (`/etc/egress-proxy/routes.yaml`) — the egress-proxy-block tool +# description points at this exact path, and the apply step writes +# the new content to the matching live path. +CURRENT_CONFIG_ROUTES = "routes.yaml" CURRENT_CONFIG_ALLOWLIST = "allowlist" CURRENT_CONFIG_DOCKERFILE = "Dockerfile" @@ -437,7 +443,7 @@ class SupervisePlan: `queue_dir` is the host directory bind-mounted into the sidecar at /run/supervise/queue. `current_config_dir` is the host directory bind-mounted (read-only) into the *agent* container at - /etc/claude-bottle/current-config, holding routes.json + allowlist + /etc/claude-bottle/current-config, holding routes.yaml + allowlist + Dockerfile so the agent can read them before composing a proposal. `internal_network` is empty at prepare time; the backend's launch step fills it via dataclasses.replace before diff --git a/tests/unit/test_dashboard.py b/tests/unit/test_dashboard.py index 80e8c24..39ce94a 100644 --- a/tests/unit/test_dashboard.py +++ b/tests/unit/test_dashboard.py @@ -38,7 +38,7 @@ FIXED = datetime(2026, 5, 25, 12, 0, 0, tzinfo=timezone.utc) def _proposal(slug: str = "dev", tool: str = TOOL_EGRESS_PROXY_BLOCK) -> Proposal: - # Per-tool payload shape: cred-proxy gets routes.json, pipelock + # Per-tool payload shape: cred-proxy gets routes.yaml, pipelock # gets a failed URL (PR #25 follow-up), capability gets a # Dockerfile-ish blob. Match the production dispatch in # PROPOSED_FILE_FIELD. diff --git a/tests/unit/test_supervise.py b/tests/unit/test_supervise.py index f24baa2..9e18c70 100644 --- a/tests/unit/test_supervise.py +++ b/tests/unit/test_supervise.py @@ -297,9 +297,9 @@ class TestDiffAndHash(unittest.TestCase): self.assertEqual("", render_diff("a\nb\n", "a\nb\n")) def test_render_diff_shows_changes(self): - diff = render_diff("a\nb\nc\n", "a\nB\nc\n", label="routes.json") - self.assertIn("routes.json (current)", diff) - self.assertIn("routes.json (proposed)", diff) + diff = render_diff("a\nb\nc\n", "a\nB\nc\n", label="routes.yaml") + self.assertIn("routes.yaml (current)", diff) + self.assertIn("routes.yaml (proposed)", diff) self.assertIn("-b", diff) self.assertIn("+B", diff) @@ -365,7 +365,7 @@ class TestSupervisePrepare(unittest.TestCase): self.assertTrue(plan.current_config_dir.is_dir()) self.assertEqual( '{"routes": [{"path": "/x/"}]}\n', - (plan.current_config_dir / "routes.json").read_text(), + (plan.current_config_dir / "routes.yaml").read_text(), ) self.assertEqual( "example.com\n", @@ -382,7 +382,7 @@ class TestSupervisePrepare(unittest.TestCase): plan = _StubSupervise().prepare("dev", self.stage_dir) self.assertEqual( '{"routes": []}\n', - (plan.current_config_dir / "routes.json").read_text(), + (plan.current_config_dir / "routes.yaml").read_text(), )