Shimmy is a profile-aware OCI tool harness that exposes containerized tool implementations as ordinary host CLI commands, with version selection, runtime isolation, registry policy, and AI-agent tool integration. Tool runtimes mount the current directory at /work, select the native Linux platform, and retain each tool's documented configuration and
credential boundaries.
SHIMMY PROFILE
│
┌───────────────┼────────────────┐
│ │ │
tool policy runtime policy registry policy
│ │ │
▼ ▼ ▼
jq@1.8 shared/isolated image redirect
rg@15.1 engine
│
▼
host-visible
shims
│
▼
implementation resolution
│
▼
OCI image
│
▼
isolated tool process
- POSIX-compatible
/bin/sh - Git
- Podman CLI and a reachable local rootless engine
Shimmy does not install Podman or adopt existing machines. On macOS, fresh
bootstrap provisions the installation-owned shared machine shimmy-default; leave that
machine and connection name unused beforehand.
The official macOS package may install Podman at /opt/podman/bin/podman.
Machine creation uses the Podman 5.8-compatible machine init <name> command
surface and preserves any existing default connection itself.
Every tool implementation accepts one optional host trust file through
SHIMMY_HOST_CA_BUNDLE=/absolute/path/to/bundle.pem. When present, every runtime mounts
that exact file read-only at /tmp/shimmy-host-ca-bundle.pem and explicitly
assigns either the implementation's documented native CA variable or the
SSL_CERT_FILE compatibility fallback to that container path. The host-only
SHIMMY_HOST_CA_BUNDLE variable and its host path are not forwarded as
container environment variables. Unset, empty, invalid, and zero-byte inputs
add no runtime mount or assignment.
For local-build tools, a present bundle is supplied only as the temporary
shimmy-host-ca-bundle build secret before build-time network work. The secret
source and certificate contents are not embedded in an image layer, logged, or
included in the local image identity, tag, or label. Consequently, normal cache
reuse does not rebuild a local image when the bundle changes. Set the tool's
SHIMMY_<TOOL>_IMAGE_BUILD=always setting when refreshed build-time trust is
required. Shimmy does not validate PEM syntax, merge certificate bundles, or
guarantee that every application honors SSL_CERT_FILE.
| Runtime mapping | Concrete implementations |
|---|---|
AWS_CA_BUNDLE |
AWS CLI 2.31 |
CLOUDSDK_CORE_CUSTOM_CA_CERTS_FILE |
Google Cloud CLI 573.0 |
NODE_EXTRA_CA_CERTS |
npx 24.18, gdrive 0.2, Tessl 0.1 |
SSL_CERT_FILE fallback |
ABA 1.3, Bats 1.14, community-ansible-dev-tools 26.7, Flux 2.9, GitHub CLI 2.94, Go 1.26, jq 1.8, jv 6.0, KeePassXC 2.7, Logmine 0.1, Netcat 7.92, Nmap 7.98, OpenShift CLI 4.18/4.20/4.22, both OPNsense MCP tools, ripgrep 15.1, Skopeo 1.22, Task 3.45, Terraform 1.15, Textual 8.2, and yq 4.53 |
Node's NODE_EXTRA_CA_CERTS augments built-in public roots. The AWS, Google
Cloud CLI, Go, and HTTPX mechanisms can replace normal trust-file discovery or
have implementation-specific precedence. Supply a combined public and
corporate bundle when the selected runtime must trust both; Shimmy does not
discover, merge, or parse certificates. ABA 1.3 additionally adds the supplied
bundle to its local Fedora image's system trust store before package installation.
Application-specific CA flags
or configuration can still take precedence. For OPNsense MCP read-only, also
set OPNSENSE_VERIFY_SSL=true; Shimmy then gives the same host bundle to the
curl reachability preflight through --cacert.
Bootstrap from a clean, committed checkout on the attached local main branch:
. ./bootstrap.sh
jq --version
rg --versionThe entire tracked catalog must validate, including tools outside the initial toolset. Commit executable permission fixes before bootstrapping; catalog validation failures are reported in the bootstrap error.
The bootstrap creates and activates default, publishes the checkout as the
first immutable default catalog generation, installs jq, rg, and Skopeo, and
sources the generated shell-init.sh when the bootstrap itself is sourced.
Executing ./bootstrap.sh performs the same installation but cannot change its
parent shell. On macOS it transactionally creates the installation-owned shared
machine and connection named shimmy-default; an exact pre-existing name is a collision
and is never adopted. On Linux it records the current local rootless engine as
the shared host-local engine.
The generated engines/shared/engine.conf is a strict, read-only state record.
Each attribute has a canonical explanatory comment describing its meaning and
accepted values or representative examples. The values remain platform-specific;
use shimmy admin engine status for supported operational inspection instead of
editing the record.
Use --shell <bash|zsh|sh|ksh|mksh> to select the recorded startup shell or
--no-startup to record manual startup policy. The installation root is
${XDG_CONFIG_HOME:-$HOME/.config}/shimmy; a non-empty XDG_CONFIG_HOME must
be absolute. Bootstrap refuses any pre-existing installation root instead of
merging or migrating it.
A failed bootstrap normally removes its fresh installation root. If Podman machine initialization is ambiguous or exact rollback cannot finish, Shimmy reports incomplete rollback and retains the root plus engine lifecycle journal as recovery evidence. Do not retry bootstrap or delete/adopt the machine by name; inspect the reported state first. Image preparation failures identify the tool, version, pull/build action, and configured reference so the failing catalog entry can be inspected directly.
See BOOTSTRAP.md for first-contact installation and engine preparation.
The installed launcher has five groups:
| Group | Purpose |
|---|---|
shimmy admin |
Inspect engine, network, or installation state and manage installation lifecycle. |
shimmy profile |
List, inspect, create, clone, activate, sync, repair, or delete profiles and redirects. |
shimmy catalog |
Inspect, verify, publish, or roll back the immutable default catalog. |
shimmy shim |
Add, remove, select, sync, list, or test profile-local tool versions. |
shimmy ai-skill |
Inspect or repair active-profile skill links. |
Invoking the launcher, any group, or the profile redirect subgroup without a
child command is exactly equivalent to adding --help: it exits successfully,
writes the same bytes to stdout, writes nothing to stderr, and does not validate
or mutate installed state. Actions are different: they retain their documented
defaults or require their documented inputs.
shimmy
shimmy --help
shimmy profile
shimmy profile --help
shimmy profile activate --helpThere are no compatibility aliases for the previous install, update,
images, skills, status, test, netinfo, or uninstall top-level
commands. The catalog schema-1 ownership contract is replaced in place by this
layout, so installations created by an earlier contract are unsupported. Remove
an older installation with the Shimmy version that created it, then bootstrap a
fresh installation.
Profiles are independent materialized installations below
.../shimmy/profiles/<name>. Names use lowercase letters, digits, and single
hyphens. The launcher containing the command is the invoking profile; the
installation-wide active record independently owns engine, registry, mutation,
and user-skill-link authority.
Create and inspect a sibling safely:
shimmy profile create team-one --dry-run
shimmy profile create team-one
shimmy profile listOrdinary creation binds the profile to the shared engine. On macOS, an explicit isolated profile provisions a separately owned machine and warns before that machine is later destroyed:
shimmy profile create isolated-one --isolated --dry-run
shimmy profile create isolated-one --isolated
shimmy profile delete isolated-one --dry-run
shimmy profile delete isolated-oneCreation activates the new profile. Clone copies supported profile-owned configuration and selection state, then activates the target. Shared sources clone to the shared engine by default; isolated sources create a new owned isolated machine. Use one explicit override when needed:
shimmy profile clone default team-two --dry-run
shimmy profile clone isolated-one isolated-two --sharedTo switch back, inspect the transition before applying it, then source the selected profile in the current shell:
shimmy profile activate default --dry-run
shimmy profile activate default
. "${XDG_CONFIG_HOME:-$HOME/.config}/shimmy/profiles/default/shell-init.sh"Ordinary profiles bind to one shared engine. On Linux, activation selects the
exact user registry-policy link and validates the current user's local rootless
Podman process. On macOS, shared-to-shared activation keeps the installation's
owned shared VM shimmy-default and running containers up. A changed effective
registry policy causes only a brief rootless Podman API interruption while
podman.service is recycled; equal
policies require no recycle. A transition between shared and isolated engines
stages the target policy before starting it, stops the prior machine only when
required, and requires --stop-running if that interruption would affect
listed workloads. --restart remains explicit VM recovery and is not part of
normal shared-profile switching.
CONTAINER_CONNECTION, CONTAINER_HOST, CONTAINERS_REGISTRIES_CONF, and
CONTAINERS_REGISTRIES_CONF_OVERRIDE can mask profile authority and therefore
fail closed. Diagnostics name the variable but do not print its value.
Registry redirects are profile-local:
shimmy profile redirect list
shimmy profile redirect set --prefix docker.io \
--location registry.corp.example/docker --dry-run
shimmy profile redirect delete --prefix docker.ioActive-profile edits update and validate the engine projection immediately; inactive-profile edits change only their source policy until later activation.
Inspect the strict profile bindings and engine registry without mutation:
shimmy admin engine status --format manifestSkopeo is the only initial tool-container consumer of this policy.
shimmy catalog verify inherits it through the active profile's Skopeo shim.
The installation owns exactly one catalog named default. It contains retained
immutable generations. Each profile pins one generation, so publication and
rollback never silently change installed profile contents.
The catalog payload is exactly tools/, including each tool's canonical
SKILL.md. A retained generation contains only generation.conf and tools/.
Its content fingerprint covers every regular file below tools/, including
executable-mode identity. generation.conf records the catalog format/schema,
source commit, and content fingerprint outside that fingerprint's scope;
control-plane sources are also excluded.
shimmy catalog status
shimmy catalog tools
shimmy catalog verify --tool jq@1.8 --format manifest
shimmy catalog refresh netcat@7.92 --dry-runMaintainers can refresh one existing version's mutable tag-backed runtime or
base-image records from the attached local main checkout root. Refresh uses
the active profile's exact jq and Skopeo runtimes, registry redirects, and
explicit SHIMMY_SKOPEO_AUTH_SECRET, validates the resolved immutable index for
both required platforms, then re-resolves tags before changing only the
selected image.conf; other staged, unstaged, and untracked work is preserved.
It refuses immutable-only inputs and cross-repository
mirror boundaries. --dry-run performs the same discovery and validation.
Review any reported guide or skill references and complete both native-host
smokes before committing and running the separate catalog publication command.
shimmy catalog publish must run at a clean committed checkout root on attached
local main; it stages and validates only tracked tools/.
If that content already has a valid retained generation, publication reuses the
generation and its original provenance commit. Publishing equivalent current
content is a no-op: it does not rewrite the registry, advance current/previous,
or create another generation. shimmy catalog rollback selects the retained
previous valid generation without deleting generations.
A profile's exact control-source commit and catalog pin are independent.
shimmy profile sync explicitly advances the invoking active profile from
refs/heads/main, adopts the applicable retained catalog generation, and
reconciles its materialized assets. Catalog publication and rollback never
silently advance either part of an existing profile.
Shim selectors are tool or tool@version without catalog prefixes:
shimmy shim add task@3.45
shimmy shim list --format manifest
shimmy shim set-version oc@4.20
shimmy shim sync oc
shimmy shim test oc@4.20An unqualified shim add is interactive and records tracking policy. An exact
first selection is noninteractive and records pinned policy. Every profile owns
its direct bin/<tool> wrapper and concrete version assets; no implementation-
name routing layer exists.
Canonical management skills are control-plane-only direct directories under
plugins/shimmy/skills/; they are not catalog content. Each profile
materializes its complete non-empty control bundle dynamically from that tree
at the profile's exact shimmy_source_ref. Tool skills remain catalog-owned at
tools/<tool>/SKILL.md and are materialized from the profile's pinned catalog
generation. Installed profiles reconcile both validated bundles as direct links
in the active user's $HOME/.agents/skills directory.
shimmy ai-skill list --format manifest
shimmy ai-skill repairOnly exact bundle-declared names are replaced. Recognized stale Shimmy links may
be removed; unrelated names and the skill root itself are preserved. This
repository deliberately does not contain generated .agents/skills adapters.
Adding or removing a canonical management-skill directory requires a committed
source change and explicit shimmy profile sync for adoption; it requires
catalog publication only when catalog-owned content also changed.
shimmy admin status --format manifest
shimmy admin network --format manifest
shimmy admin uninstall --dry-run
shimmy admin uninstallUninstall validates ownership before removing all profiles, retained catalog state, the active record, exact startup blocks, recognized registry projections, and recognized direct Shimmy skill links. On macOS it also removes every shared or isolated machine whose complete current host, guest, connection, and inspect evidence proves Shimmy ownership. It preserves source checkouts, external, ambiguous, and Linux host-local engines, unrelated registry policy, unrelated skill names, and the user skill root.
Destructive uninstall warning: removing an owned machine permanently destroys its containers, images, volumes, build caches, and all other VM-local data. None of that data will be preserved. Run
--dry-runfirst. Listed running containers require explicit--stop-runningacknowledgement.
Machine deletion cannot be rolled back. Shimmy records ordered pending and completed engines before the first stop or removal. A partial failure retains the installation and journal, reports preserved/completed/pending engines, and prints the exact retry command. Reused names are collisions and are never treated as the machine that was already removed.
Deleting a shared profile never removes the shared engine. Deleting a profile with a fully proven Shimmy-owned isolated engine permanently deletes that machine and all VM-local containers, images, volumes, build cache, and other data. Legacy, external, or ambiguously owned machines are preserved.
| Tool | Guide |
|---|---|
| aba | tools/aba/guide.md |
| aws | tools/aws/guide.md |
| bats | tools/bats/guide.md |
| community-ansible-dev-tools | tools/community-ansible-dev-tools/guide.md |
| flux | tools/flux/guide.md |
| gcloud | tools/gcloud/guide.md |
| gdrive | tools/gdrive/guide.md |
| gh | tools/gh/guide.md |
| go | tools/go/guide.md |
| jq | tools/jq/guide.md |
| jv | tools/jv/guide.md |
| logmine | tools/logmine/guide.md |
| netcat | tools/netcat/guide.md |
| nmap | tools/nmap/guide.md |
| npx | tools/npx/guide.md |
| oc | tools/oc/guide.md |
| opnsense-mcp-admin | tools/opnsense-mcp-admin/guide.md |
| opnsense-mcp-read-only | tools/opnsense-mcp-read-only/guide.md |
| rg | tools/rg/guide.md |
| skopeo | tools/skopeo/guide.md |
| task | tools/task/guide.md |
| terraform | tools/terraform/guide.md |
| tessl | tools/tessl/guide.md |
| textual | tools/textual/guide.md |
| yq | tools/yq/guide.md |
Source previews remain available without contacting Podman:
./commands/run-tool.sh jq --preview-shim --version
./tests/test.sh --list-groups
./tests/test.shcommands/agent-preflight.sh is also source-only, but it still probes
podman info even without --smoke so it can report approval readiness.
Direct podman info success does not approve or verify nested Podman access
through a Shimmy wrapper. If an AI Agent sandbox blocks a wrapper, retry that
same outer wrapper command with escalation only when the operation is safe to
replay. Wrapper failures can still come from the outer sandbox, image
acquisition, container setup, or the wrapped tool itself.
Read CONTRIBUTING.md before changing the repository. Registry ownership details are in docs/registries.md.