Skip to main content
Archal runs in any CI environment. Set the auth token, pick an output format, set a pass threshold. The build fails if satisfaction drops below it. Run npx archal init locally first, then commit .archal.json, your harness, and the archal devDependency. CI should use the project-pinned CLI with npx archal.

Secrets

The only required secret is your Archal token. For CI, use a workspace API key (archal_ws_...). Workspace keys are bound to one workspace, do not expire when a team member leaves, and are the recommended auth method for any non-interactive environment:
ARCHAL_TOKEN=archal_ws_<your-key>
If your agent needs a model API key, set that too:
ARCHAL_ENGINE_API_KEY=sk-...

Creating a workspace API key

Create one from the CLI (requires owner or admin role):
archal workspace api-key create ci-runner --scope sessions:write --scope workspaces:read
Or from the dashboard: Settings > API Keys > Create Key. Recommended scopes: sessions:read, sessions:write, workspaces:read. Because workspace keys are already bound to a workspace, you do not need ARCHAL_WORKSPACE_ID. Setting it to a different workspace returns workspace_key_scope_mismatch. Workspace keys are runtime and CI credentials, not governance credentials. They can run clones, upload and read traces, and read usage for their bound workspace. They cannot list, create, or revoke workspace API keys, and they cannot read audit events. Use an owner/admin user credential, either archal login or a dashboard-issued user API key, for those workspace administration actions.

Personal tokens (local dev only)

For local development you can use archal login (browser OAuth) or set a personal token. Personal tokens start with arc_ and are tied to your individual account:
export ARCHAL_TOKEN=arc_<your-personal-token>
Personal tokens are fine for local runs but should not be used in CI because workspace keys are more durable and are not tied to a single team member.

GitHub Actions

name: Agent tests
on: [push]

jobs:
  archal:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Install dependencies
        run: npm ci

      - name: Run scenarios
        env:
          ARCHAL_TOKEN: ${{ secrets.ARCHAL_TOKEN }}
          ARCHAL_ENGINE_API_KEY: ${{ secrets.ENGINE_API_KEY }}
        run: |
          npx archal run scenarios/close-stale-issues.md \
            --docker \
            --runs 3 \
            --pass-threshold 80 \
            -o json \
            -q

GitLab CI

archal:
  image: node:22
  services:
    - docker:dind
  variables:
    DOCKER_HOST: tcp://docker:2375
    DOCKER_TLS_CERTDIR: ""
    ARCHAL_TOKEN: $ARCHAL_TOKEN
    ARCHAL_ENGINE_API_KEY: $ENGINE_API_KEY
  script:
    - npm ci
    - >
      npx archal run scenarios/close-stale-issues.md
      --docker
      --runs 3
      --pass-threshold 80
      -o json
      -q

Useful flags

FlagWhat it does
--pass-threshold <score>Exit 1 if satisfaction is below this (0-100)
-o jsonMachine-readable JSON output
-qSuppress non-error output
-n, --runs <count>Run the scenario multiple times for a real satisfaction score
--tag <tag>Only run scenarios with a matching tag (exits 0 if no match)

Exit codes

CodeMeaning
0Score met the threshold (or scenario skipped by --tag)
1Score below threshold or runtime error
2Validation error (bad flags, missing scenario, invalid config)

Go deeper

Run multiple scenarios

List scenario paths in the scenarios array of .archal.json. archal run executes each one:
{
  "agent": {
    "command": "npx",
    "args": ["tsx", "src/agent.ts"]
  },
  "clones": ["github"],
  "scenarios": [
    "scenarios/close-stale-issues.md",
    "scenarios/triage-new-issues.md"
  ],
  "runs": 3,
  "timeout": 120
}