Diagnose a Runner failure
Trace the failure from a public status comment to bounded local diagnostics.
Keep tokens, internal hostnames, absolute paths, raw adapter output, and private
deployment details out of issue comments and public pull requests.
Start from the failing identifier
- Record the public session ID, job ID, trigger-comment URL, status-comment
URL, approximate time, and command (
/new, /resume, or /cancel).
- Locate the scoped Runner directory containing
state.json and logs/.
Use the runner's configured --state path rather than assuming a repository
name or service-account layout.
- Resolve the job or session through
logs/index.ndjson, then read only the
matching job and session records.
state.json
logs/
runner.ndjson
errors.ndjson
index.ndjson
jobs/<job-id>.ndjson
jobs/<job-id>-acpx-stdout.log
jobs/<job-id>-acpx-stderr.log
sessions/<public-session-id>/<turn-correlation-id>.ndjson
Use jq and narrow rg queries. Do not dump all logs.
rg -n '"id":"<job-id>"|"id":"<public-session-id>"' logs/index.ndjson
rg -n '"level":"error"|"component":"(intake|dispatch|acpx)"' logs/jobs/<job-id>.ndjson
tail -100 logs/jobs/<job-id>-acpx-stderr.log
Reproduce in the correct order
- Run
issue-spec runner preflight as the same OS service user.
- For Codex, add
--verify-agent-runtime to create one tools-denied ACP
session. This validates the effective ACPX adapter and any explicit
--model; it is not a substitute for the bubblewrap check.
- Check the durable job's
sandbox.agent_runtime, sandbox.bwrap,
sandbox.env_decisions, and bounded diagnostics before changing any config.
- Re-run only the smallest failed layer: signed webhook delivery, command
authorization, clone, read-only Git command, documentation-only commit and
push, then Provider
change.create when that capability is configured.
Diagnose the common boundaries
Command intake
- Confirm the command starts at the beginning of the comment.
- Confirm the author is allowed and has repository write-equivalent permission.
- For self-hosted intake, confirm the subscription ID, secret rotation window,
receiver reachability, and server/runner clocks.
- Correlate the delivery ID,
cycle_id, trigger_comment_id, and job ID before
deciding that a command was ignored.
Codex or ACPX
- Treat
acpx and its configured agents.codex override as the effective
runtime. A host codex --version does not prove that the adapter supports a
model.
- Inspect
codex-acp preflight and sandbox.agent_runtime. The latter stores
only builtin or a safe adapter description, never the host config path.
- When ACPX rejects a model, use the exact adapter-advertised ID, including a
reasoning-effort suffix. Remove an unnecessary explicit
--model only after
confirming the service-user default works.
- Check npm/npx access or the pre-cached pinned adapter package. Do not paste
raw ACPX output into an issue because it can contain environment diagnostics.
Proxy and network
- Inspect the systemd environment file and
proxy_inherited:* decisions in
sandbox metadata. Standard HTTP_PROXY, HTTPS_PROXY, and NO_PROXY names
are inherited by the sandbox.
- Put directly reachable receiver, issue-server, and code-host addresses in
NO_PROXY. Keep proxy credentials out of the unit, logs, and issue comments.
- Restart the service after editing the environment file, then re-run the live
runtime probe as the service user.
Sandbox, Git, and SSH
- Check
sandbox.bwrap and sandbox.preflight_result before considering
--unsafe-no-sandbox; do not use unsafe mode as a routine workaround.
- For brokered credentials, compare the active Source Binding identity and
clone URL, then verify lease acquisition and revocation.
- For
--allow-host-ssh, verify the dedicated Runner account's non-interactive
SSH access and known_hosts. Treat all authority reachable by that identity
as available to every job in that Runner boundary.
- Do not solve a missing code-host CLI by mounting arbitrary host binaries into
bubblewrap.
PR/MR creation
- Distinguish commit/push success from change creation. A job can safely push a
branch and still lack authority to create a PR/MR.
- If a configured
issue-spec.code-provider/v1 bridge advertises
change.create, verify its request and resulting change URL. Keep the
company-specific wrapper and registry operator-owned.
- If the bridge does not advertise
change.create, report the branch/revision
evidence and create the change outside the sandbox. Do not broaden sandbox
mounts to bypass this boundary.
Report safely
Report the public session/job identifiers, failing boundary, timestamp,
sanitized error category, relevant preflight check, and the smallest safe next
action. Link to the status comment or change URL when available. Exclude raw
logs, credentials, internal addresses, full filesystem paths, and secret-like
environment values.
1---2name: runner-diagnostics3description: Diagnose issue-spec comment Runner failures using preflight output, persistent NDJSON logs, ACPX/Codex adapter output, bubblewrap metadata, proxy inheritance, host SSH, webhook intake, and Provider bridge evidence. Use when a /new, /resume, or /cancel command is ignored, a Runner job fails, Codex does not start, a model is rejected, clone/push fails, a webhook is rejected, or a PR/MR was not created.4---56# Diagnose a Runner failure78Trace the failure from a public status comment to bounded local diagnostics.9Keep tokens, internal hostnames, absolute paths, raw adapter output, and private10deployment details out of issue comments and public pull requests.1112## Start from the failing identifier13141. Record the public session ID, job ID, trigger-comment URL, status-comment15 URL, approximate time, and command (`/new`, `/resume`, or `/cancel`).162. Locate the scoped Runner directory containing `state.json` and `logs/`.17 Use the runner's configured `--state` path rather than assuming a repository18 name or service-account layout.193. Resolve the job or session through `logs/index.ndjson`, then read only the20 matching job and session records.2122```text23state.json24logs/25 runner.ndjson26 errors.ndjson27 index.ndjson28 jobs/<job-id>.ndjson29 jobs/<job-id>-acpx-stdout.log30 jobs/<job-id>-acpx-stderr.log31 sessions/<public-session-id>/<turn-correlation-id>.ndjson32```3334Use `jq` and narrow `rg` queries. Do not dump all logs.3536```bash37rg -n '"id":"<job-id>"|"id":"<public-session-id>"' logs/index.ndjson38rg -n '"level":"error"|"component":"(intake|dispatch|acpx)"' logs/jobs/<job-id>.ndjson39tail -100 logs/jobs/<job-id>-acpx-stderr.log40```4142## Reproduce in the correct order43441. Run `issue-spec runner preflight` as the same OS service user.452. For Codex, add `--verify-agent-runtime` to create one tools-denied ACP46 session. This validates the effective ACPX adapter and any explicit47 `--model`; it is not a substitute for the bubblewrap check.483. Check the durable job's `sandbox.agent_runtime`, `sandbox.bwrap`,49 `sandbox.env_decisions`, and bounded diagnostics before changing any config.504. Re-run only the smallest failed layer: signed webhook delivery, command51 authorization, clone, read-only Git command, documentation-only commit and52 push, then Provider `change.create` when that capability is configured.5354## Diagnose the common boundaries5556### Command intake5758- Confirm the command starts at the beginning of the comment.59- Confirm the author is allowed and has repository write-equivalent permission.60- For self-hosted intake, confirm the subscription ID, secret rotation window,61 receiver reachability, and server/runner clocks.62- Correlate the delivery ID, `cycle_id`, `trigger_comment_id`, and job ID before63 deciding that a command was ignored.6465### Codex or ACPX6667- Treat `acpx` and its configured `agents.codex` override as the effective68 runtime. A host `codex --version` does not prove that the adapter supports a69 model.70- Inspect `codex-acp` preflight and `sandbox.agent_runtime`. The latter stores71 only `builtin` or a safe adapter description, never the host config path.72- When ACPX rejects a model, use the exact adapter-advertised ID, including a73 reasoning-effort suffix. Remove an unnecessary explicit `--model` only after74 confirming the service-user default works.75- Check npm/npx access or the pre-cached pinned adapter package. Do not paste76 raw ACPX output into an issue because it can contain environment diagnostics.7778### Proxy and network7980- Inspect the systemd environment file and `proxy_inherited:*` decisions in81 sandbox metadata. Standard `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY` names82 are inherited by the sandbox.83- Put directly reachable receiver, issue-server, and code-host addresses in84 `NO_PROXY`. Keep proxy credentials out of the unit, logs, and issue comments.85- Restart the service after editing the environment file, then re-run the live86 runtime probe as the service user.8788### Sandbox, Git, and SSH8990- Check `sandbox.bwrap` and `sandbox.preflight_result` before considering91 `--unsafe-no-sandbox`; do not use unsafe mode as a routine workaround.92- For brokered credentials, compare the active Source Binding identity and93 clone URL, then verify lease acquisition and revocation.94- For `--allow-host-ssh`, verify the dedicated Runner account's non-interactive95 SSH access and `known_hosts`. Treat all authority reachable by that identity96 as available to every job in that Runner boundary.97- Do not solve a missing code-host CLI by mounting arbitrary host binaries into98 bubblewrap.99100### PR/MR creation101102- Distinguish commit/push success from change creation. A job can safely push a103 branch and still lack authority to create a PR/MR.104- If a configured `issue-spec.code-provider/v1` bridge advertises105 `change.create`, verify its request and resulting change URL. Keep the106 company-specific wrapper and registry operator-owned.107- If the bridge does not advertise `change.create`, report the branch/revision108 evidence and create the change outside the sandbox. Do not broaden sandbox109 mounts to bypass this boundary.110111## Report safely112113Report the public session/job identifiers, failing boundary, timestamp,114sanitized error category, relevant preflight check, and the smallest safe next115action. Link to the status comment or change URL when available. Exclude raw116logs, credentials, internal addresses, full filesystem paths, and secret-like117environment values.