Question
How should ensure_tools (devlaunch/tools.py) behave when the container image already carries the lent tools — and how do we make that path trustworthy — so a prebuilt image genuinely skips the ~342MB transfer?
Current facts (verified on main at f03158b):
- The probe (
_probe, tools.py:344-359) is one devpod ssh --command "bash -lc 'command -v gh && command -v claude'" — so an image with both tools on the login-shell PATH already skips the transfer today. That half of the candidate is done.
- But the probe cannot tell a real
claude from claude-shim — and the repo's own devcontainer feature installs the shim (.devcontainer/claude-code/install.sh:107, "Claude binary will be downloaded on first run"). An image baking the shim passes the probe and the user pays the ~285MB GCS download at first run — exactly the cost the lending exists to avoid.
- The payload is all-or-nothing (
host_payload, tools.py:256-274): an image with only gh still receives both binaries.
- No version awareness: an image with an ancient
claude is left alone forever; no checksum/marker exists despite CHANGELOG.md:69 claiming "checksum-verified".
- When the transfer runs it prepends
$HOME/.local/bin to PATH (tools.py:291-293), shadowing image-provided tools on later launches.
- Only opt-out is
DEVLAUNCH_NO_TOOLS (machine-wide).
Decide, against the principles (maintainability > simplicity):
- Should the probe distinguish a shim/stale tool from a usable one — and by what test (e.g.
claude --version exit + output shape vs a marker file vs accepting the shim)?
- Should the payload become per-tool instead of all-or-nothing?
- Is version-drift (image has old tool, host has new) in scope, or explicitly accepted and documented?
- What does the README/CHANGELOG say afterwards (README.md:294-299 is stale — still describes pixi-global install)?
The resolution must state how each accepted behavior will be tested (probe-script unit tests exist at test level today; extend the same seam). Any code change graduates as build ticket(s) on this map — this ticket only decides.
Question
How should
ensure_tools(devlaunch/tools.py) behave when the container image already carries the lent tools — and how do we make that path trustworthy — so a prebuilt image genuinely skips the ~342MB transfer?Current facts (verified on main at f03158b):
_probe, tools.py:344-359) is onedevpod ssh --command "bash -lc 'command -v gh && command -v claude'"— so an image with both tools on the login-shell PATH already skips the transfer today. That half of the candidate is done.claudefromclaude-shim— and the repo's own devcontainer feature installs the shim (.devcontainer/claude-code/install.sh:107, "Claude binary will be downloaded on first run"). An image baking the shim passes the probe and the user pays the ~285MB GCS download at first run — exactly the cost the lending exists to avoid.host_payload, tools.py:256-274): an image with onlyghstill receives both binaries.claudeis left alone forever; no checksum/marker exists despite CHANGELOG.md:69 claiming "checksum-verified".$HOME/.local/binto PATH (tools.py:291-293), shadowing image-provided tools on later launches.DEVLAUNCH_NO_TOOLS(machine-wide).Decide, against the principles (maintainability > simplicity):
claude --versionexit + output shape vs a marker file vs accepting the shim)?The resolution must state how each accepted behavior will be tested (probe-script unit tests exist at test level today; extend the same seam). Any code change graduates as build ticket(s) on this map — this ticket only decides.