Skip to content

acq: make oci-engine an opt-in catalog kit and retire the adapter OCI auto-install #505

Description

@mogul

Context

Per ADR-0030, rootless-podman OCI provisioning moves OUT of the msb backend adapter and INTO a neutral patterns kit (integrations/isolation/acq-kits/oci-engine/). The kit shipped in agentic-coding-patterns v1.10.0 (2dd2ad6ad5f63b842d732424bed5ba9aebeed676) and declares schemaVersion: "hybrid/v1", kind: mixin, name: oci-engine. This issue tracks the quickstart-side work to complete that migration.

Rewritten 2026-10-02. The original plan called for a bespoke ACQ_ENABLE_OCI_KIT environment gate. That design is superseded: #500 landed the generic opt-in kit catalog and acq configure, so oci-engine should be a catalog entry like any other kit — not a special case acq knows about by name. See "Superseded design" below for what NOT to build.

Blocked on / sequencing

Blocked on #474 merging. main currently pins
agentic-coding-patterns v1.9.0 (6c6753c60a2b24322fb2e8c0d8e8af60c56ede8f), whose
integrations/isolation/acq-kits/ contains only openchamber and paseo — there is no
oci-engine directory at that ref
. The kit first appears in v1.10.0
(2dd2ad6ad5f63b842d732424bed5ba9aebeed676), and the pin bump to v1.10.0 lands in
#474.

This matters because _acq_apply_configured_extra_kits validates a configured kit name only
against the local ACQ_OPTIN_KIT_NAMES array; it does not verify the name resolves at the
pinned ref. So adding oci-engine to the catalog while the pin is still v1.9.0 would let
acq configure offer a kit whose ref points at a non-existent directory, and the adapter's
kit fetch (_acq_msb_fetch_kit) aborts the create with exit 1 rather than skipping it.

Trigger to start this work: #474 merges (carrying the
v1.10.0 pin). Do not add the catalog entry on a branch cut from a v1.9.0-pinned main, and do
not duplicate the pin bump here — it would conflict with #474.

Within this issue, keep step 1 (add the catalog entry) before step 2 (retire the adapter
auto-install) so there is never a window where neither path provides an OCI engine.

Current state

  • acq.backends/msb.sh auto-installs podman itself: _acq_msb_ensure_oci (≈200 lines) is called from acq_backend_provision, gated on ACQ_MSB_ENSURE_OCI, which defaults to on. _acq_msb_grant_oci_devs re-grants /dev/net/tun + /dev/fuse on provision AND on acq_backend_start (/dev is a devtmpfs re-created each boot).
  • sbx has no OCI path at all, so the two backends are asymmetric today: msb sandboxes get podman unasked, sbx sandboxes never do.
  • The generic opt-in machinery now exists on main (ADR-0031): ACQ_OPTIN_KIT_NAMES / ACQ_OPTIN_KIT_DESCS, _acq_optin_kit_ref, _acq_apply_configured_extra_kits (reads config.yaml extra_kits:), acq_configure, and create_time_kit_picker. Catalog selections flow through ACQ_EXTRA_KITS → _build_kit_list → acq_cli_kits_write, so they are durable across shells and re-applied on resume.

Work

1. Add oci-engine to the opt-in kit catalog

Append oci-engine to ACQ_OPTIN_KIT_NAMES and a matching one-line description to ACQ_OPTIN_KIT_DESCS in acq.backends/common.sh. That is the whole selection mechanism — no OCI-specific ref builder, readiness probe, cache, or env gate. The kit becomes selectable via a single keystroke in acq configure and in the create-time picker, and is persisted per-sandbox by the existing kit-record path.

Requires the built-in patterns pin to be at v1.10.0 or later, since _acq_optin_kit_ref builds refs from PATTERNS_KIT_REF and _acq_apply_configured_extra_kits fails closed on a kit name that does not resolve. The pin bump lands in #474.

Per the catalog-membership rule recorded in ADR-0031 (prime-agent is omitted because it is a skeleton at the current pin), a catalog entry must be functional at the pinned ref. oci-engine at v1.10.0 qualifies.

2. Retire the adapter's OCI auto-install (BREAKING)

Remove _acq_msb_ensure_oci, _acq_msb_grant_oci_devs, ACQ_MSB_ENSURE_OCI, ACQ_MSB_PODMAN_PKGS, and all call sites (provision, acq_backend_start, and the prereq/diagnostic paths that reference them). The kit performs install + device-grant declaratively, for both backends.

This is a breaking change and must be committed as such (feat!: or a BREAKING CHANGE: footer) with a release note: an OCI engine is no longer provisioned by default. Users who rely on docker run / docker compose inside a sandbox must opt into the oci-engine kit via acq configure (or ACQ_EXTRA_KITS / --kit).

Two behavioral notes that make the kit the better path, worth stating in the commit body:

  • The kit's startup script is gated on podman being present and revokes a stale device grant when the engine is absent. The adapter's _acq_msb_grant_oci_devs grants /dev/net/tun + /dev/fuse unconditionally, so retiring it narrows device exposure.
  • The kit applies identically on sbx and msb, ending the current asymmetry.

Sequence step 2 after step 1 so there is never a window with neither path active.

3. Update scripts/verify-backends

_verify_oci_checks currently proves acq's auto-installed podman on msb. Repoint it at the kit path (provision with the oci-engine kit selected) and drop the ACQ_MSB_ENSURE_OCI skip branch once the auto-install is gone. The patterns kit's own scripts/verify already exercises the kit on msb via acq.

4. Docs

  • docs/BACKEND_GUIDE.md — remove the ACQ_MSB_ENSURE_OCI / ACQ_MSB_PODMAN_PKGS env rows and rewrite the "Running OCI images inside the sandbox (podman)" section around the opt-in kit.
  • docs/CONCEPTS.md — describe OCI as a catalog kit chosen through acq configure, not as an advanced env-var toggle.
  • ADR-0020 (msb oci engine via podman) — supersede it, or add a status note pointing at ADR-0030 and ADR-0031: the podman-over-dind and rootless decisions still hold, but the mechanism and the default both changed.

Verification

  • acq configure offers oci-engine; selecting it writes extra_kits: to config.yaml; a subsequent acq create applies the kit; acq start in a fresh shell still re-applies it (the round-trip through acq_cli_kits_write / acq_cli_kits_load).
  • With the kit not selected, no podman is installed and no device grant occurs on either backend.
  • With the kit selected on msb: rootless podman works, docker resolves to podman, and /dev/net/tun + /dev/fuse are group-scoped to the agent after a stop/start cycle.
  • The patterns kit's own scripts/verify passes against a build of acq with the auto-install removed.
  • Full offline suite green. ACQ_BUILTIN_KIT_COUNT assertions should remain at 4 — a catalog kit lands after the built-in block and must not inflate the built-in count.

Superseded design — do NOT build this

The original version of this issue specified a bespoke ACQ_ENABLE_OCI_KIT env gate with a dedicated _acq_oci_engine_kit_ref, an acq_oci_engine_kit_ready validation probe, a readiness cache, a "kit not available, falling back to adapter" notice, and an adapter-side _oci_kit_selected suppression flag keyed on the exact OCI kit ref. That makes oci-engine a kit acq knows about by name, which is the opposite of the goal. The generic catalog supersedes it on every axis — discoverability, durability across shells, resume behavior, per-sandbox deviation, and lines of code in acq.

Refs

  • ADR-0030 (agent kits on a devenv base) — the decision moving OCI provisioning into a kit
  • ADR-0031 (interactive acq configure) — the generic opt-in catalog this now rides on
  • ADR-0020 (msb OCI engine via podman) — the adapter-era decision to supersede
  • agentic-coding-patterns integrations/isolation/acq-kits/oci-engine/ and its docs/decisions/

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmaintenanceissues for attention to maintenance rotation

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions