Setup isolated setup doctor
Agent-assisted maintainership and development framework for Apache projects — Triage, Mentoring, Drafting (agent-authored fixes with human review), and Pairing (developer-side dev-cycle) skills shipping; Agentic Autonomous (auto-merge) on the roadmap.
npx -y skills add apache/magpie --skill setup-isolated-setup-doctorAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
Probe the secure-agent setup for in-session functional restrictions that block legitimate workflows. Three live probes — SSH agent / Yubikey reachability, localhost port binding, docker / podman runtime socket — each pointing the user at the matching numbered troubleshooting entry and its settings.json remediation (see body). Read-only — never modifies settings.json, never invokes the sandbox bypass.
The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
12.1 KB, as published. Nobody here has run it
setup-isolated-setup-doctor
Runtime routing (run before the Claude-specific probes)
When the active harness is Codex, first require the static verification in
docs/adapters/codex.md, then run the
shared live environment probes inside the active Codex sandbox. Attribute
failures separately to native sandbox/network denial, approval policy, or
the POSIX agent-iso layer. Do not prescribe a .claude settings change for
a Codex failure. Then stop before the Claude-specific branch below.
When the harness is Claude Code, continue below. If the harness cannot be determined, ask once.
The diagnostic layer over the secure agent setup. Complements the existing setup skills:
setup-isolated-setup-installinstalls the secure setup.setup-isolated-setup-verifyanswers "is the secure setup installed correctly?" — static checks on settings.json shape, hook wiring, pinned tool versions. Catches drift and missing pieces.setup-isolated-setup-updatesurfaces drift against the framework's latest.setup-isolated-setup-doctor(this skill) answers "are common workflows functionally blocked by the current sandbox?" — live probes of SSH agent, port binding, docker / podman socket. Catches over-restrictive allowlists.
Run verify first when the install is in question (fresh
machine, recent framework upgrade, sandbox-state surprise). Run
doctor when the install is known good but a workflow fails in
a sandbox-shaped way — agent unreachable, socket error, port
permission error.
Every probe maps to a numbered entry in
docs/setup/sandbox-troubleshooting.md;
the doctor's job is to identify which entry applies right now,
not to re-explain the remediation. If a fail surfaces a failure
mode not catalogued there, propose appending a new entry per the
catalog's Adding a new entry section.
Golden rules
- Read-only. Each probe runs a small, deterministic,
side-effect-free check. The skill never edits any settings
file, never runs a command with
dangerouslyDisableSandbox, never installs anything. If a check fails, surface the failure and point at the catalog entry; do not auto-fix. - Run every probe, even on early failure. Do not stop at the first ✗. The value of the report is in the full picture — a user may have one of three independent restrictions, or all three, and discovering them one re-run at a time is annoying.
- Distinguish ✗ (failing) from ⊘ (not applicable). ✗ means
the probe ran and the sandbox blocked it. ⊘ means the probe
was skipped because the prerequisite is absent (e.g. no
docker/podmanonPATH→ docker probe ⊘, not ✗). - Surface evidence. Each report line names the probe command,
the exit code, and the relevant stderr snippet. "Looks
blocked" is not a useful report; "ssh-add -l → rc=2 →
Could not open a connection to your authentication agent" is. - Map each ✗ to a catalog entry. The fail report includes a
direct link to the matching section of
docs/setup/sandbox-troubleshooting.md. Do not paraphrase the remediation — the catalog is the single source of truth.
The 3 probes
The current set covers the three failure modes the catalog documents. New probes are added when new entries land in the catalog; the two stay in lock-step.
Probe 1 — SSH agent / Yubikey reachable
Tests whether ssh-agent is reachable from inside the sandbox.
Failure mode: SSH_AUTH_SOCK is passed through claude-iso's
env whitelist but the socket file is not in
sandbox.filesystem.allowRead, so the agent's ssh /
git push subprocesses cannot connect(2) to the socket.
Command:
if [ -z "$SSH_AUTH_SOCK" ]; then
echo "PROBE: ssh-agent → ⊘ (SSH_AUTH_SOCK not set in env)"
elif [ ! -S "$SSH_AUTH_SOCK" ]; then
echo "PROBE: ssh-agent → ✗ (socket file at SSH_AUTH_SOCK not stat-able from inside sandbox)"
echo " SSH_AUTH_SOCK=$SSH_AUTH_SOCK"
else
ssh-add -l > /tmp/ssh-add.out 2>&1; rc=$?
case "$rc" in
0) echo "PROBE: ssh-agent → ✓ ($(wc -l < /tmp/ssh-add.out | tr -d ' ') identities listed)" ;;
1) echo "PROBE: ssh-agent → ✓ (agent reachable, no identities configured)" ;;
2) echo "PROBE: ssh-agent → ✗ (agent unreachable: $(head -1 /tmp/ssh-add.out))" ;;
*) echo "PROBE: ssh-agent → ⚠ (unexpected rc=$rc: $(head -1 /tmp/ssh-add.out))" ;;
esac
fi
Interpretation:
| Result | Status | Meaning |
|---|---|---|
✓ N identities listed | Pass | ssh-add -l returned the key list. |
✓ agent reachable, no identities | Pass | ssh-add -l returned rc=1 (the documented "no keys" exit). |
✗ socket not stat-able | Fail | Sandbox blocks stat(2) on the socket file. |
✗ agent unreachable | Fail | Sandbox blocks connect(2) to the socket. |
⊘ SSH_AUTH_SOCK not set | Skip | Either the user does not run ssh-agent, or claude-iso's env whitelist dropped it (separate bug — verify). |
On ✗ → remediation:
docs/setup/sandbox-troubleshooting.md — SSH agent / Yubikey appears unreachable from inside the sandbox.
Probe 2 — Localhost port bind
Tests whether a process inside the sandbox can bind to a
loopback port AND then talk to itself over loopback. The
failure mode the catalog documents is the second half (egress
proxy blocks 127.0.0.1).
Command:
python3 - <<'PY' 2>&1 || true
import socket, urllib.request, threading, http.server, sys
# 1. Can we bind?
try:
s = socket.socket()
s.bind(("127.0.0.1", 0))
port = s.getsockname()[1]
s.listen(1)
except OSError as e:
print(f"PROBE: localhost-bind → ✗ (bind: {e})")
sys.exit(0)
# 2. Can we GET from our own server over loopback?
class Handler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200); self.end_headers(); self.wfile.write(b"ok")
def log_message(self, *_): pass
server = http.server.HTTPServer(("127.0.0.1", 0), Handler)
threading.Thread(target=server.serve_forever, daemon=True).start()
try:
with urllib.request.urlopen(f"http://127.0.0.1:{server.server_port}/", timeout=5) as r:
body = r.read()
print(f"PROBE: localhost-bind → ✓ (bound + loopback GET → HTTP {r.status}, body={body!r})")
except Exception as e:
print(f"PROBE: localhost-bind → ✗ (bind ok, loopback GET: {type(e).__name__}: {e})")
finally:
server.shutdown()
s.close()
PY
Interpretation:
| Result | Status | Meaning |
|---|---|---|
✓ bound + loopback GET → HTTP 200 | Pass | Both bind and loopback HTTP work. |
✗ bind: ... | Fail | The sandbox blocks bind(2) on 127.0.0.1. Rare. |
✗ bind ok, loopback GET: ... | Fail | Bind works but the sandbox egress proxy refuses 127.0.0.1 as a destination. Common shape. |
On ✗ → remediation:
docs/setup/sandbox-troubleshooting.md — Test cannot bind to a localhost port.
Probe 3 — Docker / Podman runtime socket
Tests whether the runtime CLI can talk to its daemon. Run for
each of docker / podman that is on PATH; ⊘ each that is
not installed (this is not a sandbox failure, just an absent
prerequisite).
Command:
for rt in docker podman; do
if ! command -v "$rt" > /dev/null 2>&1; then
echo "PROBE: ${rt}-runtime → ⊘ ($rt not on PATH)"
continue
fi
out=$("$rt" info > /dev/null 2>&1 && echo ok || echo "fail:$?")
case "$out" in
ok)
echo "PROBE: ${rt}-runtime → ✓ (${rt} info returned)" ;;
fail:*)
err=$("$rt" info 2>&1 >/dev/null | head -2 | tr '\n' ' ')
echo "PROBE: ${rt}-runtime → ✗ ($out: $err)"
;;
esac
done
Interpretation:
| Result | Status | Meaning |
|---|---|---|
✓ <rt> info returned | Pass | The CLI reached the daemon successfully. |
✗ fail:1: Cannot connect to the Docker daemon … | Fail | Daemon socket not readable from inside the sandbox. |
✗ fail:1: connect: permission denied | Fail | Same root cause, different stderr (Linux variant). |
⊘ <rt> not on PATH | Skip | Runtime not installed; not a sandbox restriction. |
On ✗ → remediation:
docs/setup/sandbox-troubleshooting.md — Docker / Podman command fails with a socket error.
After the report
If every probe is ✓ or ⊘:
All three probes pass (or are not applicable). The sandbox is not currently blocking the known failure modes catalogued in
docs/setup/sandbox-troubleshooting.md. If you hit a different sandbox-shaped failure, follow the catalog's Adding a new entry section and (optionally) extend this skill with a fourth probe so future runs catch the same shape automatically.
If any probe is ✗:
- Surface every fail in one report (do not stop at the first).
- For each fail, print the troubleshooting-doc anchor link from the probe's On ✗ → remediation row above.
- Suggest the user open the catalog entry to read the symptom → root cause → fix shape, then apply the settings.json widening themselves. Do not propose to apply the widening from this skill — settings.json widenings are sandbox-bypass-adjacent and need an explicit user-driven edit.
- After the user has applied the widening (in a separate flow),
re-run
setup-isolated-setup-doctorto confirm the probe now passes.
If a probe surfaces a fail shape not catalogued in
docs/setup/sandbox-troubleshooting.md:
- Report the fail with the literal probe command + exit code + stderr.
- Suggest the user add a new entry to the catalog per its Adding a new entry section (symptom verbatim, root cause, fix, notes).
- Once the catalog has the new entry, extend this skill with a matching probe in the same shape so the next doctor run catches it automatically.
Extending the skill with a new probe
When the catalog grows a new entry, add a matching probe section following the shape above:
- Command — a short, deterministic, side-effect-free one-liner (or short Python heredoc) that triggers the failure mode reliably.
- Interpretation — a 3–5-row table mapping result strings to ✓ / ✗ / ⊘ / ⚠.
- On ✗ → remediation — a direct link to the matching
section of
docs/setup/sandbox-troubleshooting.md.
Keep probes narrowly scoped: each probe tests one failure mode, not a bundle. A probe that conflates two restrictions makes the report ambiguous when the result is ✗.