CLI-first arena workflow¶
Use this guide to prepare reusable images, create a named arena, connect over SSH and run a bounded agent task. It then covers refresh, add, and remove/recreate. These are the current implemented CLI operations. For architecture, trust roles and accepted policy, read AI-assisted work; proposed deployment work does not add options to this recipe.
Trust, execution contexts and prerequisites¶
The human operator runs management commands in the trusted host shell. Preparation needs a connected Linux provisioning host with working rootless Podman/Buildah, subordinate IDs and access to public registries/package repositories. Host tools include Python 3.11+, Bash, jq, Git and Skopeo; arena startup needs usable user-systemd and Quadlet. See Arena administration reference for prerequisites and deployment-specific checks.
The agent demonstration runs in an SSH session as ci, inside an untrusted
execution member. Its commands and mutable workspace remain untrusted. The
default runtime has no general external access; brokered inference is the
permitted data-export path. Local SSH uses prepared images and needs neither an
active host network-online.target nor a reachable upstream provider.
Keep trusted management tools and their host state outside execution mounts.
This example uses the existing tooling checkout at $HOME/src/shyft-tools and
a separate task workspace at $HOME/projects/shyft-work. Place the checkout
there first and review the material exposed under the policy in AI-assisted work.
Warning
Read Known issues and assurance limits before choosing an agent or containment boundary: Codex file tools retain their sandbox failure, and strict bridge-gateway host-service isolation remains incomplete. Local-mock OpenCode success is neither real-provider acceptance nor full-containment verification.
At a glance: images and deployment are separate¶
Images can serve several arenas. Create generates configuration and starts the named arena; saved work and private runtime state persist separately from its replaceable images. Dashed branches below are optional, human-operated actions. Image preparation refresh does not update a running service automatically.
---
config:
flowchart:
nodeSpacing: 18
rankSpacing: 22
---
flowchart TD
I["Trusted host<br/>prepare images"] --> C["Human-operated create<br/>prepared local selections"]
C --> W["Named arena<br/>untrusted SSH / agent work"]
W -->|"human stops writers"| R["Human review<br/>outside the arena"]
R --> T["Governed acceptance"]
W -.->|"optional"| F["Trusted host<br/>image preparation refresh"]
F -.->|"explicit deployment"| D["Controlled member /<br/>gateway refresh"]
D -.->|"affected services recreated"| W
I -.->|"prepared selection"| A["Human-operated add"]
A -.->|"new member"| W
R -.->|"optional"| X["Remove<br/>deployment only"]
X -.->|"retained recreate"| C
classDef untrusted fill:#fbe1dc,stroke:#a74432,color:#54251e
classDef guard fill:#e4effb,stroke:#35669a,color:#193d62
classDef context fill:#eeeeee,stroke:#666666,color:#333333
classDef accepted fill:#e4f0e6,stroke:#477650,color:#25472b
class W untrusted
class I,C,R,F,D,A guard
class X context
class T accepted
Human-operated lifecycle; optional branches retain work/state, not running processes.¶
A. Prepare, create and use an agent¶
1. Trusted host shell: prepare, create and connect¶
Choose the public-source sequence below, or the local-source substitution in
step 2, before starting. Stop if any command fails. --images identifies
a named preparation selection, not an arbitrary image tag or JSON filename.
Important
First create needs a provider secret: after checking non-secret prerequisites,
it prompts without echo and creates an arena-specific Podman secret. To use an
existing secret, add --secret YOUR_PODMAN_SECRET_NAME; noninteractive first
create requires that mechanism. Pass only the name. Never put secret values
in arguments, JSON, logs or examples. Create itself makes no inference call.
cd "$HOME/src/shyft-tools"
mkdir -p "$HOME/projects/shyft-work"
bash tools/ai/build.sh prepare archlinux-dev \
--source registry.gitlab.com/shyft-os/shyft/archlinux-dev:latest
bash tools/ai/build.sh gateways
bash tools/ai/build.sh status
python3 -B tools/ai/arena.py create shyft \
--images archlinux-dev --workspace "$HOME/projects/shyft-work" --member dev
python3 -B tools/ai/arena.py status --arena shyft
python3 -B tools/ai/arena.py ssh --arena shyft --member dev
Expected: preparation reports selections archlinux-dev,
archlinux-squid and caddy. Gateways builds Arch Squid and acquires
registry.access.redhat.com/hi/caddy:latest unmodified. Create validates the
recorded immutable local images, allocates networking/loopback SSH, installs
managed source Quadlets and starts services. It never pulls or builds.
Status distinguishes saved configuration from running services and reports local
gateway health. The last command opens a pinned SSH session as ci; continue
with step 3 there. Local gateway health does not prove upstream authentication
or model readiness. An identical create rerun retains keys/work and reconciles
state; identity/configuration conflicts are refused, not overwritten.
Mutating arena commands support --dry-run without mutation or secret input.
2. Alternative: prepare a local source on the trusted host¶
This is a substitution before first create, not an extra step inside SSH. Replace the Arch preparation line above with this trusted host shell command:
bash tools/ai/build.sh prepare archlinux-dev \
--source localhost/archlinux-dev:next --name local-dev
Then use --images local-dev in create. Local input is inspected and used
directly without registry access or invented registry provenance. Package
installation can still need distribution repositories unless prepared explicitly
offline. See Image preparation for offline preparation and the
Fedora preparation branch.
3. SSH session as ci: create files with an agent and test them¶
This is an explicit real-provider action: it sends task data to the configured inference provider and can incur charges. Use only permitted task material. The demonstration creates a disposable subdirectory in the mounted workspace:
cd /home/ci/workspace
DEMO=$(mktemp -d ./agent-demo.XXXXXX)
cd "$DEMO"
/opt/ai-agents/runtime.sh opencode --format json \
'Create add.py with add(a, b).
Create test_add.py using unittest: add(2, 3) == 5 and add(-2, 2) == 0.
Run python3 -m unittest -v. Report the test result and files changed.'
ls add.py test_add.py
python3 -m unittest -v
Expected: add.py and test_add.py exist and the user-run unittest
passes. A text response alone is not file-tool success. The launcher selects the
installed supported OpenCode profile; do not replace its broker configuration.
Local-mock file/exec evidence is separate from real-provider acceptance. No
inference runs automatically during create or status. An upstream failure does
not broaden egress; stop and consult Arena troubleshooting and known issues.
B. Refresh images in an arena¶
Return to the trusted host shell in the tooling checkout. Build refresh prepares a new image and retains the previous one. Arena refresh deliberately deploys the prepared immutable identity; it does not build or pull.
bash tools/ai/build.sh refresh archlinux-dev
python3 -B tools/ai/arena.py refresh --arena shyft \
--member dev --images archlinux-dev --dry-run
python3 -B tools/ai/arena.py refresh --arena shyft \
--member dev --images archlinux-dev --stop-running
Expected: the dry-run identifies affected services and old/new identities.
An unchanged identity is a no-op. A changed image with running affected services
requires --stop-running; the example explicitly permits that interruption.
Member SSH sessions and processes stop. Saved mounts, keys, addresses and
initialized runtime/cache state persist; processes and unsaved buffers do not.
Stop independent host writers separately and preserve valuable work independently.
Image rollback — trusted host shell: restore the previous local identity:
python3 -B tools/ai/arena.py refresh --arena shyft --member dev \
--rollback --stop-running
Image rollback does not roll back persistent data or state migrations. Retained local images must remain available; see Arena administration reference for compatibility and recovery limits.
Gateway refresh — trusted host shell: prepare, then deploy explicitly:
bash tools/ai/build.sh gateways --refresh
python3 -B tools/ai/arena.py refresh --arena shyft --gateways --stop-running
Expected: policy and secret references remain unchanged. Gateway refresh
temporarily interrupts inference for every member; local member SSH remains
independent of upstream readiness. For the local-source example, prepare with
refresh archlinux-dev --name local-dev and deploy with --images local-dev.
C. Add another member¶
First prepare fedora44-scripting with its verified local agent bundles. Then run in the trusted host shell:
mkdir -p "$HOME/projects/analysis"
python3 -B tools/ai/arena.py add --arena shyft --member analysis \
--images fedora44-scripting --workspace "$HOME/projects/analysis"
python3 -B tools/ai/arena.py ssh --arena shyft --member analysis
Expected: add allocates a separate address/loopback port, SSH identity and
private state; scripting disables the development compiler cache. Existing
members and gateways are not restarted. The last command enters the new member’s
SSH session as ci. Identical input preserves state; conflicting input fails.
Use --dry-run to inspect the addition before deployment.
Members in the same arena are mutually reachable and share a trust domain; add is not tenant isolation. Use another arena for a different trust domain, while remembering that arenas on the same host still share its kernel.
D. Remove and recreate an arena¶
Return to the trusted host shell. Review the removal plan before continuing:
python3 -B tools/ai/arena.py remove --arena shyft --dry-run
python3 -B tools/ai/arena.py remove --arena shyft
python3 -B tools/ai/arena.py status --arena shyft
python3 -B tools/ai/arena.py create shyft --retained
python3 -B tools/ai/arena.py ssh --arena shyft --member dev
Expected: remove stops/removes only the owned deployment and status records
it as removed. Work/data, runtime/cache, SSH keys, images, selections, secrets and
operation records remain. Repeated removal is safe. --retained recreates every
saved member using saved configuration, immutable images and existing keys/state
where available; it does not select newer images or recopy initialized seeds.
Missing retained inputs or ownership conflicts require deliberate recovery, not replacement or forced deletion. See Arena administration reference for optional owned-secret removal and partial-failure recovery. The last command reconnects to SSH as ci; removal/recreation does not restore stopped processes.
What to check and when to stop¶
Stop at a failed prerequisite, identity mismatch, configuration conflict or unavailable inspection. Do not overwrite state, bypass validation or widen network/mount access. Failed operations can be partial; inspect diagnostics and follow Arena administration reference before retrying identical input.
Check status and actual files/test results. Local SSH and default-deny gateway health are separate from real-provider readiness. Consult Known issues and assurance limits for agent and bridge-service blockers; bounded checks in Bounded security verification are not certification.
Before acceptance, stop the execution member and independent writers. Review returned files as untrusted input outside the arena, following AI-assisted work. Persistence is not a backup. Human acceptance, signing, publication and production integration remain outside agent authority.
References and known issues¶
Use these references for details rather than expanding the CLI recipe:
Image inputs/provenance, administration, bounded verification and troubleshooting
remain separate topics. Optional IDE provisioning and named members is an optional provisioning
extension, not a CLI prerequisite; ordinary arena.py add does not expose IDE
backend/seed options. Lifecycle regressions and manual checks do not establish
independent security review or full containment.