You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(oci): extract rootless podman into optional OCI engine kit #483
Extract rootless podman provisioning out of backend-specific adapter behavior into an explicit optional OCI engine kit, as described in ADR-0030.
Parent: #473
ADR: #474
Related ADR: docs/adr/0020-msb-oci-engine-via-podman.md
Scope
Define an OCI engine kit that provides rootless podman or equivalent container-run capability.
Keep the OCI engine kit optional and out of the default built-in bundle.
Preserve the security decisions from ADR-0020: rootless operation, no docker-in-docker daemon lifecycle, explicit device/capability handling, and deterministic registry behavior.
Make the kit usable across backends where feasible.
Remove or reduce msb-adapter-owned podman provisioning only after the kit path is verified.
Deferred Decisions
Exact backend-specific translation can be deferred until implementation proves which pieces remain adapter-owned.
Whether a compatibility shim is needed during migration can be decided after live verification.
Acceptance Criteria
Sandboxes that do not request OCI do not pay the create-time install or egress cost.
Sandboxes that request OCI get a working rootless container engine.
Existing OCI verification still passes where the capability is requested.
Tests cover the requested and not-requested paths.
Orchestration Notes
Implementation should be done by an authoring sub-agent and reviewed by an independent adversarial review sub-agent. Review findings must be addressed before the increment is accepted.
Quickstart-side, opt-in (ACQ_ENABLE_OCI_KIT, off by default) selection of an oci-engine capability kit into the built-in bundle, gated on a readiness probe of the pinned patterns ref
This is the deliberately conservative "safer course" increment: selection + allowlisting + tests only. The patterns-side kit body is not published yet, so opting in currently falls back with a single notice and adds no ref. The msb adapter's active podman provisioning (_acq_msb_ensure_oci / ACQ_MSB_ENSURE_OCI) is untouched and remains the OCI mechanism until the kit path is live-verified.
What landed
ACQ_ENABLE_OCI_KIT env knob (normalized like ACQ_MSB_ENSURE_OCI), off by default.
oci-engine kit deliberately not added to ACQ_KIT_NAMES, so the default acq kit list set and provenance-bundle count are unchanged; selection is gated purely in _acq_selected_builtin_kit_refs.
acq_oci_engine_kit_ready readiness probe (fetch + spec.yaml validation), memoized per process (ACQ_OCI_KIT_READY_CACHE) so at most one network fetch runs per invocation.
Single fallback notice, emitted once per process from _build_kit_list via a process-global guard (_ACQ_OCI_KIT_NOTICE_SHOWN), mirroring the sbx recreate-notice guard.
Offline test coverage (test/bats/66-oci-engine-kit.bats): default-off, no ACQ_KIT_NAMES pollution, opted-in-not-ready (no ref + exactly-once notice across a 2× _build_kit_list lifecycle), opted-in-ready ordering, real readiness validation (well-formed / wrong-name / wrong-kind), ref shape/allowlist, env normalization.
docs/CONCEPTS.md documents the opt-in, its off-by-default gating, and that the msb adapter remains the active mechanism today.
Verification: full offline bats suite green (581/581 after merging current main), bash -n clean on all adapters, focused ShellCheck clean, git diff --check clean, npm run lint:md clean. Live verify-backends not run (requires a sandbox-capable host).
Deferred (dependency-blocked on the patterns-side kit publishing) — tracked here so it is not lost
Patterns-side oci-engine kit body. The neutral rootless-podman capability kit (schema hybrid/v1, kind: mixin, name: oci-engine) does not exist in agentic-coding-patterns/integrations/isolation/acq-kits/ yet. A patterns PR is the trigger that flips acq_oci_engine_kit_ready to true. Until then this quickstart selection is inert-by-design.
sbx forced-heal wiring (the hardcoded-4 boundary). The sbx forced-heal refresh loop (acq.backends/sbx.sh, [ "$_idx" -le 4 ]) hardcodes the support-kit count and treats index ≥5 as an agent kit. When the oci-engine kit lands at index 5 it would be re-added but mislabeled, and — if the kit declares setup.startup — an sbx-0.38-class kit add refusal (rc=3) would stall provenance and cause perpetual stale-refresh offers. Before the patterns kit ships: derive the support-kit boundary instead of hardcoding 4, classify the oci kit as a support (not agent) kit, and give it the same feature-probe/label treatment as git-ssh-sign.
msb OCI double-provisioning sequencing. Once the kit publishes and a user opts in on msb, both the kit and _acq_msb_ensure_oci would install/alias podman. Sequence-disable ACQ_MSB_ENSURE_OCI when the oci-engine kit is selected (do not remove the adapter path until the kit is live-verified per this issue's acceptance criteria).
Trigger for items 2 and 3: the patterns oci-engine kit becoming available at the pinned ref (item 1).
New neutral hybrid/v1 mixin at integrations/isolation/acq-kits/oci-engine/ (schemaVersion: "hybrid/v1", kind: mixin, name: oci-engine — exactly what the quickstart readiness probe requires).
Ports the msb adapter's rootless-podman provisioning into the neutral vocabulary, preserving the ADR-0020 posture (rootless, daemonless, minimal device grants, Docker-Hub-first with short-name-mode=enforcing).
Written by an authoring agent, then run through the same independent adversarial review used on the quickstart side. Three findings fixed before the PR: a blocker where set -eu + bare package-manager calls defeated the documented fail-soft (would have failed sbx create); a dropped rootless vfs recovery step vs. the reference; and a verify script that could pass on a rootful engine. All fixed; a docs/decisions/ note records the port.
CI green (validate-kits --strict, acq-kits tests, pattern validation, python lint/test, markdown/link/commit-title). The live scripts/verify is host-only and skipped in CI, like the zscaler kit.
This unblocks the deferred items filed earlier on this issue
Once #437 merges and the quickstart side pins the new patterns ref, the readiness gate flips true and these become actionable (previously dependency-blocked on this kit):
sbx forced-heal wiring (the hardcoded-4 boundary) — derive the support-kit boundary, classify the oci-engine kit as a support (not agent) kit, and give it the same feature-probe/label treatment as git-ssh-sign before the kit goes live, to avoid the rc=3 provenance-stall risk.
msb OCI double-provisioning sequencing — sequence-disable ACQ_MSB_ENSURE_OCI when the oci-engine kit is selected, so the kit and the adapter don't both install/alias podman. (Do not remove the adapter path until the kit is live-verified per this issue's acceptance criteria.)
Trigger for both: #437 merging and the quickstart pin bump.
Implemented and shipped in v4.0.0 via #474 (with corrective #549). Rootless podman moved to the opt-in oci-engine kit; adapter-owned MSB OCI auto-install (ACQ_MSB_ENSURE_OCI) removed. The PR's Closes: footer did not auto-close this because the collapsed-stack squash merge dropped the closing keyword references; closing manually now that the work is on main and released.
Activity
mogul commentedon Sep 21, 2026
Quickstart-side progress update (increment 1 of N)
Landed on
refactor/acq-devenv-base-image:d946f27 feat(oci): add opt-in OCI-engine capability kit selectionACQ_ENABLE_OCI_KIT, off by default) selection of anoci-enginecapability kit into the built-in bundle, gated on a readiness probe of the pinned patterns refThis is the deliberately conservative "safer course" increment: selection + allowlisting + tests only. The patterns-side kit body is not published yet, so opting in currently falls back with a single notice and adds no ref. The msb adapter's active podman provisioning (
_acq_msb_ensure_oci/ACQ_MSB_ENSURE_OCI) is untouched and remains the OCI mechanism until the kit path is live-verified.What landed
ACQ_ENABLE_OCI_KITenv knob (normalized likeACQ_MSB_ENSURE_OCI), off by default.oci-enginekit deliberately not added toACQ_KIT_NAMES, so the defaultacq kit listset and provenance-bundle count are unchanged; selection is gated purely in_acq_selected_builtin_kit_refs.acq_oci_engine_kit_readyreadiness probe (fetch +spec.yamlvalidation), memoized per process (ACQ_OCI_KIT_READY_CACHE) so at most one network fetch runs per invocation._build_kit_listvia a process-global guard (_ACQ_OCI_KIT_NOTICE_SHOWN), mirroring the sbx recreate-notice guard.test/bats/66-oci-engine-kit.bats): default-off, noACQ_KIT_NAMESpollution, opted-in-not-ready (no ref + exactly-once notice across a 2×_build_kit_listlifecycle), opted-in-ready ordering, real readiness validation (well-formed / wrong-name / wrong-kind), ref shape/allowlist, env normalization.docs/CONCEPTS.mddocuments the opt-in, its off-by-default gating, and that the msb adapter remains the active mechanism today.Verification: full offline bats suite green (581/581 after merging current
main),bash -nclean on all adapters, focused ShellCheck clean,git diff --checkclean,npm run lint:mdclean. Liveverify-backendsnot run (requires a sandbox-capable host).Deferred (dependency-blocked on the patterns-side kit publishing) — tracked here so it is not lost
oci-enginekit body. The neutral rootless-podman capability kit (schemahybrid/v1,kind: mixin,name: oci-engine) does not exist inagentic-coding-patterns/integrations/isolation/acq-kits/yet. A patterns PR is the trigger that flipsacq_oci_engine_kit_readyto true. Until then this quickstart selection is inert-by-design.4boundary). The sbx forced-heal refresh loop (acq.backends/sbx.sh,[ "$_idx" -le 4 ]) hardcodes the support-kit count and treats index ≥5 as an agent kit. When the oci-engine kit lands at index 5 it would be re-added but mislabeled, and — if the kit declaressetup.startup— an sbx-0.38-classkit addrefusal (rc=3) would stall provenance and cause perpetual stale-refresh offers. Before the patterns kit ships: derive the support-kit boundary instead of hardcoding4, classify the oci kit as a support (not agent) kit, and give it the same feature-probe/label treatment asgit-ssh-sign._acq_msb_ensure_ociwould install/alias podman. Sequence-disableACQ_MSB_ENSURE_OCIwhen the oci-engine kit is selected (do not remove the adapter path until the kit is live-verified per this issue's acceptance criteria).Trigger for items 2 and 3: the patterns
oci-enginekit becoming available at the pinned ref (item 1).mogul commentedon Sep 21, 2026
Patterns-side OCI-engine kit is now up for review
The kit body that the quickstart-side
ACQ_ENABLE_OCI_KITreadiness gate depends on is now open as a patterns PR:GSA-TTS/agentic-coding-patterns#437 —
feat(oci-engine): add rootless podman OCI-engine capability kithybrid/v1mixin atintegrations/isolation/acq-kits/oci-engine/(schemaVersion: "hybrid/v1",kind: mixin,name: oci-engine— exactly what the quickstart readiness probe requires).short-name-mode=enforcing).set -eu+ bare package-manager calls defeated the documented fail-soft (would have failedsbx create); a dropped rootlessvfsrecovery step vs. the reference; and a verify script that could pass on a rootful engine. All fixed; adocs/decisions/note records the port.--strict, acq-kits tests, pattern validation, python lint/test, markdown/link/commit-title). The livescripts/verifyis host-only and skipped in CI, like the zscaler kit.This unblocks the deferred items filed earlier on this issue
Once #437 merges and the quickstart side pins the new patterns ref, the readiness gate flips true and these become actionable (previously dependency-blocked on this kit):
4boundary) — derive the support-kit boundary, classify the oci-engine kit as a support (not agent) kit, and give it the same feature-probe/label treatment asgit-ssh-signbefore the kit goes live, to avoid the rc=3 provenance-stall risk.ACQ_MSB_ENSURE_OCIwhen the oci-engine kit is selected, so the kit and the adapter don't both install/alias podman. (Do not remove the adapter path until the kit is live-verified per this issue's acceptance criteria.)Trigger for both: #437 merging and the quickstart pin bump.
mogul commentedon Oct 6, 2026
Implemented and shipped in v4.0.0 via #474 (with corrective #549). Rootless podman moved to the opt-in oci-engine kit; adapter-owned MSB OCI auto-install (ACQ_MSB_ENSURE_OCI) removed. The PR's
Closes:footer did not auto-close this because the collapsed-stack squash merge dropped the closing keyword references; closing manually now that the work is onmainand released.