fix(macos): review fixes — token on plan, self-heal, symmetric digest, DHCP poll
Addresses findings from a high-effort review of the PRD 0070 macOS backend. Correctness: - Stamp identity_token onto MacosContainerBottlePlan after registration. git's gitconfig extraHeader and the supervise MCP --header read getattr(plan,"identity_token","") at provision time, and both reach the gateway on NO_PROXY (bypassing the egress proxy that carries the token). The plan never carried it, so /resolve fail-closed and every git fetch/push and supervise call from a macOS bottle would have been denied. Registration precedes provision(), so — unlike the run-time env — the plan can carry it. - Self-heal the orchestrator: recreate when it is not (source-current AND answering /health), not on the source-hash label alone. A container running current code but with a wedged HTTP server was left alone and polled to death, failing every launch until manual deletion. - image_digest and container_image_digest now read the same descriptor.digest field; dropped image_digest's id/tag fallback that could yield a value the container side can't produce — a permanent mismatch would have recreated the shared gateway on every launch (severing every live bottle's egress, since the replacement gets a new DHCP address). - Poll for the agent's and gateway's DHCP address instead of a fatal read right after `container run` (there is no --ip; the address can lag start). Cleanup: - One _inspect_first + _descriptor_digest behind the four inspect readers. - Shared bind_mount_spec (util) and host_db_dir (paths) replace per-module copies; _GIT_HTTP_PORT now imports git_http_backend.DEFAULT_PORT. - Drop the dead _url cache / url property and the write-only agent_proxy_url. Deferred (noted on the PR, not fixed here): the gateway image rebuilding on every launch (needs source-hash-labeled build), SQLite shared across VM guests, and the sh -lc profile-override edge — each is design-level or behavior-risk beyond a review fix. Verified: real Apple Container bring-up is green and idempotent; 1826 unit tests pass with `container` absent (CI parity), pyright clean, pylint 9.86. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -158,6 +158,36 @@ class TestIdentityTokenDelivery(unittest.TestCase):
|
||||
argv = bottle.agent_argv(["--help"], tty=False)
|
||||
self.assertNotIn("--env", argv)
|
||||
|
||||
|
||||
class TestPlanIdentityToken(unittest.TestCase):
|
||||
"""git-gate's gitconfig extraHeader and the supervise MCP --header read
|
||||
`getattr(plan, "identity_token", "")` at provision time and both bypass the
|
||||
egress proxy (NO_PROXY), so the exec-time proxy token never reaches them —
|
||||
the plan must carry the token or /resolve fail-closes and git + supervise
|
||||
are denied on macOS."""
|
||||
|
||||
def test_macos_plan_has_the_identity_token_field(self) -> None:
|
||||
from dataclasses import fields
|
||||
|
||||
from bot_bottle.backend.macos_container.bottle_plan import (
|
||||
MacosContainerBottlePlan,
|
||||
)
|
||||
names = {f.name for f in fields(MacosContainerBottlePlan)}
|
||||
self.assertIn("identity_token", names)
|
||||
|
||||
def test_matches_the_docker_plan(self) -> None:
|
||||
"""Both consolidated backends must expose identity_token so a shared
|
||||
provision-time consumer degrades to neither backend silently."""
|
||||
from dataclasses import fields
|
||||
|
||||
from bot_bottle.backend.docker.bottle_plan import DockerBottlePlan
|
||||
from bot_bottle.backend.macos_container.bottle_plan import (
|
||||
MacosContainerBottlePlan,
|
||||
)
|
||||
docker = {f.name for f in fields(DockerBottlePlan)}
|
||||
macos = {f.name for f in fields(MacosContainerBottlePlan)}
|
||||
self.assertIn("identity_token", docker & macos)
|
||||
|
||||
def test_provisioning_exec_also_carries_the_token(self) -> None:
|
||||
"""`provision` runs through `exec`; a provider whose provision step
|
||||
fetches anything would otherwise egress token-less and be denied."""
|
||||
|
||||
Reference in New Issue
Block a user