feat: bake the orchestrator into the outer image#58
Merged
Conversation
…install)
The published outer image carried only the runtime; the orchestrator (.sandcastle/*.ts)
still had to be vendored into every adopting repo, and run.sh ran `npm install` on
every launch. Bake the orchestrator SOURCE into /opt/agentic-orchestrator so adopters
run without vendoring, and install deps once per container instead of per run (ADR-0016).
Key constraints handled:
- The workspace bind mount shadows anything baked at the workspace path → bake at
the non-mounted /opt.
- The image is public → clone the COMMITTED code at build time (Dockerfile, git
fetch AGENTIC_REF) rather than COPY the build context, so gitignored secrets
(.sandcastle/.env, orchestrator.env) can never be baked. Verified: secrets absent
from the built image.
- node comes from a devcontainer feature (after the Dockerfile), so npm ci can't run
at build time → ship source only; run.sh installs into /opt (chowned vscode) on
first use. (Confirmed `devcontainer build` does NOT bake onCreateCommand.)
run.sh / afk resolve the orchestrator: prefer the workspace copy when it has the
source (dogfood / vendored adopters → local edits win), else fall back to the baked
/opt (override via AGENTIC_ORCHESTRATOR_HOME). afk also locates a project by its
.devcontainer/ so a non-vendoring adopter is found. The orchestrator always runs with
cwd = the project, so config/worktrees/identity resolve against the target repo.
The bake is build-arg-gated (BAKE_ORCHESTRATOR), so the compose/runtime build stays
lean and the dogfood is untouched. CI passes AGENTIC_REF=${github.sha} via
devcontainer.build.json so the image bakes the exact built commit.
Validated locally: built the dist image; /opt has the source, no secrets, owned by
vscode; a non-vendoring project resolves afk → baked run.sh. 108 tests pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes the published outer image actually deliver the orchestrator, so adopters can run without vendoring
.sandcastle/*.ts— and stopsrun.shreinstalling deps on every launch (ADR-0016).What
/opt/agentic-orchestratorin the published image; adopters keep only their config in.sandcastle/(orchestrator.env,.env,opencode.json).run.sh/afkresolution: prefer the workspace.sandcastle/when it carries the source (dogfood / vendored adopters → local edits win), else fall back to the baked copy (AGENTIC_ORCHESTRATOR_HOMEoverrides).afkalso locates a project by its.devcontainer/.npm install— guard on a missing/stale lockfile (Part A; helps all tiers). Baked copy installs into/optonce per container.Three traps handled (each verified)
/opt..sandcastle/.env/orchestrator.env. Instead the Dockerfile git-fetches the committed code atAGENTIC_REF. ✅ Verified secrets are absent from the built image.npm cican't run there (confirmeddevcontainer builddoes not bakeonCreateCommand). Ship source only; install on first use into a vscode-owned/opt.The bake is build-arg-gated (
BAKE_ORCHESTRATOR), so the compose/runtime build stays lean and the dogfood is untouched. CI passesAGENTIC_REF=${{ github.sha }}so the image bakes the exact built commit.Validation (local, real built image)
/opt/agentic-orchestratorhas the source, no.env/orchestrator.env, ownedvscode:vscode,node_modulesabsent (installed on first use)..devcontainer/+ config only) resolvesafk→/opt/agentic-orchestrator/run.sh.Note / follow-up
First run does one
npm installinto/opt(not fully offline-from-boot). If that matters, bakenode_modulesper-arch via a secondFROM <devcontainer-image>build stage — deferred (adds multi-arch build cost); noted in ADR-0016.🤖 Generated with Claude Code