Per PR review feedback (review #132): guest_home shouldn't be
buried inside workspace_plan / read from a hardcoded literal in
each provision module. It's a cross-cutting bottle property — the
backend's prepare step knows it, and every downstream consumer
(contrib providers, git provisioning, gitconfig path) should
read it from one place.
- Adds guest_home: str to BottlePlan base dataclass.
- Both backends' prepare steps populate plan.guest_home.
- contrib/{claude,codex}/agent_provider.py read plan.guest_home
(was plan.workspace_plan.guest_home).
- bot_bottle/backend/docker/provision/git.py reads plan.guest_home
for the gitconfig destination (was hardcoded "/home/node").
- bot_bottle/backend/smolmachines/provision/git.py drops the
_GUEST_HOME / _guest_home() helpers and reads plan.guest_home.
- Tests that construct BottlePlan subclasses directly pass
guest_home="/home/node" explicitly.
Per PR review feedback (review #130): the GUEST_HOME = '/home/node'
default in agent_provider.py was driving the wrong direction —
the agent provider shouldn't ship its own opinion about the guest
home, the backend should.
- Removes the GUEST_HOME constant.
- Makes guest_home a required kwarg on AgentProvider.provision_plan
and the agent_provision_plan shim (no default).
- Drops module-level _SKILLS_DIR / _PROMPT_PATH constants from
contrib/{claude,codex}/agent_provider.py; both providers now
derive the in-guest paths from plan.workspace_plan.guest_home
at call time, which the backend's prepare step populated.
- Updates tests/unit/test_agent_provider.py callers to pass
guest_home explicitly. The backend prepare paths already pass
it; no production-code call sites changed.
Each AgentProvider now owns its skills / prompt / provision /
supervise_mcp end-to-end. The base ABC declares all four as
abstract; ClaudeAgentProvider and CodexAgentProvider each carry
their own copy loop.
Per PR review feedback (review #128): the shared
_provision_apply.py abstraction was weak — Claude and Codex
harnesses already diverge (codex's dummy-auth + login-status
verify has no claude analogue) and forcing both onto one helper
just postpones the split. Duplication is intentional.
Deletes bot_bottle/_provision_apply.py and consolidates testing
under tests/unit/test_contrib_{claude,codex}_provider.py (one
file per provider, covering all four methods).
- tests/unit/test_provision_apply.py covers the new shared
apply helpers (apply_skills / apply_prompt / apply_provision)
that replace the per-backend modules deleted in the prior
commit.
- tests/unit/test_contrib_supervise_mcp.py covers both providers'
provision_supervise_mcp behavior — confirms the codex bottle
now runs `codex mcp add` symmetrically with claude.
- tests/unit/test_smolmachines_provision.py drops the four test
classes whose subjects moved (TestProvisionPrompt /
TestProvisionProviderAuth / TestProvisionSkills /
TestProvisionSupervise); the backend-side CA / git / workspace
classes stay.
- tests/unit/test_docker_provision_provider_auth.py removed; its
coverage now lives in tests/unit/test_provision_apply.py
(apply_provision is backend-agnostic, one test file suffices).
Drops the BOT_BOTTLE_CONTAINER_HOME, BOT_BOTTLE_GUEST_HOME,
BOT_BOTTLE_CONTAINER_SKILLS_DIR, and BOT_BOTTLE_GUEST_SKILLS_DIR
env knobs the deleted provision modules used to read. /home/node
is hardcoded everywhere the knobs lived; the values were
effectively constants today and removing them keeps the PRD-0050
surface area honest.
Flips PRD 0050 Status: Draft → Active. Closes#177 on merge.
BottleBackend.provision now resolves the provider plugin from the
plan and dispatches prompt / skills / declarative-apply /
supervise-mcp through it. The four hooks the docker + smolmachines
backends used to override (provision_skills, provision_prompt,
provision_provider_auth, provision_supervise) are gone — the
duplicated 50-line implementations under
backend/{docker,smolmachines}/provision/{skills,prompt,
provider_auth,supervise}.py are deleted.
Each backend gains a small supervise_mcp_url(plan) override so the
provider plugin can run `claude mcp add` / `codex mcp add`
against the right URL: docker returns
http://{SUPERVISE_HOSTNAME}:{SUPERVISE_PORT}/ on the compose
network alias; smolmachines returns plan.agent_supervise_url which
launch.py already pins to a host-loopback port.
Removes tests/unit/test_provision_supervise.py — the URL it
asserted on now lives on the backend, with no equivalent
standalone surface to test against (it's covered by the broader
plan / launch integration tests).
Lift the provider-specific blocks of agent_provision_plan into
contrib/claude/agent_provider.py and contrib/codex/agent_provider.py,
behind a new AgentProvider ABC and a lazy get_provider() registry
(mirrors PRD 0048's contrib convention).
agent_provision_plan and runtime_for stay as thin shims so existing
callers in backend/{docker,smolmachines}/prepare.py and cli/start.py
keep working without per-call edits — the shipping diff in this commit
is purely 'who owns the producer'.
Adds bot_bottle/_provision_apply.py — the backend-agnostic
skills / prompt / declarative-plan apply loops the per-provider
default methods will dispatch through in the next commit.