Smoke-test agent images after build, add start --no-cache #354
Open
didericis-claude
wants to merge 3 commits from
post-build-image-smoke-test into main
pull from: post-build-image-smoke-test
merge into: didericis:main
didericis:main
didericis:orchestrator-cutover
didericis:orchestrator-agent-compose
didericis:orchestrator-gateway-ca
didericis:orchestrator-consolidated-launch
didericis:orchestrator-gateway-provision
didericis:orchestrator-gateway-network
didericis:orchestrator-client
didericis:orchestrator-gateway-net
didericis:orchestrator-gitgate-provision
didericis:orchestrator-registration
didericis:orchestrator-lifecycle
didericis:orchestrator-supervise-writers
didericis:orchestrator-supervise-multitenant
didericis:orchestrator-gitgate-multitenant
didericis:orchestrator-rename-gateway
didericis:orchestrator-slice8
didericis:orchestrator-slice7
didericis:orchestrator-slice6
didericis:prd-orchestrator
didericis:orchestrator-slice5
didericis:orchestrator-slice4
didericis:orchestrator-slice3
didericis:orchestrator-slice2
didericis:ci-kvm-runner
didericis:firecracker-backend
didericis:issue-330-cached-images
didericis:forge-native-integration
didericis:prd-smolmachines-linux
didericis:claude-forward-host-credentials
didericis:fold-orchestrator-subpackage
didericis:prd-egress-control-plane
didericis:manifest-break-import-cycle
didericis:dlp-supervise-quality-fixes
didericis:table-drive-dlp-tests
didericis:fix-integration-test-failures
didericis:fix/macos-container-relative-dockerfile
didericis:prd-0054-install-script
didericis:commit-bottle-state
didericis:pr-211
didericis:move-codex-auth-to-contrib
didericis:feat/pipelock-skip-scan-extensions
didericis:prd-0049-named-labelled-agents
didericis:harden-git-gate-shell-rendering
Dismiss Review
Are you sure you want to dismiss this review?
Labels
Clear labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Breaking change that won't be backward compatible
Something is not working
Documentation changes
Improve existing functionality
New functionality
This is security issue
Issue or pull request related to testing
Priority
Critical
1
The priority is critical
Priority
High
2
The priority is high
Priority
Low
4
The priority is low
Priority
Medium
3
The priority is medium
Reviewed
Confirmed
1
Issue has been confirmed
Reviewed
Duplicate
2
This issue or pull request already exists
Reviewed
Invalid
3
Invalid issue
Reviewed
Won't Fix
3
This issue won't be fixed
Status
Abandoned
3
Somebody has started to work on this but abandoned work
Status
Blocked
1
Something is blocking this issue or pull request
Status
Need More Info
2
Feedback is required to reproduce issue or to continue work
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: didericis/bot-bottle#354
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "post-build-image-smoke-test"
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?
Closes #353.
Summary
AgentProviderRuntime.smoke_test: an optional argv each provider can declare (claude:claude --version, codex:codex --version) that a fresh build must pass.verify_agent_image()to both the docker and macos-containerutilmodules: runs the smoke test in a throwaway container of the just-built agent image anddie()s with the command's own stderr if it fails, instead of shipping an image whose CLI is silently broken. Wired into all three launch paths (docker, macos-container, smolmachines) right after the agent image build, skipped when a committed image is reused.bot-bottle start --no-cache(alsoBOT_BOTTLE_NO_CACHE=1) to forcedocker build --no-cache/container build --no-cache, so a broken cached layer (like the one that caused #353) can be rebuilt from scratch without manually pruning image caches.Root cause recap
@anthropic-ai/claude-codeships its CLI as a native binary pulled via a platform-specificoptionalDependenciesentry. npm treats optional-dependency failures as non-fatal, so a transient fetch failure duringnpm install -gleft a 500-byte stubclaude.exein an image that still exited 0 — then that broken layer got cached indefinitely by BuildKit/Container's layer cache.Out of scope
bot_bottle/contrib/pi/Dockerfileinstalls with--ignore-scripts, which has a different (unverified) risk profile — not touched here.bfdbae804btoe862b82322@@ -113,1 +114,4 @@)docker_mod.verify_agent_image(plan.image, runtime_for(plan.agent_provider_template).smoke_test,)This requires spinning up a new container, just for the verification step?
@@ -113,1 +114,4 @@)docker_mod.verify_agent_image(plan.image, runtime_for(plan.agent_provider_template).smoke_test,)Yes — it runs
docker run --rmwith just the smoke-test argv (e.g.claude --version), so the container exits in under a second and is immediately removed. The overhead is intentional: the root bug was thatdocker buildexits 0 even when npm silently fails to install the optional binary, so the only reliable way to catch a broken image is to actually run it.@didericis-claude I think it's pretty rare to have a broken image/that only happened because a build got interrupted (ideally we'd be using cached images the majority of the time). Could we instead only have this run in a new "doctor" or "rebuild" command? I think an explicit "rebuild" command for agent images probably makes more sense. Push back/challenge whatever seems wrong and acknowledge what seems like good direction.
@@ -113,1 +114,4 @@)docker_mod.verify_agent_image(plan.image, runtime_for(plan.agent_provider_template).smoke_test,)Two things worth separating:
Agree: A
rebuildcommand is a good idea regardless — useful escape hatch when you want to force a fresh build without digging into--no-cacheflags. Worth adding.Push back on the framing: The root cause wasn't just an interrupted build. npm treats optional-dependency failures as non-fatal and exits 0, so a transient network hiccup during
npm install -gcan silently produce a broken binary on any build — then BuildKit caches that broken layer indefinitely. You wouldn't know until the agent tries to use its CLI. That's the exact failure mode in #353.Also: the verify already only runs in the fresh-build branch. When a committed image is reused (the common case), it's skipped entirely. Moving verification to a
doctor/rebuildcommand doesn't reduce per-launch overhead (there isn't any on cached launches) — it just shifts discovery from build time to first-real-use time, which is where we started.I'd keep the verify on build and add the
rebuildcommand on top.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.