Skip to content

feat(msb): derive default sandbox-template image from agent token - #409

Open
mogul wants to merge 1 commit into
mainfrom
plan/msb-image-selection-third-param
Open

feat(msb): derive default sandbox-template image from agent token#409
mogul wants to merge 1 commit into
mainfrom
plan/msb-image-selection-third-param

Conversation

@mogul

@mogul mogul commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Context

AI-assisted change.

When acq provisions through the msb backend and the user does not set an image, msb always used docker.io/docker/sandbox-templates:shell-docker. That differs from sbx, where sbx run opencode . uses docker.io/docker/sandbox-templates:opencode-docker — which bakes in the agent binary and significantly shortens startup. This PR brings the msb path to parity.

Fixes #404. Also does the enabling cleanup from #377 (single-sourcing the agent list). prime-agent is not added here.

What changed

  • Agent-derived default image (msb): when no explicit image override is set, msb derives docker.io/docker/sandbox-templates:<agent>-docker for known agents (shellshell-docker), matching sbx's template naming. Precedence: ACQ_MSB_IMAGE > --image/ACQ_IMAGE > agent-derived default > shell-docker fallback.
  • Fallback only on not-found: on msb create failure, msb retries once with shell-docker only when the image was agent-derived, the error is registry not-found, and no sandbox was created. Auth/network failures and explicit image overrides never fall back silently. The not-found classifier was live-verified against msb (Docker Hub + ghcr.io both return manifest unknown).
  • Single-source agent catalog (Single-source the agent list (KNOWN_AGENTS dup + 4 case statements + 3 docs) #377): new acq.backends/agents.sh holds ACQ_KNOWN_AGENTS, acq_is_known_agent, acq_agent_template_image, and the msb install-recipe check. Both adapters source it; the duplicated KNOWN_AGENTS definitions and parallel is_known_agent case statements are removed. New test/bats/36-agent-catalog.bats enforces catalog/adapter parity and that the list lives only in the shared file.
  • Docs/ADRs: BACKEND_GUIDE.md, ADR-0022, ADR-0011 updated for the derived default + fallback; howto/msb.md and howto/sbx.md agent lists corrected and pointed at agents.sh.

Verification

scripts/test-acq-bats (full)                              376 ok, 0 not ok
scripts/test-acq-bats test/bats/35-image-override.bats     22 ok, 0 not ok
scripts/test-acq-bats test/bats/36-agent-catalog.bats       5 ok, 0 not ok
classifier probe vs real msb stderr    manifest unknown -> fallback; unauthorized -> no fallback
shellcheck --severity=warning (acq + backends + tests)    clean
markdownlint (touched docs)                               0 issues

Live msb probe (host with a sandbox-capable runtime), confirming the classifier wording:

$ msb create ... docker.io/docker/sandbox-templates:definitely-not-a-real-tag-xyz
error: image error: registry error: ... [OCI API error: manifest unknown]   rc=1
$ msb create ... ghcr.io/gsa-tts/definitely-private-nonexistent:v1
error: image error: registry error: ... [OCI API error: manifest unknown]   rc=1

Rollback

Revert this commit; no state migration. Behavior returns to always using shell-docker on msb.

Security impact

None. No change to auth, secrets, or egress. The image name is derived from a charset-validated known-agent token; unknown/unsafe tokens fall back to shell-docker. Explicit-image failures are never masked.

When no explicit image override is set, the msb backend now derives the
sbx agent-template image name from the requested agent
(docker.io/docker/sandbox-templates:<agent>-docker), matching how
`sbx run <agent>` selects its template, and falls back to
shell-docker only if the derived image is not found. This shortens
startup for agents like opencode whose template bakes in the binary.

Fallback is conservative and live-verified against msb: it triggers only
on registry not-found errors (manifest unknown) for an agent-derived
image, never on auth/network failures or explicit image overrides.

As the enabling cleanup, single-source the known-agent list into
acq.backends/agents.sh (shared by both adapters) so adding an agent no
longer means editing duplicated KNOWN_AGENTS lists and parallel case
statements. A new bats suite enforces catalog/adapter parity. prime-agent
is intentionally not added here.

Refs: #404
Refs: #377

Co-authored-by: OpenCode [claude_4_8_opus] <bret.mogilefsky@gsa.gov>
@mogul
mogul requested a review from a team as a code owner August 27, 2026 07:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

msb: derive default sandbox-template image from agent token

1 participant