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.
- 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.
Closes#178.
The backend provision functions now receive a Bottle handle with
exec / cp_in methods instead of a raw target string. Provisioner
modules use bottle.exec and bottle.cp_in in place of inlined
subprocess.run(["docker", "exec"/"cp", ...]) and direct
_smolvm.machine_cp / machine_exec calls. This decouples the
provisioners from backend-specific runtime primitives so future
refactors (e.g. the supervise rework) can swap the bottle's exec
implementation without touching every provisioner.
Each launch.py constructs the Bottle handle before calling
provision so it can be passed in; provision_prompt's return value
is wired back onto the bottle's prompt path attribute after the
fact.