refactor: hoist plan fields and print to BottlePlan base class (PRD 0044)

Move git_gate_plan, egress_plan, supervise_plan, and agent_provision
from DockerBottlePlan and SmolmachinesBottlePlan into BottlePlan.
Replace the abstract print method with a single concrete implementation
that renders git gate entries as "name → upstream_host:upstream_port"
and egress routes with conditional "[auth:scheme]" annotations.
This commit is contained in:
2026-06-02 16:08:20 +00:00
committed by didericis
parent 71ac555f25
commit 53219a55e1
3 changed files with 59 additions and 125 deletions
+5 -68
View File
@@ -2,30 +2,25 @@
Carries the Docker-specific resolved fields produced by
DockerBottleBackend.prepare. The launch step consumes it without
further resolution; show_plan-style rendering is the `print` method.
further resolution; preflight rendering is inherited from BottlePlan.
"""
from __future__ import annotations
import sys
from dataclasses import dataclass, field
from pathlib import Path
from ...agent_provider import AgentProvisionPlan, PromptMode
from ...egress import EgressPlan
from ...git_gate import GitGatePlan
from ...log import info
from ...agent_provider import PromptMode
from ...pipelock import PipelockProxyPlan
from ...supervise import SupervisePlan
from .. import BottlePlan
from ..print_util import print_multi, visible_agent_env_names
@dataclass(frozen=True)
class DockerBottlePlan(BottlePlan):
"""Docker-specific resolved fields produced by
DockerBottleBackend.prepare. Inherits `spec` and `stage_dir` from
BottlePlan."""
DockerBottleBackend.prepare. Inherits `spec`, `stage_dir`,
`git_gate_plan`, `egress_plan`, `supervise_plan`, and
`agent_provision` from BottlePlan."""
slug: str
container_name: str
@@ -46,13 +41,7 @@ class DockerBottlePlan(BottlePlan):
forwarded_env: dict[str, str] = field(repr=False)
prompt_file: Path
proxy_plan: PipelockProxyPlan
git_gate_plan: GitGatePlan
egress_plan: EgressPlan
# None when bottle.supervise is False. PRD 0013 supervise sidecar
# is opt-in via the manifest's bottle.supervise field.
supervise_plan: SupervisePlan | None
use_runsc: bool
agent_provision: AgentProvisionPlan
@property
def agent_command(self) -> str:
@@ -65,55 +54,3 @@ class DockerBottlePlan(BottlePlan):
@property
def agent_provider_template(self) -> str:
return self.agent_provision.template
def print(self, *, remote_control: bool) -> None:
"""Render the y/N preflight summary to stderr — compact form
intended to fit on screen without scrolling. The full
structured shape (image, container, runtime, etc.) lives on
this dataclass for tooling that wants to introspect it."""
del remote_control # not surfaced in the compact summary
spec = self.spec
manifest = spec.manifest
agent = manifest.agents[spec.agent_name]
bottle = manifest.bottle_for(spec.agent_name)
# The agent sees the union of literal env names (rendered into
# --env-file) and forwarded env names (`-e NAME` with the
# value arriving via subprocess env). The forwarded set holds
# the OAuth token (CLAUDE_CODE_OAUTH_TOKEN) and any host-env
# interpolations from the manifest; egress holds
# upstream tokens in its own environ, so no token forwarding
# from the agent to the proxy is needed.
env_names = visible_agent_env_names(
sorted(
set(bottle.env.keys())
| set(self.forwarded_env.keys())
| set(self.agent_provision.guest_env.keys())
),
hidden_env_names=self.agent_provision.hidden_env_names,
)
print(file=sys.stderr)
info(f"agent : {spec.agent_name}")
info(f"provider : {self.agent_provider_template}")
print_multi("env ", env_names)
print_multi("skills ", list(agent.skills))
info(f"bottle : {agent.bottle}")
identity = manifest.git_identity_summary(spec.agent_name)
if identity:
info(f" git identity : {identity}")
git_lines = [
f"{u.upstream_host}:{u.upstream_port}"
for u in self.git_gate_plan.upstreams
]
if git_lines:
print_multi(" git gate ", git_lines)
if self.egress_plan.routes:
egress_lines = []
for r in self.egress_plan.routes:
auth = f" [auth:{r.auth_scheme}]" if r.auth_scheme else ""
egress_lines.append(f"{r.host}{auth}")
print_multi(" egress ", egress_lines)
print(file=sys.stderr)