You were right — workspace_plan was the only place guest_home lived, and reading it through plan.workspace_plan.guest_home was the wrong layer. Hoisted in 21a46b97d8f35734fa23165ee2b94d1268ddb8d3: guest_home: str is now a field on the base BottlePlan dataclass, populated by each backend's prepare step. The contrib providers, this gitconfig path, and the smolmachines _guest_home() helper all read plan.guest_home directly.
Done in b2dc5fd20bcbfbc5dcf0def096a3fd0cb447105c — GUEST_HOME is gone from agent_provider.py, guest_home is a required kwarg on provision_plan (no default), and the _SKILLS_DIR / _PROMPT_PATH constants in both contrib providers are gone too. The providers now derive in-guest paths from plan.workspace_plan.guest_home at call time, which the backend's prepare step populates.
Agreed — pushed ceb850655931dae87efe3c61dea16ef2cfa83372 which deletes _provision_apply.py entirely and inlines the skills / prompt / provision steps into each provider class. AgentProvider now declares all four methods (provision_skills, provision_prompt, provision, provision_supervise_mcp) as abstract; ClaudeAgentProvider and CodexAgentProvider each carry their own copy loop. Tests split into test_contrib_claude_provider.py and test_contrib_codex_provider.py.
Agreed — bot_bottle/contrib/ fits cleanly as the home for anything that is platform-specific rather than core: deploy-key provisioners per forge, agent provisioners per runtime, etc. The core…