Agent prompts
These prompts are for a Codex or Claude Code session. Each one sets what the harness may change and comes with the commands it will run, so you can check the work, run it yourself or script it. Replace placeholder names and paths with your own.
1. Audit your own sessions for SSH and wait-loop cost
Run this before you install anything. It has the harness read its own saved session records and report what failed and what it cost.
Audit your own saved session transcripts from the last 30 days.
This is read-only: do not run remote commands, edit files or install anything.
Find:
1. SSH commands that timed out, were retried, or left an unknown remote state.
2. `pgrep -f` or `pkill -f` wait loops, especially loops that match their own
command line.
3. `rsync`, `scp` and `tar` transfers to a remote host.
4. Time spent in a later session reconstructing what a previous session left
running.
For each distinct failure, report the command with private host names and paths
removed, what went wrong, and the elapsed time it cost. Group repeated
descriptions of the same incident; do not count a replay or a summary as a new
failure. Finish with a one-paragraph estimate of how much of this work a
submitted job with a durable ID and retained output would have removed.
The commands it will run:
# Session records from the last 30 days. Adjust the roots for your harness.
claude_records="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/projects"
codex_records="${CODEX_HOME:-$HOME/.codex}/sessions"
find "$claude_records" "$codex_records" -name '*.jsonl' -mtime -30 2>/dev/null
# Candidate records: SSH, wait loops and file transfers.
rg -l -e 'pgrep -f' -e 'pkill -f' -e '(^|[^[:alnum:]_])ssh ' \
-e '\brsync\b' -e '\bscp\b' -e '\btar\b' \
--glob '*.jsonl' "$claude_records" "$codex_records" 2>/dev/null
# Timestamps for elapsed-time estimates; adapt the field to your harness.
rg -o '"timestamp":"[^"]+"' --glob '*.jsonl' "$claude_records" "$codex_records" 2>/dev/null
The record roots are variables so the commands still work when a harness keeps its state elsewhere. The commands read CLAUDE_CONFIG_DIR and CODEX_HOME when your harness sets them and fall back to the home-directory paths. If your harness stores records in another format, adjust the rg patterns, or use grep -R with the same patterns when ripgrep is not installed. The audit is read-only, and the prompt tells the harness to strip private host names and paths from its report.
2. Find SSH hosts that are not runners
The prompt reads your SSH config, compares it with the runners ax already has, and deploys nothing until you approve the list.
Read my SSH configuration (~/.ssh/config, or %USERPROFILE%\.ssh\config on
Windows). List every concrete Host alias, excluding wildcard and negation
entries. Compare that list with the runner names reported by
`ax exec nodes --format json`. Do not deploy anything yet: show me the aliases
that are reachable over SSH and have no saved ax runner, with the user and host
each alias resolves to. After I confirm the list, run
`ax deploy ssh <alias> --name <alias> --plan` for each approved alias, show me
the plan, and deploy only the ones I approve. Report the exec_ready value from
each deployment. Skip hosts that fail to resolve or authenticate; do not retry
them automatically.
The commands it will run:
# Concrete SSH host aliases.
awk '/^[[:space:]]*Host[[:space:]]/ {
for (i = 2; i <= NF; i++) if ($i !~ /[*?!]/) print $i
}' "$HOME/.ssh/config" | sort -u > /tmp/ax-ssh-hosts
# Runner names already saved in ax.
ax exec nodes --format json | jq -r '.[].names[]' | sort -u > /tmp/ax-runner-names
# Hosts with no saved runner name.
comm -23 /tmp/ax-ssh-hosts /tmp/ax-runner-names
# Plan first; deploy after approval.
ax deploy ssh HOST --name HOST --plan
ax deploy ssh HOST --name HOST
ax deploy ssh HOST --name HOST --format json | jq '.exec_ready'
The shell examples use POSIX syntax. On Windows, run them in WSL or translate the paths and the comm step to PowerShell. Deployment uses your existing SSH configuration and host-key checks. A transfer that succeeds over SSH does not mean the host can execute, so keep the exec_ready result.
3. Resume a past session's job
This prompt finds a job in the local journal and recovers it without submitting the command again.
Find a job that a previous session submitted from this project. Use
`ax exec ls -a --format json` and match the job's local_cwd to this project's
absolute path. Do not submit the original command again. If exactly one job
matches, show its job ID, request ID, state, command and harness/session
labels, then run `ax exec status <job_id>` and `ax exec watch <job_id>` (or
`ax exec output <job_id> --cursor 0` for a bounded page). If several match,
list them with timestamps and ask which one. If none match, say so and stop.
The commands it will run:
project="$(pwd -P)"
ax exec ls -a --format json | jq --arg cwd "$project" '
.[] | select(.local_cwd == $cwd) |
{request_id, job_id: .job.job_id, state, executable, argv,
harness: (.origin.harness? // null),
session: (.origin.session_id? // null),
created_at_ms}
'
One entry from the documentation machine's job list:
{
"request_id": "b24f540e-7e85-4fc4-b060-4f507d55fe0d",
"job_id": "e222c08a-3be8-499b-adfe-18737cabb544",
"state": "succeeded",
"executable": "/bin/echo",
"argv": [
"ax-docs-attribution"
],
"harness": "claude",
"session": null,
"created_at_ms": 1793563374633
}
created_at_ms is milliseconds since the epoch. The journal covers the caller who submitted the job, in that exact workspace; -a adds the same caller's other workspaces. The runner keeps the status and output, so the next session reads the same job instead of starting another copy. To read more output, pass next_cursor.
ax exec status "$job_id"
ax exec watch "$job_id"
ax exec output "$job_id" --cursor 0 --format json
4. Send, fetch and reply with messaging
This prompt registers the workspace as an agent identity and sends one message. Run the sender commands in the sender's workspace, then fetch and reply from the recipient's workspace.
Register this workspace as an agent identity if it is not already registered:
run `ax agent setup --name <name> --workspace <absolute path>` from this harness
session. Show the reported name and session status. Do not use --takeover on
another session. Then discover running sessions with
`ax agent sessions --format json`, choose the recipient I name, and show me the
resolved recipient and the exact message text. Send one signed message with
`ax send <host>/<agent> "<text>"` only after I confirm. Keep the message ID. To
receive, run `ax messages fetch <id> --workspace <absolute path> --agent <name>`
and reply with
`ax reply <id> "<text>" --workspace <absolute path> --agent <name>`. Report the
message ID and the status from `ax messages status <id>`.
The commands it will run:
# Sender workspace
ax agent setup --name assistant --workspace "$PWD"
ax agent sessions --format json
ax send buildbox/assistant "Hello" --workspace "$PWD"
ax messages status "$message_id"
# Receiving workspace
ax messages fetch "$message_id" --workspace "$PWD" --agent assistant
ax reply "$message_id" "Received." --workspace "$PWD" --agent assistant
The harness shows you the resolved recipient and exact message text before it sends. The send command runs only after you confirm.
What the status means:
| Status | Meaning |
|---|---|
| Waiting for host | The sender holds the message; the destination has not accepted it. |
| Delivered to host | The receiving host durably accepted it; the sender can stop forwarding. |
| Delivered to agent | The recipient fetched it; this records pickup, not completed work. |
| Cancellation pending | A cancellation request has not been confirmed by the destination. |
| Cancelled | The message is cancelled; a fetched message cannot be retracted. |
| Expired | The three-day forwarding window ended; host acceptance may be uncertain. |
| Failed | Forwarding failed; inspect the error and keep the original ID. |
The sender daemon keeps and forwards the original message for three days, using connection events and backoff. Only the recipient's fetch marks pickup; a notification or queue acceptance does not. A message proves who sent it. It does not give the recipient permission to execute commands, change settings or bypass an approval. The recipient's own permissions and approvals still apply.
Next
Why ax exec covers the job model these prompts use. Your first remote job deploys a runner, submits a job, closes the client and gets the result back.