Design a workspace-porting abstraction for bottle start #116
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
bot-bottle has several backend-specific assumptions about where the operator's current workspace lands inside a bottle. Docker
--cwdlayering copies the host cwd into/home/node/workspaceand sets that as the image workdir; smolmachines currently copies.gitinto<guest_home>/workspace/.git; provider setup has started to need path-specific trust/auth state as well.Those details are currently scattered across image build, git provisioning, provider provisioning, and agent launch behavior. That makes it too easy for a provider-specific fix to encode another one-off
/workspaceassumption instead of using a coherent "current workspace in the bottle" contract.Desired outcome
Design a backend-neutral abstraction for porting the current workspace into a bottle at start time, including:
--cwdcontent and.gitstate are copied or mountedNotes
This is design work first. Avoid additional provider-specific workspace-path changes in PRD 0029 until this abstraction is settled.
Design sketch after reading the current Docker/smolmachines paths:
Proposed abstraction:
WorkspacePlanIntroduce a backend-neutral workspace plan resolved during
prepare, then let each backend implement the transport details during launch/provisioning.BottleSpecshould keep the user intent (copy_cwd,user_cwd).BottlePlanshould carry the resolvedworkspace_planso all later code uses one contract instead of re-readingspec.copy_cwdand spelling/home/node/workspaceagain.Relevant current hard-coded sites:
/home/node/workspace, patches Claude trust, and setsWORKDIRinbot_bottle/backend/docker/util.py..gitto/home/node/workspace/.gitinbot_bottle/backend/docker/provision/git.py.<guest_home>/workspace/.gitinbot_bottle/backend/smolmachines/provision/git.py.guest_home, not the copied workspace, inbot_bottle/agent_provider.py.Contract
When
--cwdis enabled:workspace_plan.guest_path, defaulting to/home/node/workspace.workspace_plan.workdiras its working directory.node:nodeand writable bynode..gitdirectory, the guest workspace has the equivalent.gitat<guest_path>/.gitbefore the agent is attached.workspace_plan.guest_path, not for an independently chosen path.When
--cwdis disabled:workspace_plan.enabled == False.workspace_plan.workdirfalls back to the provider guest home, currently/home/node..gitcopy occurs.This keeps
/home/node/workspaceas the default path, but makes it a resolved value rather than a convention each subsystem rediscoveres.Implementation shape
Add a small module, probably
bot_bottle/workspace.py, with:WorkspacePlanworkspace_plan(spec, guest_home) -> WorkspacePlanAdd
workspace_plan: WorkspacePlantoBottlePlanor to both concrete plans. I preferBottlePlanbecause the contract is backend-neutral and provider logic should be able to depend on it.Resolve it in each backend
prepareusing that backend's guest home override:BOT_BOTTLE_CONTAINER_HOME, default/home/nodeBOT_BOTTLE_GUEST_HOME, default/home/nodeChange provider provisioning to accept the workspace path:
agent_provision_plan(..., trusted_project_path: str = guest_home)or pass the fullWorkspacePlanif that does not create an awkward dependency.[projects."<trusted_project_path>"]instead of always[projects."<guest_home>"].build_image_with_cwdand into provider provisioning, or make the Docker image build receiveworkspace_plan.guest_path. Moving it into provider provisioning is cleaner because smolmachines then gets the same trust behavior.Replace backend-specific
.gitcopy helpers with workspace-aware helpers:docker cpto copy.gitinto{workspace_plan.guest_path}/.git, thenchown -R node:nodeon the copied.gitor the whole workspace if needed.machine cpandmachine_exec, but targets the sameworkspace_plan.guest_path.workspace_plan.enabled and workspace_plan.has_host_git_dir.Backend transport:
workspace_plan.host_path,COPY --chown=node:node . {workspace_plan.guest_path},WORKDIR {workspace_plan.workdir}..git; that means the desired logical parity is not actually met unless the packed image already contains the cwd content through some other path.Suggested tests
workspace_plan()for enabled/disabled, guest-home override, relative/absolute host cwd, and.gitdetection.workspace_plan.guest_pathandworkspace_plan.workdirinstead of hard-coded/home/node/workspace.--cwdis enabled and home when disabled.workspace_plan.guest_path..git, are copied.Non-goals for the first PRD
gitentries./home/node/workspaceas the default resolved path.The main decision to make before implementation is whether smolmachines should copy full workspace contents now. If the desired outcome is true Docker/smolmachines parity for
--cwd, I think yes: copying only.gitgives the agent repository metadata without the working tree, which is not the same logical workspace behavior as Docker.