aude-workflow(7)
NAME
aude-workflow — an
aude session in a GitHub workflow, steered from a phone
DESCRIPTION
aude's GitHub action runs one session on a
hosted runner. Each workflow run is a new machine that makes its own key.
The workflow lists the devices that can reach the machine through a tunnel.
The session prints the machine's URL and QR code in the log.
A person with a listed device scans the QR code to read the transcript and steer the session, as on any machine (aude-rc(7)).
SETUP
Add these once in the repository settings:
- A deployment environment ‘
aude’ that only the branch ‘main’ can deploy to. - Its configuration variable
AUDE_PEERS, a peers.json (aude-rc(7) FILES) with each device that can steer. An app shows its fingerprint on its attach sheet. A machine shows its fingerprint on the ‘this machine’ line of ‘aude devices’. - Its secret:
ANTHROPIC_API_KEYorCLAUDE_CODE_OAUTH_TOKENfor claude,OPENAI_API_KEYfor codex. Give it a spend limit.
Nothing more is necessary for
‘trycloudflare’. For
‘tailnet’ or
‘funnel’, run
‘tailscale/github-action’ in an
earlier step with a Tailscale OAuth client that makes only
‘tag:aude-workflow’ nodes. Then run
‘sudo tailscale set --operator=$USER’.
In the tailnet's policy, let that tag reach nothing.
aude-tunnel(7) gives the
rest.
THE ACTION
‘dickolsson/aude/action’
takes seven inputs. Only agent is optional.
version- The release to install, such as 0.2.0. It must match SHA256SUMS and its attestation.
harness- ‘
claude’ or ‘codex’. An earlier step must install it and log in. agent- The
--agentof aude(1), by default ‘default’. task- The session's standard input. Each line is a turn (aude(1) INPUT AND OUTPUT).
peers- The peer list. The action writes it to ~/.aude/rc/peers.json.
tunnel- ‘
trycloudflare’, ‘tailnet’ or ‘funnel’. An earlier step must put its program onPATH. The action writes it to ~/.aude/rc/tunnel.json. Then it prints both files with ‘aude devices’.
It runs only on the
‘schedule’ and
‘workflow_dispatch’ workflow events.
The runner must have no ~/.aude. Then it runs
‘aude --harness harness
’
with the task on standard input until the task is done and no line waits.
The job's ‘--agent agenttimeout-minutes’ stops the
session.
Its output records has one line for each
record directory of the session and its subagents. It uploads nothing.
STEERING
Open the job's log in a wide window. Scan the aude step's first QR
code with the phone's camera. Tap Attach. On a
computer, give the URL above the QR code to ‘aude
attach’.
In the app, each run is a new machine with its own URL. The app keeps nothing of it. When the job ends, the app shows the machine out of reach. Close it.
EXIT STATUS
The aude step fails with the exit status of
‘aude devices’ or the session
(aude(1)). After an
‘aude:’ line of
DIAGNOSTICS, it fails with 1.
EXAMPLES
For claude:
on:
schedule: [{ cron: "17 3 * * *" }]
workflow_dispatch: {}
permissions: { contents: read }
jobs:
nightly:
runs-on: ubuntu-24.04
environment: aude
timeout-minutes: 120
steps:
- uses: actions/checkout@<sha>
with: { persist-credentials: false }
- run: |
curl -fsSLo cloudflared https://github.com/cloudflare/cloudflared/releases/download/<version>/cloudflared-linux-amd64
echo "<sha256> cloudflared" | sha256sum -c
sudo install -m 0755 cloudflared /usr/local/bin/cloudflared
- run: npm install --global @anthropic-ai/claude-code@<version>
- uses: dickolsson/aude/action@<sha>
id: aude
with:
version: <version>
harness: claude
task: Do the task in .github/aude/nightly.md.
peers: ${{ vars.AUDE_PEERS }}
tunnel: trycloudflare
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- if: always() && steps.aude.outputs.records != ''
uses: actions/upload-artifact@<sha>
with:
name: aude-nightly-${{ github.run_id }}
path: ${{ steps.aude.outputs.records }}
For codex, the aude step takes ‘harness:
codex’ and no ‘env’. Log
in before it:
- run: npm install --global @openai/codex@<version>
- run: printenv OPENAI_API_KEY | codex login --with-api-key
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
After the lines of the checksum and the attestation, the aude step's log shows:
installed: aude <version>, linux-x86_64 rc: made this device's key; no machine lists it yet this machine <fingerprint> tunnel trycloudflare my phone <fingerprint> devices reach this machine at AUDE:<name>$/<fingerprint>: my phone <the QR code>
DIAGNOSTICS
- aude: version '<version>' is not a release, such as 0.2.0
- aude: no release for a <system> <architecture> hosted runner
- aude: the workflow event <event> can put another's text in the task; aude runs on schedule and workflow_dispatch alone
- aude: <home>/.aude exists; aude runs on an ephemeral hosted runner alone
- rc could not read peers.json: <defect>
- Correct
AUDE_PEERS. - rc could not read tunnel.json: <defect>
- Correct the
tunnelinput. - devices cannot reach this machine: the <tunnel> tunnel <finding> — see aude-tunnel(7)
- Install or set up its program.
- could not attach — unauthorised: this machine does not list this device
- Add the device to
AUDE_PEERS. The next run lists it.
SEE ALSO
CAVEATS
Do not give a secret or a write token to a step after aude. The model can use sudo on the runner. It can read each secret of the job, the run's key and a tunnel's state. It can change the steps after aude.
Scan the aude step's first QR code. The model can also print a QR code.
A device in AUDE_PEERS can run shell
commands in each run of a workflow that lists it.
Anyone who can read the repository can read the log and the uploaded records. They show what the model printed.
The action is not tested on a hosted runner. The listener is not tested over Tailscale's tunnels.