Run in the container

oci workflow run runs a workflow in the same runner image OutcomeCI uses for cloud runs. The steps, grants, broker, and policy review behave as they do online; only the secrets and the agent login come from your machine, unless you use the workspace's credentials. You need Docker.

oci workflow run --payload .outcomeci/request.json --auto-continue

What happens

  1. oci compiles outcome.yml and fails early on any error, before a container starts.
  2. It resolves each secret the workflow references from the local Vault, and reads the agent login for each runner the workflow uses.
  3. It starts the runner container. Your repository is mounted read-only and copied inside, including .outcomeci/, so the run sees your current instructions. Secrets and the agent login cross into the container on stdin, never in arguments or environment variables that docker inspect shows.
  4. The runner executes the steps. Every API call goes through the broker, which authenticates it with the credential, enforces the step's grants, and records the call.
  5. When the container exits, the run's state is copied back into .outcomeci/outcomes/<run-id>/ and .outcomeci/.broker/<run-id>/, and the command prints the run's final state. Your checkout is never written to from inside the container.

A Codex login that the run refreshes is written back to ~/.codex/auth.json, because Codex spends the old refresh token when it refreshes. The same holds for a Vault secret a provider rotates during the run, such as a Slack refresh token: it is saved back to the local Vault however the run ends.

Choose the trigger and payload

The run starts from the workflow's trigger. With one trigger, or one manual trigger among several, oci workflow run picks it; otherwise pass --trigger NAME.

--payload FILE supplies the trigger's JSON payload, which steps read as trigger. A manual run without --payload starts with an empty payload, and a cron run gets a generated schedule payload. Other triggers need --payload, and a payload that does not match its trigger's shape fails before any step runs.

Run every step

--auto-continue runs each step in turn until the workflow completes, pauses for input, or fails. Without it, the run stops after the first step so you can inspect its result.

--auto-continue performs the real side effects later steps have, such as posting to Slack or opening a pull request. Point a first run at a test channel or repository.

Pick the agent

The agent comes from the workflow's reasoning, and any step can override it with using. --agent codex, --agent claude, or --agent opencode runs every step with that agent instead, and --model sets its model. OpenCode needs an OpenRouter model, such as --model openrouter/<provider>/<model>. Each agent needs a login on your machine; see agent logins.

A step on a model profile calls the model directly instead. With key: secrets.<name>, the key comes from your local Vault; without it, from ANTHROPIC_API_KEY or OPENAI_API_KEY. --agent does not change a model step.

Read the results

.outcomeci/outcomes/<run-id>/
  run.json                  the run's state and trigger payload
  <step>/outputs.json       what the step returned
  transcripts/<step>/       the agent's transcript and token usage
  attachments/              files the run downloaded
.outcomeci/.broker/<run-id>/
  journal.json              every API call and event

journal.json lists each call with its step, capability, request, and status:

Status Means
confirmed The call was sent and succeeded
denied The policy reviewer refused it; nothing was sent
unsent The call could not be reviewed; nothing was sent
uncertain The call failed or its delivery is unknown

A step that completes while its calls are uncertain did its work without that data. Check the journal before trusting a result, and see artifacts for what to keep.

Retry a failed run

A run that stops on an error keeps its state. Fix the cause, then resume it from where it stopped:

oci workflow run --retry <run-id> --auto-continue

Retry refuses a run that did not fail. An interrupted run, such as one stopped with Ctrl-C, is recorded as failed and can be retried the same way.

Use the workspace's credentials

--cloud runs the same way, with the credentials a cloud run of that workflow receives instead of your own. Sign in with oci auth login first:

oci workflow run --cloud --workspace-id WORKSPACE_ID --workflow-id WORKFLOW_ID \
  --payload .outcomeci/request.json --auto-continue

The run takes a short-lived lease on the workspace Vault entries granted to the workflow, and leases the workspace's connected agent, holding it for the run as a cloud run does. It needs the same permission as managing the workflow's Vault grants. The workflow file still comes from --dir, so you can try a change against real credentials before you sync it. A refreshed agent login and any rotated Vault secret are saved back to the workspace.

Choose the image and network

Every run executes in the container. The default image is ghcr.io/outcomeci/outcome-runner at the version of your oci. Pass --image to use another build. When Docker's default bridge network cannot resolve DNS, pass --network host.

Next

Review what a run records, then take the workflow online.