[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-apache-magpie-setup-isolated-setup-doctor":3,"mdc-p2fx0s-key":42,"related-repo-apache-magpie-setup-isolated-setup-doctor":2539,"related-org-apache-magpie-setup-isolated-setup-doctor":2637},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":25,"repoUrl":26,"updatedAt":27,"license":28,"forks":29,"topics":30,"repo":37,"sourceUrl":40,"mdContent":41},"magpie-setup-isolated-setup-doctor","diagnose secure agent setup restrictions","Probe the secure-agent setup for in-session functional\nrestrictions that block legitimate workflows. Three live\nprobes — SSH agent \u002F Yubikey reachability, localhost port\nbinding, docker \u002F podman runtime socket — each pointing the\nuser at the matching numbered troubleshooting entry and its\nsettings.json remediation (see body). Read-only — never\nmodifies settings.json, never invokes the sandbox bypass.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"apache","Apache Software Foundation","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fapache.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"Security","security","tag",{"name":17,"slug":18,"type":15},"Operations","operations",{"name":20,"slug":21,"type":15},"Engineering","engineering",{"name":23,"slug":24,"type":15},"Debugging","debugging",61,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fmagpie","2026-07-29T05:38:31.768054","Apache-2.0",42,[31,8,32,33,34,14,35,36],"agent-skills","automation","claude-code","cve","vulnerability-disclosure","vulnerability-management",{"repoUrl":26,"stars":25,"forks":29,"topics":38,"description":39},[31,8,32,33,34,14,35,36],"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.","https:\u002F\u002Fgithub.com\u002Fapache\u002Fmagpie\u002Ftree\u002FHEAD\u002Fskills\u002Fsetup-isolated-setup-doctor","---\n# SPDX-License-Identifier: Apache-2.0\n# https:\u002F\u002Fwww.apache.org\u002Flicenses\u002FLICENSE-2.0\nname: magpie-setup-isolated-setup-doctor\nfamily: setup\nmode: Meta\ndescription: |\n  Probe the secure-agent setup for in-session functional\n  restrictions that block legitimate workflows. Three live\n  probes — SSH agent \u002F Yubikey reachability, localhost port\n  binding, docker \u002F podman runtime socket — each pointing the\n  user at the matching numbered troubleshooting entry and its\n  settings.json remediation (see body). Read-only — never\n  modifies settings.json, never invokes the sandbox bypass.\nwhen_to_use: |\n  Invoke when the user says \"doctor my sandbox\", \"diagnose\n  sandbox friction\", \"why is the sandbox blocking X\", \"check\n  whether ssh \u002F docker \u002F port-bind works inside the sandbox\",\n  or after the user reports a workflow failure that smells\n  sandbox-shaped (agent unreachable, socket errors, port\n  permission errors). Also a good periodic check after every\n  Claude Code upgrade — the sandbox profile evolves and a\n  previously-working call may have moved into deny.\ncapability:\n  - capability:platform\n  - capability:reassess\nlicense: Apache-2.0\n---\n\n\u003C!-- Placeholder convention (see AGENTS.md#placeholder-convention-used-in-skill-files):\n     \u003Cproject-config> → adopting project's `.apache-magpie\u002F` directory -->\n\n# setup-isolated-setup-doctor\n\n## Runtime routing (run before the Claude-specific probes)\n\nWhen the active harness is Codex, first require the static verification in\n[docs\u002Fadapters\u002Fcodex.md](..\u002F..\u002Fdocs\u002Fadapters\u002Fcodex.md#verify), then run the\nshared live environment probes inside the active Codex sandbox. Attribute\nfailures separately to native sandbox\u002Fnetwork denial, approval policy, or\nthe POSIX agent-iso layer. Do not prescribe a `.claude` settings change for\na Codex failure. Then stop before the Claude-specific branch below.\n\nWhen the harness is Claude Code, continue below. If the harness cannot be\ndetermined, ask once.\n\nThe **diagnostic** layer over the secure agent setup. Complements\nthe existing setup skills:\n\n- [`setup-isolated-setup-install`](..\u002Fsetup-isolated-setup-install\u002FSKILL.md)\n  installs the secure setup.\n- [`setup-isolated-setup-verify`](..\u002Fsetup-isolated-setup-verify\u002FSKILL.md)\n  answers *\"is the secure setup **installed** correctly?\"* —\n  static checks on settings.json shape, hook wiring, pinned tool\n  versions. Catches drift and missing pieces.\n- [`setup-isolated-setup-update`](..\u002Fsetup-isolated-setup-update\u002FSKILL.md)\n  surfaces drift against the framework's latest.\n- **`setup-isolated-setup-doctor` (this skill)** answers *\"are\n  common workflows **functionally** blocked by the current\n  sandbox?\"* — live probes of SSH agent, port binding, docker \u002F\n  podman socket. Catches over-restrictive allowlists.\n\nRun `verify` first when the install is in question (fresh\nmachine, recent framework upgrade, sandbox-state surprise). Run\n`doctor` when the install is known good but a workflow fails in\na sandbox-shaped way — agent unreachable, socket error, port\npermission error.\n\nEvery probe maps to a numbered entry in\n[`docs\u002Fsetup\u002Fsandbox-troubleshooting.md`](..\u002F..\u002Fdocs\u002Fsetup\u002Fsandbox-troubleshooting.md);\nthe doctor's job is to identify *which* entry applies right now,\nnot to re-explain the remediation. If a fail surfaces a failure\nmode not catalogued there, propose appending a new entry per the\ncatalog's *Adding a new entry* section.\n\n## Golden rules\n\n- **Read-only.** Each probe runs a small, deterministic,\n  side-effect-free check. The skill never edits any settings\n  file, never runs a command with `dangerouslyDisableSandbox`,\n  never installs anything. If a check fails, surface the failure\n  and point at the catalog entry; do not auto-fix.\n- **Run every probe, even on early failure.** Do not stop at the\n  first ✗. The value of the report is in the full picture — a\n  user may have one of three independent restrictions, or all\n  three, and discovering them one re-run at a time is annoying.\n- **Distinguish ✗ (failing) from ⊘ (not applicable).** ✗ means\n  the probe ran and the sandbox blocked it. ⊘ means the probe\n  was skipped because the prerequisite is absent (e.g. no\n  `docker` \u002F `podman` on `PATH` → docker probe ⊘, not ✗).\n- **Surface evidence.** Each report line names the probe command,\n  the exit code, and the relevant stderr snippet. \"Looks\n  blocked\" is not a useful report; \"ssh-add -l → rc=2 →\n  `Could not open a connection to your authentication agent`\" is.\n- **Map each ✗ to a catalog entry.** The fail report includes a\n  direct link to the matching section of\n  [`docs\u002Fsetup\u002Fsandbox-troubleshooting.md`](..\u002F..\u002Fdocs\u002Fsetup\u002Fsandbox-troubleshooting.md).\n  Do not paraphrase the remediation — the catalog is the single\n  source of truth.\n\n## The 3 probes\n\nThe current set covers the three failure modes the catalog\ndocuments. New probes are added when new entries land in the\ncatalog; the two stay in lock-step.\n\n### Probe 1 — SSH agent \u002F Yubikey reachable\n\nTests whether `ssh-agent` is reachable from inside the sandbox.\nFailure mode: `SSH_AUTH_SOCK` is passed through `claude-iso`'s\nenv whitelist but the socket file is not in\n`sandbox.filesystem.allowRead`, so the agent's `ssh` \u002F\n`git push` subprocesses cannot `connect(2)` to the socket.\n\n**Command:**\n\n```bash\nif [ -z \"$SSH_AUTH_SOCK\" ]; then\n  echo \"PROBE: ssh-agent → ⊘ (SSH_AUTH_SOCK not set in env)\"\nelif [ ! -S \"$SSH_AUTH_SOCK\" ]; then\n  echo \"PROBE: ssh-agent → ✗ (socket file at SSH_AUTH_SOCK not stat-able from inside sandbox)\"\n  echo \"       SSH_AUTH_SOCK=$SSH_AUTH_SOCK\"\nelse\n  ssh-add -l > \u002Ftmp\u002Fssh-add.out 2>&1; rc=$?\n  case \"$rc\" in\n    0) echo \"PROBE: ssh-agent → ✓ ($(wc -l \u003C \u002Ftmp\u002Fssh-add.out | tr -d ' ') identities listed)\" ;;\n    1) echo \"PROBE: ssh-agent → ✓ (agent reachable, no identities configured)\" ;;\n    2) echo \"PROBE: ssh-agent → ✗ (agent unreachable: $(head -1 \u002Ftmp\u002Fssh-add.out))\" ;;\n    *) echo \"PROBE: ssh-agent → ⚠ (unexpected rc=$rc: $(head -1 \u002Ftmp\u002Fssh-add.out))\" ;;\n  esac\nfi\n```\n\n**Interpretation:**\n\n| Result | Status | Meaning |\n|---|---|---|\n| `✓ N identities listed` | Pass | `ssh-add -l` returned the key list. |\n| `✓ agent reachable, no identities` | Pass | `ssh-add -l` returned rc=1 (the documented \"no keys\" exit). |\n| `✗ socket not stat-able` | Fail | Sandbox blocks `stat(2)` on the socket file. |\n| `✗ agent unreachable` | Fail | Sandbox blocks `connect(2)` to the socket. |\n| `⊘ 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). |\n\n**On ✗ → remediation:**\n[`docs\u002Fsetup\u002Fsandbox-troubleshooting.md` — SSH agent \u002F Yubikey appears unreachable from inside the sandbox](..\u002F..\u002Fdocs\u002Fsetup\u002Fsandbox-troubleshooting.md#ssh-agent--yubikey-appears-unreachable-from-inside-the-sandbox).\n\n### Probe 2 — Localhost port bind\n\nTests whether a process inside the sandbox can bind to a\nloopback port AND then talk to itself over loopback. The\nfailure mode the catalog documents is the second half (egress\nproxy blocks `127.0.0.1`).\n\n**Command:**\n\n```bash\npython3 - \u003C\u003C'PY' 2>&1 || true\nimport socket, urllib.request, threading, http.server, sys\n\n# 1. Can we bind?\ntry:\n    s = socket.socket()\n    s.bind((\"127.0.0.1\", 0))\n    port = s.getsockname()[1]\n    s.listen(1)\nexcept OSError as e:\n    print(f\"PROBE: localhost-bind → ✗ (bind: {e})\")\n    sys.exit(0)\n\n# 2. Can we GET from our own server over loopback?\nclass Handler(http.server.BaseHTTPRequestHandler):\n    def do_GET(self):\n        self.send_response(200); self.end_headers(); self.wfile.write(b\"ok\")\n    def log_message(self, *_): pass\n\nserver = http.server.HTTPServer((\"127.0.0.1\", 0), Handler)\nthreading.Thread(target=server.serve_forever, daemon=True).start()\ntry:\n    with urllib.request.urlopen(f\"http:\u002F\u002F127.0.0.1:{server.server_port}\u002F\", timeout=5) as r:\n        body = r.read()\n    print(f\"PROBE: localhost-bind → ✓ (bound + loopback GET → HTTP {r.status}, body={body!r})\")\nexcept Exception as e:\n    print(f\"PROBE: localhost-bind → ✗ (bind ok, loopback GET: {type(e).__name__}: {e})\")\nfinally:\n    server.shutdown()\n    s.close()\nPY\n```\n\n**Interpretation:**\n\n| Result | Status | Meaning |\n|---|---|---|\n| `✓ bound + loopback GET → HTTP 200` | Pass | Both bind and loopback HTTP work. |\n| `✗ bind: ...` | Fail | The sandbox blocks `bind(2)` on `127.0.0.1`. Rare. |\n| `✗ bind ok, loopback GET: ...` | Fail | Bind works but the sandbox egress proxy refuses `127.0.0.1` as a destination. Common shape. |\n\n**On ✗ → remediation:**\n[`docs\u002Fsetup\u002Fsandbox-troubleshooting.md` — Test cannot bind to a localhost port](..\u002F..\u002Fdocs\u002Fsetup\u002Fsandbox-troubleshooting.md#test-cannot-bind-to-a-localhost-port).\n\n### Probe 3 — Docker \u002F Podman runtime socket\n\nTests whether the runtime CLI can talk to its daemon. Run for\neach of `docker` \u002F `podman` that is on `PATH`; ⊘ each that is\nnot installed (this is not a sandbox failure, just an absent\nprerequisite).\n\n**Command:**\n\n```bash\nfor rt in docker podman; do\n  if ! command -v \"$rt\" > \u002Fdev\u002Fnull 2>&1; then\n    echo \"PROBE: ${rt}-runtime → ⊘ ($rt not on PATH)\"\n    continue\n  fi\n  out=$(\"$rt\" info > \u002Fdev\u002Fnull 2>&1 && echo ok || echo \"fail:$?\")\n  case \"$out\" in\n    ok)\n      echo \"PROBE: ${rt}-runtime → ✓ (${rt} info returned)\" ;;\n    fail:*)\n      err=$(\"$rt\" info 2>&1 >\u002Fdev\u002Fnull | head -2 | tr '\\n' ' ')\n      echo \"PROBE: ${rt}-runtime → ✗ ($out: $err)\"\n      ;;\n  esac\ndone\n```\n\n**Interpretation:**\n\n| Result | Status | Meaning |\n|---|---|---|\n| `✓ \u003Crt> info returned` | Pass | The CLI reached the daemon successfully. |\n| `✗ fail:1: Cannot connect to the Docker daemon …` | Fail | Daemon socket not readable from inside the sandbox. |\n| `✗ fail:1: connect: permission denied` | Fail | Same root cause, different stderr (Linux variant). |\n| `⊘ \u003Crt> not on PATH` | Skip | Runtime not installed; not a sandbox restriction. |\n\n**On ✗ → remediation:**\n[`docs\u002Fsetup\u002Fsandbox-troubleshooting.md` — Docker \u002F Podman command fails with a socket error](..\u002F..\u002Fdocs\u002Fsetup\u002Fsandbox-troubleshooting.md#docker--podman-command-fails-with-a-socket-error).\n\n## After the report\n\nIf every probe is ✓ or ⊘:\n\n> All three probes pass (or are not applicable). The sandbox is\n> not currently blocking the known failure modes catalogued in\n> `docs\u002Fsetup\u002Fsandbox-troubleshooting.md`. If you hit a different\n> sandbox-shaped failure, follow the catalog's *Adding a new\n> entry* section and (optionally) extend this skill with a fourth\n> probe so future runs catch the same shape automatically.\n\nIf any probe is ✗:\n\n1. Surface every fail in one report (do not stop at the first).\n2. For each fail, print the troubleshooting-doc anchor link from\n   the probe's *On ✗ → remediation* row above.\n3. Suggest the user open the catalog entry to read the symptom →\n   root cause → fix shape, then apply the settings.json widening\n   themselves. Do **not** propose to apply the widening from this\n   skill — settings.json widenings are sandbox-bypass-adjacent\n   and need an explicit user-driven edit.\n4. After the user has applied the widening (in a separate flow),\n   re-run `setup-isolated-setup-doctor` to confirm the probe now\n   passes.\n\nIf a probe surfaces a fail shape not catalogued in\n[`docs\u002Fsetup\u002Fsandbox-troubleshooting.md`](..\u002F..\u002Fdocs\u002Fsetup\u002Fsandbox-troubleshooting.md):\n\n1. Report the fail with the literal probe command + exit code +\n   stderr.\n2. Suggest the user add a new entry to the catalog per its\n   *Adding a new entry* section (symptom verbatim, root cause,\n   fix, notes).\n3. Once the catalog has the new entry, extend this skill with a\n   matching probe in the same shape so the next doctor run\n   catches it automatically.\n\n## Extending the skill with a new probe\n\nWhen the catalog grows a new entry, add a matching probe section\nfollowing the shape above:\n\n1. **Command** — a short, deterministic, side-effect-free\n   one-liner (or short Python heredoc) that triggers the failure\n   mode reliably.\n2. **Interpretation** — a 3–5-row table mapping result strings\n   to ✓ \u002F ✗ \u002F ⊘ \u002F ⚠.\n3. **On ✗ → remediation** — a direct link to the matching\n   section of `docs\u002Fsetup\u002Fsandbox-troubleshooting.md`.\n\nKeep probes narrowly scoped: each probe tests **one** failure\nmode, not a bundle. A probe that conflates two restrictions\nmakes the report ambiguous when the result is ✗.\n",{"data":43,"body":50},{"name":4,"family":44,"mode":45,"description":6,"when_to_use":46,"capability":47,"license":28},"setup","Meta","Invoke when the user says \"doctor my sandbox\", \"diagnose\nsandbox friction\", \"why is the sandbox blocking X\", \"check\nwhether ssh \u002F docker \u002F port-bind works inside the sandbox\",\nor after the user reports a workflow failure that smells\nsandbox-shaped (agent unreachable, socket errors, port\npermission errors). Also a good periodic check after every\nClaude Code upgrade — the sandbox profile evolves and a\npreviously-working call may have moved into deny.\n",[48,49],"capability:platform","capability:reassess",{"type":51,"children":52},"root",[53,61,68,92,97,110,204,225,256,262,365,371,376,383,444,452,966,974,1153,1174,1180,1193,1200,1515,1522,1630,1649,1655,1680,1687,2215,2222,2330,2349,2355,2360,2383,2388,2433,2448,2472,2478,2483,2521,2533],{"type":54,"tag":55,"props":56,"children":58},"element","h1",{"id":57},"setup-isolated-setup-doctor",[59],{"type":60,"value":57},"text",{"type":54,"tag":62,"props":63,"children":65},"h2",{"id":64},"runtime-routing-run-before-the-claude-specific-probes",[66],{"type":60,"value":67},"Runtime routing (run before the Claude-specific probes)",{"type":54,"tag":69,"props":70,"children":71},"p",{},[72,74,81,83,90],{"type":60,"value":73},"When the active harness is Codex, first require the static verification in\n",{"type":54,"tag":75,"props":76,"children":78},"a",{"href":77},"..\u002F..\u002Fdocs\u002Fadapters\u002Fcodex.md#verify",[79],{"type":60,"value":80},"docs\u002Fadapters\u002Fcodex.md",{"type":60,"value":82},", then run the\nshared live environment probes inside the active Codex sandbox. Attribute\nfailures separately to native sandbox\u002Fnetwork denial, approval policy, or\nthe POSIX agent-iso layer. Do not prescribe a ",{"type":54,"tag":84,"props":85,"children":87},"code",{"className":86},[],[88],{"type":60,"value":89},".claude",{"type":60,"value":91}," settings change for\na Codex failure. Then stop before the Claude-specific branch below.",{"type":54,"tag":69,"props":93,"children":94},{},[95],{"type":60,"value":96},"When the harness is Claude Code, continue below. If the harness cannot be\ndetermined, ask once.",{"type":54,"tag":69,"props":98,"children":99},{},[100,102,108],{"type":60,"value":101},"The ",{"type":54,"tag":103,"props":104,"children":105},"strong",{},[106],{"type":60,"value":107},"diagnostic",{"type":60,"value":109}," layer over the secure agent setup. Complements\nthe existing setup skills:",{"type":54,"tag":111,"props":112,"children":113},"ul",{},[114,130,160,175],{"type":54,"tag":115,"props":116,"children":117},"li",{},[118,128],{"type":54,"tag":75,"props":119,"children":121},{"href":120},"..\u002Fsetup-isolated-setup-install\u002FSKILL.md",[122],{"type":54,"tag":84,"props":123,"children":125},{"className":124},[],[126],{"type":60,"value":127},"setup-isolated-setup-install",{"type":60,"value":129},"\ninstalls the secure setup.",{"type":54,"tag":115,"props":131,"children":132},{},[133,143,145,158],{"type":54,"tag":75,"props":134,"children":136},{"href":135},"..\u002Fsetup-isolated-setup-verify\u002FSKILL.md",[137],{"type":54,"tag":84,"props":138,"children":140},{"className":139},[],[141],{"type":60,"value":142},"setup-isolated-setup-verify",{"type":60,"value":144},"\nanswers ",{"type":54,"tag":146,"props":147,"children":148},"em",{},[149,151,156],{"type":60,"value":150},"\"is the secure setup ",{"type":54,"tag":103,"props":152,"children":153},{},[154],{"type":60,"value":155},"installed",{"type":60,"value":157}," correctly?\"",{"type":60,"value":159}," —\nstatic checks on settings.json shape, hook wiring, pinned tool\nversions. Catches drift and missing pieces.",{"type":54,"tag":115,"props":161,"children":162},{},[163,173],{"type":54,"tag":75,"props":164,"children":166},{"href":165},"..\u002Fsetup-isolated-setup-update\u002FSKILL.md",[167],{"type":54,"tag":84,"props":168,"children":170},{"className":169},[],[171],{"type":60,"value":172},"setup-isolated-setup-update",{"type":60,"value":174},"\nsurfaces drift against the framework's latest.",{"type":54,"tag":115,"props":176,"children":177},{},[178,188,190,202],{"type":54,"tag":103,"props":179,"children":180},{},[181,186],{"type":54,"tag":84,"props":182,"children":184},{"className":183},[],[185],{"type":60,"value":57},{"type":60,"value":187}," (this skill)",{"type":60,"value":189}," answers ",{"type":54,"tag":146,"props":191,"children":192},{},[193,195,200],{"type":60,"value":194},"\"are\ncommon workflows ",{"type":54,"tag":103,"props":196,"children":197},{},[198],{"type":60,"value":199},"functionally",{"type":60,"value":201}," blocked by the current\nsandbox?\"",{"type":60,"value":203}," — live probes of SSH agent, port binding, docker \u002F\npodman socket. Catches over-restrictive allowlists.",{"type":54,"tag":69,"props":205,"children":206},{},[207,209,215,217,223],{"type":60,"value":208},"Run ",{"type":54,"tag":84,"props":210,"children":212},{"className":211},[],[213],{"type":60,"value":214},"verify",{"type":60,"value":216}," first when the install is in question (fresh\nmachine, recent framework upgrade, sandbox-state surprise). Run\n",{"type":54,"tag":84,"props":218,"children":220},{"className":219},[],[221],{"type":60,"value":222},"doctor",{"type":60,"value":224}," when the install is known good but a workflow fails in\na sandbox-shaped way — agent unreachable, socket error, port\npermission error.",{"type":54,"tag":69,"props":226,"children":227},{},[228,230,240,242,247,249,254],{"type":60,"value":229},"Every probe maps to a numbered entry in\n",{"type":54,"tag":75,"props":231,"children":233},{"href":232},"..\u002F..\u002Fdocs\u002Fsetup\u002Fsandbox-troubleshooting.md",[234],{"type":54,"tag":84,"props":235,"children":237},{"className":236},[],[238],{"type":60,"value":239},"docs\u002Fsetup\u002Fsandbox-troubleshooting.md",{"type":60,"value":241},";\nthe doctor's job is to identify ",{"type":54,"tag":146,"props":243,"children":244},{},[245],{"type":60,"value":246},"which",{"type":60,"value":248}," entry applies right now,\nnot to re-explain the remediation. If a fail surfaces a failure\nmode not catalogued there, propose appending a new entry per the\ncatalog's ",{"type":54,"tag":146,"props":250,"children":251},{},[252],{"type":60,"value":253},"Adding a new entry",{"type":60,"value":255}," section.",{"type":54,"tag":62,"props":257,"children":259},{"id":258},"golden-rules",[260],{"type":60,"value":261},"Golden rules",{"type":54,"tag":111,"props":263,"children":264},{},[265,283,293,327,345],{"type":54,"tag":115,"props":266,"children":267},{},[268,273,275,281],{"type":54,"tag":103,"props":269,"children":270},{},[271],{"type":60,"value":272},"Read-only.",{"type":60,"value":274}," Each probe runs a small, deterministic,\nside-effect-free check. The skill never edits any settings\nfile, never runs a command with ",{"type":54,"tag":84,"props":276,"children":278},{"className":277},[],[279],{"type":60,"value":280},"dangerouslyDisableSandbox",{"type":60,"value":282},",\nnever installs anything. If a check fails, surface the failure\nand point at the catalog entry; do not auto-fix.",{"type":54,"tag":115,"props":284,"children":285},{},[286,291],{"type":54,"tag":103,"props":287,"children":288},{},[289],{"type":60,"value":290},"Run every probe, even on early failure.",{"type":60,"value":292}," Do not stop at the\nfirst ✗. The value of the report is in the full picture — a\nuser may have one of three independent restrictions, or all\nthree, and discovering them one re-run at a time is annoying.",{"type":54,"tag":115,"props":294,"children":295},{},[296,301,303,309,311,317,319,325],{"type":54,"tag":103,"props":297,"children":298},{},[299],{"type":60,"value":300},"Distinguish ✗ (failing) from ⊘ (not applicable).",{"type":60,"value":302}," ✗ means\nthe probe ran and the sandbox blocked it. ⊘ means the probe\nwas skipped because the prerequisite is absent (e.g. no\n",{"type":54,"tag":84,"props":304,"children":306},{"className":305},[],[307],{"type":60,"value":308},"docker",{"type":60,"value":310}," \u002F ",{"type":54,"tag":84,"props":312,"children":314},{"className":313},[],[315],{"type":60,"value":316},"podman",{"type":60,"value":318}," on ",{"type":54,"tag":84,"props":320,"children":322},{"className":321},[],[323],{"type":60,"value":324},"PATH",{"type":60,"value":326}," → docker probe ⊘, not ✗).",{"type":54,"tag":115,"props":328,"children":329},{},[330,335,337,343],{"type":54,"tag":103,"props":331,"children":332},{},[333],{"type":60,"value":334},"Surface evidence.",{"type":60,"value":336}," Each report line names the probe command,\nthe exit code, and the relevant stderr snippet. \"Looks\nblocked\" is not a useful report; \"ssh-add -l → rc=2 →\n",{"type":54,"tag":84,"props":338,"children":340},{"className":339},[],[341],{"type":60,"value":342},"Could not open a connection to your authentication agent",{"type":60,"value":344},"\" is.",{"type":54,"tag":115,"props":346,"children":347},{},[348,353,355,363],{"type":54,"tag":103,"props":349,"children":350},{},[351],{"type":60,"value":352},"Map each ✗ to a catalog entry.",{"type":60,"value":354}," The fail report includes a\ndirect link to the matching section of\n",{"type":54,"tag":75,"props":356,"children":357},{"href":232},[358],{"type":54,"tag":84,"props":359,"children":361},{"className":360},[],[362],{"type":60,"value":239},{"type":60,"value":364},".\nDo not paraphrase the remediation — the catalog is the single\nsource of truth.",{"type":54,"tag":62,"props":366,"children":368},{"id":367},"the-3-probes",[369],{"type":60,"value":370},"The 3 probes",{"type":54,"tag":69,"props":372,"children":373},{},[374],{"type":60,"value":375},"The current set covers the three failure modes the catalog\ndocuments. New probes are added when new entries land in the\ncatalog; the two stay in lock-step.",{"type":54,"tag":377,"props":378,"children":380},"h3",{"id":379},"probe-1-ssh-agent-yubikey-reachable",[381],{"type":60,"value":382},"Probe 1 — SSH agent \u002F Yubikey reachable",{"type":54,"tag":69,"props":384,"children":385},{},[386,388,394,396,402,404,410,412,418,420,426,428,434,436,442],{"type":60,"value":387},"Tests whether ",{"type":54,"tag":84,"props":389,"children":391},{"className":390},[],[392],{"type":60,"value":393},"ssh-agent",{"type":60,"value":395}," is reachable from inside the sandbox.\nFailure mode: ",{"type":54,"tag":84,"props":397,"children":399},{"className":398},[],[400],{"type":60,"value":401},"SSH_AUTH_SOCK",{"type":60,"value":403}," is passed through ",{"type":54,"tag":84,"props":405,"children":407},{"className":406},[],[408],{"type":60,"value":409},"claude-iso",{"type":60,"value":411},"'s\nenv whitelist but the socket file is not in\n",{"type":54,"tag":84,"props":413,"children":415},{"className":414},[],[416],{"type":60,"value":417},"sandbox.filesystem.allowRead",{"type":60,"value":419},", so the agent's ",{"type":54,"tag":84,"props":421,"children":423},{"className":422},[],[424],{"type":60,"value":425},"ssh",{"type":60,"value":427}," \u002F\n",{"type":54,"tag":84,"props":429,"children":431},{"className":430},[],[432],{"type":60,"value":433},"git push",{"type":60,"value":435}," subprocesses cannot ",{"type":54,"tag":84,"props":437,"children":439},{"className":438},[],[440],{"type":60,"value":441},"connect(2)",{"type":60,"value":443}," to the socket.",{"type":54,"tag":69,"props":445,"children":446},{},[447],{"type":54,"tag":103,"props":448,"children":449},{},[450],{"type":60,"value":451},"Command:",{"type":54,"tag":453,"props":454,"children":459},"pre",{"className":455,"code":456,"language":457,"meta":458,"style":458},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","if [ -z \"$SSH_AUTH_SOCK\" ]; then\n  echo \"PROBE: ssh-agent → ⊘ (SSH_AUTH_SOCK not set in env)\"\nelif [ ! -S \"$SSH_AUTH_SOCK\" ]; then\n  echo \"PROBE: ssh-agent → ✗ (socket file at SSH_AUTH_SOCK not stat-able from inside sandbox)\"\n  echo \"       SSH_AUTH_SOCK=$SSH_AUTH_SOCK\"\nelse\n  ssh-add -l > \u002Ftmp\u002Fssh-add.out 2>&1; rc=$?\n  case \"$rc\" in\n    0) echo \"PROBE: ssh-agent → ✓ ($(wc -l \u003C \u002Ftmp\u002Fssh-add.out | tr -d ' ') identities listed)\" ;;\n    1) echo \"PROBE: ssh-agent → ✓ (agent reachable, no identities configured)\" ;;\n    2) echo \"PROBE: ssh-agent → ✗ (agent unreachable: $(head -1 \u002Ftmp\u002Fssh-add.out))\" ;;\n    *) echo \"PROBE: ssh-agent → ⚠ (unexpected rc=$rc: $(head -1 \u002Ftmp\u002Fssh-add.out))\" ;;\n  esac\nfi\n","bash","",[460],{"type":54,"tag":84,"props":461,"children":462},{"__ignoreMap":458},[463,512,537,580,601,626,635,680,707,799,833,889,948,957],{"type":54,"tag":464,"props":465,"children":468},"span",{"class":466,"line":467},"line",1,[469,475,481,486,491,497,502,507],{"type":54,"tag":464,"props":470,"children":472},{"style":471},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[473],{"type":60,"value":474},"if",{"type":54,"tag":464,"props":476,"children":478},{"style":477},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[479],{"type":60,"value":480}," [",{"type":54,"tag":464,"props":482,"children":483},{"style":477},[484],{"type":60,"value":485}," -z",{"type":54,"tag":464,"props":487,"children":488},{"style":477},[489],{"type":60,"value":490}," \"",{"type":54,"tag":464,"props":492,"children":494},{"style":493},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[495],{"type":60,"value":496},"$SSH_AUTH_SOCK",{"type":54,"tag":464,"props":498,"children":499},{"style":477},[500],{"type":60,"value":501},"\"",{"type":54,"tag":464,"props":503,"children":504},{"style":477},[505],{"type":60,"value":506}," ];",{"type":54,"tag":464,"props":508,"children":509},{"style":471},[510],{"type":60,"value":511}," then\n",{"type":54,"tag":464,"props":513,"children":515},{"class":466,"line":514},2,[516,522,526,532],{"type":54,"tag":464,"props":517,"children":519},{"style":518},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[520],{"type":60,"value":521},"  echo",{"type":54,"tag":464,"props":523,"children":524},{"style":477},[525],{"type":60,"value":490},{"type":54,"tag":464,"props":527,"children":529},{"style":528},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[530],{"type":60,"value":531},"PROBE: ssh-agent → ⊘ (SSH_AUTH_SOCK not set in env)",{"type":54,"tag":464,"props":533,"children":534},{"style":477},[535],{"type":60,"value":536},"\"\n",{"type":54,"tag":464,"props":538,"children":540},{"class":466,"line":539},3,[541,546,550,555,560,564,568,572,576],{"type":54,"tag":464,"props":542,"children":543},{"style":471},[544],{"type":60,"value":545},"elif",{"type":54,"tag":464,"props":547,"children":548},{"style":477},[549],{"type":60,"value":480},{"type":54,"tag":464,"props":551,"children":552},{"style":477},[553],{"type":60,"value":554}," !",{"type":54,"tag":464,"props":556,"children":557},{"style":477},[558],{"type":60,"value":559}," -S",{"type":54,"tag":464,"props":561,"children":562},{"style":477},[563],{"type":60,"value":490},{"type":54,"tag":464,"props":565,"children":566},{"style":493},[567],{"type":60,"value":496},{"type":54,"tag":464,"props":569,"children":570},{"style":477},[571],{"type":60,"value":501},{"type":54,"tag":464,"props":573,"children":574},{"style":477},[575],{"type":60,"value":506},{"type":54,"tag":464,"props":577,"children":578},{"style":471},[579],{"type":60,"value":511},{"type":54,"tag":464,"props":581,"children":583},{"class":466,"line":582},4,[584,588,592,597],{"type":54,"tag":464,"props":585,"children":586},{"style":518},[587],{"type":60,"value":521},{"type":54,"tag":464,"props":589,"children":590},{"style":477},[591],{"type":60,"value":490},{"type":54,"tag":464,"props":593,"children":594},{"style":528},[595],{"type":60,"value":596},"PROBE: ssh-agent → ✗ (socket file at SSH_AUTH_SOCK not stat-able from inside sandbox)",{"type":54,"tag":464,"props":598,"children":599},{"style":477},[600],{"type":60,"value":536},{"type":54,"tag":464,"props":602,"children":604},{"class":466,"line":603},5,[605,609,613,618,622],{"type":54,"tag":464,"props":606,"children":607},{"style":518},[608],{"type":60,"value":521},{"type":54,"tag":464,"props":610,"children":611},{"style":477},[612],{"type":60,"value":490},{"type":54,"tag":464,"props":614,"children":615},{"style":528},[616],{"type":60,"value":617},"       SSH_AUTH_SOCK=",{"type":54,"tag":464,"props":619,"children":620},{"style":493},[621],{"type":60,"value":496},{"type":54,"tag":464,"props":623,"children":624},{"style":477},[625],{"type":60,"value":536},{"type":54,"tag":464,"props":627,"children":629},{"class":466,"line":628},6,[630],{"type":54,"tag":464,"props":631,"children":632},{"style":471},[633],{"type":60,"value":634},"else\n",{"type":54,"tag":464,"props":636,"children":638},{"class":466,"line":637},7,[639,645,650,655,660,665,670,675],{"type":54,"tag":464,"props":640,"children":642},{"style":641},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[643],{"type":60,"value":644},"  ssh-add",{"type":54,"tag":464,"props":646,"children":647},{"style":528},[648],{"type":60,"value":649}," -l",{"type":54,"tag":464,"props":651,"children":652},{"style":477},[653],{"type":60,"value":654}," >",{"type":54,"tag":464,"props":656,"children":657},{"style":528},[658],{"type":60,"value":659}," \u002Ftmp\u002Fssh-add.out",{"type":54,"tag":464,"props":661,"children":662},{"style":477},[663],{"type":60,"value":664}," 2>&1;",{"type":54,"tag":464,"props":666,"children":667},{"style":493},[668],{"type":60,"value":669}," rc",{"type":54,"tag":464,"props":671,"children":672},{"style":477},[673],{"type":60,"value":674},"=",{"type":54,"tag":464,"props":676,"children":677},{"style":493},[678],{"type":60,"value":679},"$?\n",{"type":54,"tag":464,"props":681,"children":683},{"class":466,"line":682},8,[684,689,693,698,702],{"type":54,"tag":464,"props":685,"children":686},{"style":471},[687],{"type":60,"value":688},"  case",{"type":54,"tag":464,"props":690,"children":691},{"style":477},[692],{"type":60,"value":490},{"type":54,"tag":464,"props":694,"children":695},{"style":493},[696],{"type":60,"value":697},"$rc",{"type":54,"tag":464,"props":699,"children":700},{"style":477},[701],{"type":60,"value":501},{"type":54,"tag":464,"props":703,"children":704},{"style":471},[705],{"type":60,"value":706}," in\n",{"type":54,"tag":464,"props":708,"children":710},{"class":466,"line":709},9,[711,716,721,726,730,735,740,745,750,755,760,765,770,775,780,785,790,794],{"type":54,"tag":464,"props":712,"children":713},{"style":528},[714],{"type":60,"value":715},"    0",{"type":54,"tag":464,"props":717,"children":718},{"style":477},[719],{"type":60,"value":720},")",{"type":54,"tag":464,"props":722,"children":723},{"style":518},[724],{"type":60,"value":725}," echo",{"type":54,"tag":464,"props":727,"children":728},{"style":477},[729],{"type":60,"value":490},{"type":54,"tag":464,"props":731,"children":732},{"style":528},[733],{"type":60,"value":734},"PROBE: ssh-agent → ✓ (",{"type":54,"tag":464,"props":736,"children":737},{"style":477},[738],{"type":60,"value":739},"$(",{"type":54,"tag":464,"props":741,"children":742},{"style":641},[743],{"type":60,"value":744},"wc",{"type":54,"tag":464,"props":746,"children":747},{"style":528},[748],{"type":60,"value":749}," -l ",{"type":54,"tag":464,"props":751,"children":752},{"style":477},[753],{"type":60,"value":754},"\u003C",{"type":54,"tag":464,"props":756,"children":757},{"style":528},[758],{"type":60,"value":759}," \u002Ftmp\u002Fssh-add.out ",{"type":54,"tag":464,"props":761,"children":762},{"style":477},[763],{"type":60,"value":764},"|",{"type":54,"tag":464,"props":766,"children":767},{"style":641},[768],{"type":60,"value":769}," tr",{"type":54,"tag":464,"props":771,"children":772},{"style":528},[773],{"type":60,"value":774}," -d ",{"type":54,"tag":464,"props":776,"children":777},{"style":477},[778],{"type":60,"value":779},"'",{"type":54,"tag":464,"props":781,"children":782},{"style":477},[783],{"type":60,"value":784}," ')",{"type":54,"tag":464,"props":786,"children":787},{"style":528},[788],{"type":60,"value":789}," identities listed)",{"type":54,"tag":464,"props":791,"children":792},{"style":477},[793],{"type":60,"value":501},{"type":54,"tag":464,"props":795,"children":796},{"style":477},[797],{"type":60,"value":798}," ;;\n",{"type":54,"tag":464,"props":800,"children":802},{"class":466,"line":801},10,[803,808,812,816,820,825,829],{"type":54,"tag":464,"props":804,"children":805},{"style":528},[806],{"type":60,"value":807},"    1",{"type":54,"tag":464,"props":809,"children":810},{"style":477},[811],{"type":60,"value":720},{"type":54,"tag":464,"props":813,"children":814},{"style":518},[815],{"type":60,"value":725},{"type":54,"tag":464,"props":817,"children":818},{"style":477},[819],{"type":60,"value":490},{"type":54,"tag":464,"props":821,"children":822},{"style":528},[823],{"type":60,"value":824},"PROBE: ssh-agent → ✓ (agent reachable, no identities configured)",{"type":54,"tag":464,"props":826,"children":827},{"style":477},[828],{"type":60,"value":501},{"type":54,"tag":464,"props":830,"children":831},{"style":477},[832],{"type":60,"value":798},{"type":54,"tag":464,"props":834,"children":836},{"class":466,"line":835},11,[837,842,846,850,854,859,863,868,873,877,881,885],{"type":54,"tag":464,"props":838,"children":839},{"style":528},[840],{"type":60,"value":841},"    2",{"type":54,"tag":464,"props":843,"children":844},{"style":477},[845],{"type":60,"value":720},{"type":54,"tag":464,"props":847,"children":848},{"style":518},[849],{"type":60,"value":725},{"type":54,"tag":464,"props":851,"children":852},{"style":477},[853],{"type":60,"value":490},{"type":54,"tag":464,"props":855,"children":856},{"style":528},[857],{"type":60,"value":858},"PROBE: ssh-agent → ✗ (agent unreachable: ",{"type":54,"tag":464,"props":860,"children":861},{"style":477},[862],{"type":60,"value":739},{"type":54,"tag":464,"props":864,"children":865},{"style":641},[866],{"type":60,"value":867},"head",{"type":54,"tag":464,"props":869,"children":870},{"style":528},[871],{"type":60,"value":872}," -1 \u002Ftmp\u002Fssh-add.out",{"type":54,"tag":464,"props":874,"children":875},{"style":477},[876],{"type":60,"value":720},{"type":54,"tag":464,"props":878,"children":879},{"style":528},[880],{"type":60,"value":720},{"type":54,"tag":464,"props":882,"children":883},{"style":477},[884],{"type":60,"value":501},{"type":54,"tag":464,"props":886,"children":887},{"style":477},[888],{"type":60,"value":798},{"type":54,"tag":464,"props":890,"children":892},{"class":466,"line":891},12,[893,898,902,906,911,915,920,924,928,932,936,940,944],{"type":54,"tag":464,"props":894,"children":895},{"style":477},[896],{"type":60,"value":897},"    *)",{"type":54,"tag":464,"props":899,"children":900},{"style":518},[901],{"type":60,"value":725},{"type":54,"tag":464,"props":903,"children":904},{"style":477},[905],{"type":60,"value":490},{"type":54,"tag":464,"props":907,"children":908},{"style":528},[909],{"type":60,"value":910},"PROBE: ssh-agent → ⚠ (unexpected rc=",{"type":54,"tag":464,"props":912,"children":913},{"style":493},[914],{"type":60,"value":697},{"type":54,"tag":464,"props":916,"children":917},{"style":528},[918],{"type":60,"value":919},": ",{"type":54,"tag":464,"props":921,"children":922},{"style":477},[923],{"type":60,"value":739},{"type":54,"tag":464,"props":925,"children":926},{"style":641},[927],{"type":60,"value":867},{"type":54,"tag":464,"props":929,"children":930},{"style":528},[931],{"type":60,"value":872},{"type":54,"tag":464,"props":933,"children":934},{"style":477},[935],{"type":60,"value":720},{"type":54,"tag":464,"props":937,"children":938},{"style":528},[939],{"type":60,"value":720},{"type":54,"tag":464,"props":941,"children":942},{"style":477},[943],{"type":60,"value":501},{"type":54,"tag":464,"props":945,"children":946},{"style":477},[947],{"type":60,"value":798},{"type":54,"tag":464,"props":949,"children":951},{"class":466,"line":950},13,[952],{"type":54,"tag":464,"props":953,"children":954},{"style":471},[955],{"type":60,"value":956},"  esac\n",{"type":54,"tag":464,"props":958,"children":960},{"class":466,"line":959},14,[961],{"type":54,"tag":464,"props":962,"children":963},{"style":471},[964],{"type":60,"value":965},"fi\n",{"type":54,"tag":69,"props":967,"children":968},{},[969],{"type":54,"tag":103,"props":970,"children":971},{},[972],{"type":60,"value":973},"Interpretation:",{"type":54,"tag":975,"props":976,"children":977},"table",{},[978,1002],{"type":54,"tag":979,"props":980,"children":981},"thead",{},[982],{"type":54,"tag":983,"props":984,"children":985},"tr",{},[986,992,997],{"type":54,"tag":987,"props":988,"children":989},"th",{},[990],{"type":60,"value":991},"Result",{"type":54,"tag":987,"props":993,"children":994},{},[995],{"type":60,"value":996},"Status",{"type":54,"tag":987,"props":998,"children":999},{},[1000],{"type":60,"value":1001},"Meaning",{"type":54,"tag":1003,"props":1004,"children":1005},"tbody",{},[1006,1035,1061,1091,1117],{"type":54,"tag":983,"props":1007,"children":1008},{},[1009,1019,1024],{"type":54,"tag":1010,"props":1011,"children":1012},"td",{},[1013],{"type":54,"tag":84,"props":1014,"children":1016},{"className":1015},[],[1017],{"type":60,"value":1018},"✓ N identities listed",{"type":54,"tag":1010,"props":1020,"children":1021},{},[1022],{"type":60,"value":1023},"Pass",{"type":54,"tag":1010,"props":1025,"children":1026},{},[1027,1033],{"type":54,"tag":84,"props":1028,"children":1030},{"className":1029},[],[1031],{"type":60,"value":1032},"ssh-add -l",{"type":60,"value":1034}," returned the key list.",{"type":54,"tag":983,"props":1036,"children":1037},{},[1038,1047,1051],{"type":54,"tag":1010,"props":1039,"children":1040},{},[1041],{"type":54,"tag":84,"props":1042,"children":1044},{"className":1043},[],[1045],{"type":60,"value":1046},"✓ agent reachable, no identities",{"type":54,"tag":1010,"props":1048,"children":1049},{},[1050],{"type":60,"value":1023},{"type":54,"tag":1010,"props":1052,"children":1053},{},[1054,1059],{"type":54,"tag":84,"props":1055,"children":1057},{"className":1056},[],[1058],{"type":60,"value":1032},{"type":60,"value":1060}," returned rc=1 (the documented \"no keys\" exit).",{"type":54,"tag":983,"props":1062,"children":1063},{},[1064,1073,1078],{"type":54,"tag":1010,"props":1065,"children":1066},{},[1067],{"type":54,"tag":84,"props":1068,"children":1070},{"className":1069},[],[1071],{"type":60,"value":1072},"✗ socket not stat-able",{"type":54,"tag":1010,"props":1074,"children":1075},{},[1076],{"type":60,"value":1077},"Fail",{"type":54,"tag":1010,"props":1079,"children":1080},{},[1081,1083,1089],{"type":60,"value":1082},"Sandbox blocks ",{"type":54,"tag":84,"props":1084,"children":1086},{"className":1085},[],[1087],{"type":60,"value":1088},"stat(2)",{"type":60,"value":1090}," on the socket file.",{"type":54,"tag":983,"props":1092,"children":1093},{},[1094,1103,1107],{"type":54,"tag":1010,"props":1095,"children":1096},{},[1097],{"type":54,"tag":84,"props":1098,"children":1100},{"className":1099},[],[1101],{"type":60,"value":1102},"✗ agent unreachable",{"type":54,"tag":1010,"props":1104,"children":1105},{},[1106],{"type":60,"value":1077},{"type":54,"tag":1010,"props":1108,"children":1109},{},[1110,1111,1116],{"type":60,"value":1082},{"type":54,"tag":84,"props":1112,"children":1114},{"className":1113},[],[1115],{"type":60,"value":441},{"type":60,"value":443},{"type":54,"tag":983,"props":1118,"children":1119},{},[1120,1129,1134],{"type":54,"tag":1010,"props":1121,"children":1122},{},[1123],{"type":54,"tag":84,"props":1124,"children":1126},{"className":1125},[],[1127],{"type":60,"value":1128},"⊘ SSH_AUTH_SOCK not set",{"type":54,"tag":1010,"props":1130,"children":1131},{},[1132],{"type":60,"value":1133},"Skip",{"type":54,"tag":1010,"props":1135,"children":1136},{},[1137,1139,1144,1146,1151],{"type":60,"value":1138},"Either the user does not run ",{"type":54,"tag":84,"props":1140,"children":1142},{"className":1141},[],[1143],{"type":60,"value":393},{"type":60,"value":1145},", or ",{"type":54,"tag":84,"props":1147,"children":1149},{"className":1148},[],[1150],{"type":60,"value":409},{"type":60,"value":1152},"'s env whitelist dropped it (separate bug — verify).",{"type":54,"tag":69,"props":1154,"children":1155},{},[1156,1161,1172],{"type":54,"tag":103,"props":1157,"children":1158},{},[1159],{"type":60,"value":1160},"On ✗ → remediation:",{"type":54,"tag":75,"props":1162,"children":1164},{"href":1163},"..\u002F..\u002Fdocs\u002Fsetup\u002Fsandbox-troubleshooting.md#ssh-agent--yubikey-appears-unreachable-from-inside-the-sandbox",[1165,1170],{"type":54,"tag":84,"props":1166,"children":1168},{"className":1167},[],[1169],{"type":60,"value":239},{"type":60,"value":1171}," — SSH agent \u002F Yubikey appears unreachable from inside the sandbox",{"type":60,"value":1173},".",{"type":54,"tag":377,"props":1175,"children":1177},{"id":1176},"probe-2-localhost-port-bind",[1178],{"type":60,"value":1179},"Probe 2 — Localhost port bind",{"type":54,"tag":69,"props":1181,"children":1182},{},[1183,1185,1191],{"type":60,"value":1184},"Tests whether a process inside the sandbox can bind to a\nloopback port AND then talk to itself over loopback. The\nfailure mode the catalog documents is the second half (egress\nproxy blocks ",{"type":54,"tag":84,"props":1186,"children":1188},{"className":1187},[],[1189],{"type":60,"value":1190},"127.0.0.1",{"type":60,"value":1192},").",{"type":54,"tag":69,"props":1194,"children":1195},{},[1196],{"type":54,"tag":103,"props":1197,"children":1198},{},[1199],{"type":60,"value":451},{"type":54,"tag":453,"props":1201,"children":1203},{"className":455,"code":1202,"language":457,"meta":458,"style":458},"python3 - \u003C\u003C'PY' 2>&1 || true\nimport socket, urllib.request, threading, http.server, sys\n\n# 1. Can we bind?\ntry:\n    s = socket.socket()\n    s.bind((\"127.0.0.1\", 0))\n    port = s.getsockname()[1]\n    s.listen(1)\nexcept OSError as e:\n    print(f\"PROBE: localhost-bind → ✗ (bind: {e})\")\n    sys.exit(0)\n\n# 2. Can we GET from our own server over loopback?\nclass Handler(http.server.BaseHTTPRequestHandler):\n    def do_GET(self):\n        self.send_response(200); self.end_headers(); self.wfile.write(b\"ok\")\n    def log_message(self, *_): pass\n\nserver = http.server.HTTPServer((\"127.0.0.1\", 0), Handler)\nthreading.Thread(target=server.serve_forever, daemon=True).start()\ntry:\n    with urllib.request.urlopen(f\"http:\u002F\u002F127.0.0.1:{server.server_port}\u002F\", timeout=5) as r:\n        body = r.read()\n    print(f\"PROBE: localhost-bind → ✓ (bound + loopback GET → HTTP {r.status}, body={body!r})\")\nexcept Exception as e:\n    print(f\"PROBE: localhost-bind → ✗ (bind ok, loopback GET: {type(e).__name__}: {e})\")\nfinally:\n    server.shutdown()\n    s.close()\nPY\n",[1204],{"type":54,"tag":84,"props":1205,"children":1206},{"__ignoreMap":458},[1207,1260,1268,1277,1285,1293,1301,1309,1317,1325,1333,1341,1349,1356,1364,1373,1382,1391,1400,1408,1417,1426,1434,1443,1452,1461,1470,1479,1488,1497,1506],{"type":54,"tag":464,"props":1208,"children":1209},{"class":466,"line":467},[1210,1215,1220,1225,1230,1235,1240,1245,1250,1255],{"type":54,"tag":464,"props":1211,"children":1212},{"style":641},[1213],{"type":60,"value":1214},"python3",{"type":54,"tag":464,"props":1216,"children":1217},{"style":528},[1218],{"type":60,"value":1219}," -",{"type":54,"tag":464,"props":1221,"children":1222},{"style":477},[1223],{"type":60,"value":1224}," \u003C\u003C",{"type":54,"tag":464,"props":1226,"children":1227},{"style":477},[1228],{"type":60,"value":1229},"'PY'",{"type":54,"tag":464,"props":1231,"children":1232},{"style":641},[1233],{"type":60,"value":1234}," 2",{"type":54,"tag":464,"props":1236,"children":1237},{"style":493},[1238],{"type":60,"value":1239},">",{"type":54,"tag":464,"props":1241,"children":1242},{"style":477},[1243],{"type":60,"value":1244},"&",{"type":54,"tag":464,"props":1246,"children":1247},{"style":641},[1248],{"type":60,"value":1249},"1",{"type":54,"tag":464,"props":1251,"children":1252},{"style":477},[1253],{"type":60,"value":1254}," ||",{"type":54,"tag":464,"props":1256,"children":1257},{"style":518},[1258],{"type":60,"value":1259}," true\n",{"type":54,"tag":464,"props":1261,"children":1262},{"class":466,"line":514},[1263],{"type":54,"tag":464,"props":1264,"children":1265},{"style":528},[1266],{"type":60,"value":1267},"import socket, urllib.request, threading, http.server, sys\n",{"type":54,"tag":464,"props":1269,"children":1270},{"class":466,"line":539},[1271],{"type":54,"tag":464,"props":1272,"children":1274},{"emptyLinePlaceholder":1273},true,[1275],{"type":60,"value":1276},"\n",{"type":54,"tag":464,"props":1278,"children":1279},{"class":466,"line":582},[1280],{"type":54,"tag":464,"props":1281,"children":1282},{"style":528},[1283],{"type":60,"value":1284},"# 1. Can we bind?\n",{"type":54,"tag":464,"props":1286,"children":1287},{"class":466,"line":603},[1288],{"type":54,"tag":464,"props":1289,"children":1290},{"style":528},[1291],{"type":60,"value":1292},"try:\n",{"type":54,"tag":464,"props":1294,"children":1295},{"class":466,"line":628},[1296],{"type":54,"tag":464,"props":1297,"children":1298},{"style":528},[1299],{"type":60,"value":1300},"    s = socket.socket()\n",{"type":54,"tag":464,"props":1302,"children":1303},{"class":466,"line":637},[1304],{"type":54,"tag":464,"props":1305,"children":1306},{"style":528},[1307],{"type":60,"value":1308},"    s.bind((\"127.0.0.1\", 0))\n",{"type":54,"tag":464,"props":1310,"children":1311},{"class":466,"line":682},[1312],{"type":54,"tag":464,"props":1313,"children":1314},{"style":528},[1315],{"type":60,"value":1316},"    port = s.getsockname()[1]\n",{"type":54,"tag":464,"props":1318,"children":1319},{"class":466,"line":709},[1320],{"type":54,"tag":464,"props":1321,"children":1322},{"style":528},[1323],{"type":60,"value":1324},"    s.listen(1)\n",{"type":54,"tag":464,"props":1326,"children":1327},{"class":466,"line":801},[1328],{"type":54,"tag":464,"props":1329,"children":1330},{"style":528},[1331],{"type":60,"value":1332},"except OSError as e:\n",{"type":54,"tag":464,"props":1334,"children":1335},{"class":466,"line":835},[1336],{"type":54,"tag":464,"props":1337,"children":1338},{"style":528},[1339],{"type":60,"value":1340},"    print(f\"PROBE: localhost-bind → ✗ (bind: {e})\")\n",{"type":54,"tag":464,"props":1342,"children":1343},{"class":466,"line":891},[1344],{"type":54,"tag":464,"props":1345,"children":1346},{"style":528},[1347],{"type":60,"value":1348},"    sys.exit(0)\n",{"type":54,"tag":464,"props":1350,"children":1351},{"class":466,"line":950},[1352],{"type":54,"tag":464,"props":1353,"children":1354},{"emptyLinePlaceholder":1273},[1355],{"type":60,"value":1276},{"type":54,"tag":464,"props":1357,"children":1358},{"class":466,"line":959},[1359],{"type":54,"tag":464,"props":1360,"children":1361},{"style":528},[1362],{"type":60,"value":1363},"# 2. Can we GET from our own server over loopback?\n",{"type":54,"tag":464,"props":1365,"children":1367},{"class":466,"line":1366},15,[1368],{"type":54,"tag":464,"props":1369,"children":1370},{"style":528},[1371],{"type":60,"value":1372},"class Handler(http.server.BaseHTTPRequestHandler):\n",{"type":54,"tag":464,"props":1374,"children":1376},{"class":466,"line":1375},16,[1377],{"type":54,"tag":464,"props":1378,"children":1379},{"style":528},[1380],{"type":60,"value":1381},"    def do_GET(self):\n",{"type":54,"tag":464,"props":1383,"children":1385},{"class":466,"line":1384},17,[1386],{"type":54,"tag":464,"props":1387,"children":1388},{"style":528},[1389],{"type":60,"value":1390},"        self.send_response(200); self.end_headers(); self.wfile.write(b\"ok\")\n",{"type":54,"tag":464,"props":1392,"children":1394},{"class":466,"line":1393},18,[1395],{"type":54,"tag":464,"props":1396,"children":1397},{"style":528},[1398],{"type":60,"value":1399},"    def log_message(self, *_): pass\n",{"type":54,"tag":464,"props":1401,"children":1403},{"class":466,"line":1402},19,[1404],{"type":54,"tag":464,"props":1405,"children":1406},{"emptyLinePlaceholder":1273},[1407],{"type":60,"value":1276},{"type":54,"tag":464,"props":1409,"children":1411},{"class":466,"line":1410},20,[1412],{"type":54,"tag":464,"props":1413,"children":1414},{"style":528},[1415],{"type":60,"value":1416},"server = http.server.HTTPServer((\"127.0.0.1\", 0), Handler)\n",{"type":54,"tag":464,"props":1418,"children":1420},{"class":466,"line":1419},21,[1421],{"type":54,"tag":464,"props":1422,"children":1423},{"style":528},[1424],{"type":60,"value":1425},"threading.Thread(target=server.serve_forever, daemon=True).start()\n",{"type":54,"tag":464,"props":1427,"children":1429},{"class":466,"line":1428},22,[1430],{"type":54,"tag":464,"props":1431,"children":1432},{"style":528},[1433],{"type":60,"value":1292},{"type":54,"tag":464,"props":1435,"children":1437},{"class":466,"line":1436},23,[1438],{"type":54,"tag":464,"props":1439,"children":1440},{"style":528},[1441],{"type":60,"value":1442},"    with urllib.request.urlopen(f\"http:\u002F\u002F127.0.0.1:{server.server_port}\u002F\", timeout=5) as r:\n",{"type":54,"tag":464,"props":1444,"children":1446},{"class":466,"line":1445},24,[1447],{"type":54,"tag":464,"props":1448,"children":1449},{"style":528},[1450],{"type":60,"value":1451},"        body = r.read()\n",{"type":54,"tag":464,"props":1453,"children":1455},{"class":466,"line":1454},25,[1456],{"type":54,"tag":464,"props":1457,"children":1458},{"style":528},[1459],{"type":60,"value":1460},"    print(f\"PROBE: localhost-bind → ✓ (bound + loopback GET → HTTP {r.status}, body={body!r})\")\n",{"type":54,"tag":464,"props":1462,"children":1464},{"class":466,"line":1463},26,[1465],{"type":54,"tag":464,"props":1466,"children":1467},{"style":528},[1468],{"type":60,"value":1469},"except Exception as e:\n",{"type":54,"tag":464,"props":1471,"children":1473},{"class":466,"line":1472},27,[1474],{"type":54,"tag":464,"props":1475,"children":1476},{"style":528},[1477],{"type":60,"value":1478},"    print(f\"PROBE: localhost-bind → ✗ (bind ok, loopback GET: {type(e).__name__}: {e})\")\n",{"type":54,"tag":464,"props":1480,"children":1482},{"class":466,"line":1481},28,[1483],{"type":54,"tag":464,"props":1484,"children":1485},{"style":528},[1486],{"type":60,"value":1487},"finally:\n",{"type":54,"tag":464,"props":1489,"children":1491},{"class":466,"line":1490},29,[1492],{"type":54,"tag":464,"props":1493,"children":1494},{"style":528},[1495],{"type":60,"value":1496},"    server.shutdown()\n",{"type":54,"tag":464,"props":1498,"children":1500},{"class":466,"line":1499},30,[1501],{"type":54,"tag":464,"props":1502,"children":1503},{"style":528},[1504],{"type":60,"value":1505},"    s.close()\n",{"type":54,"tag":464,"props":1507,"children":1509},{"class":466,"line":1508},31,[1510],{"type":54,"tag":464,"props":1511,"children":1512},{"style":477},[1513],{"type":60,"value":1514},"PY\n",{"type":54,"tag":69,"props":1516,"children":1517},{},[1518],{"type":54,"tag":103,"props":1519,"children":1520},{},[1521],{"type":60,"value":973},{"type":54,"tag":975,"props":1523,"children":1524},{},[1525,1543],{"type":54,"tag":979,"props":1526,"children":1527},{},[1528],{"type":54,"tag":983,"props":1529,"children":1530},{},[1531,1535,1539],{"type":54,"tag":987,"props":1532,"children":1533},{},[1534],{"type":60,"value":991},{"type":54,"tag":987,"props":1536,"children":1537},{},[1538],{"type":60,"value":996},{"type":54,"tag":987,"props":1540,"children":1541},{},[1542],{"type":60,"value":1001},{"type":54,"tag":1003,"props":1544,"children":1545},{},[1546,1567,1602],{"type":54,"tag":983,"props":1547,"children":1548},{},[1549,1558,1562],{"type":54,"tag":1010,"props":1550,"children":1551},{},[1552],{"type":54,"tag":84,"props":1553,"children":1555},{"className":1554},[],[1556],{"type":60,"value":1557},"✓ bound + loopback GET → HTTP 200",{"type":54,"tag":1010,"props":1559,"children":1560},{},[1561],{"type":60,"value":1023},{"type":54,"tag":1010,"props":1563,"children":1564},{},[1565],{"type":60,"value":1566},"Both bind and loopback HTTP work.",{"type":54,"tag":983,"props":1568,"children":1569},{},[1570,1579,1583],{"type":54,"tag":1010,"props":1571,"children":1572},{},[1573],{"type":54,"tag":84,"props":1574,"children":1576},{"className":1575},[],[1577],{"type":60,"value":1578},"✗ bind: ...",{"type":54,"tag":1010,"props":1580,"children":1581},{},[1582],{"type":60,"value":1077},{"type":54,"tag":1010,"props":1584,"children":1585},{},[1586,1588,1594,1595,1600],{"type":60,"value":1587},"The sandbox blocks ",{"type":54,"tag":84,"props":1589,"children":1591},{"className":1590},[],[1592],{"type":60,"value":1593},"bind(2)",{"type":60,"value":318},{"type":54,"tag":84,"props":1596,"children":1598},{"className":1597},[],[1599],{"type":60,"value":1190},{"type":60,"value":1601},". Rare.",{"type":54,"tag":983,"props":1603,"children":1604},{},[1605,1614,1618],{"type":54,"tag":1010,"props":1606,"children":1607},{},[1608],{"type":54,"tag":84,"props":1609,"children":1611},{"className":1610},[],[1612],{"type":60,"value":1613},"✗ bind ok, loopback GET: ...",{"type":54,"tag":1010,"props":1615,"children":1616},{},[1617],{"type":60,"value":1077},{"type":54,"tag":1010,"props":1619,"children":1620},{},[1621,1623,1628],{"type":60,"value":1622},"Bind works but the sandbox egress proxy refuses ",{"type":54,"tag":84,"props":1624,"children":1626},{"className":1625},[],[1627],{"type":60,"value":1190},{"type":60,"value":1629}," as a destination. Common shape.",{"type":54,"tag":69,"props":1631,"children":1632},{},[1633,1637,1648],{"type":54,"tag":103,"props":1634,"children":1635},{},[1636],{"type":60,"value":1160},{"type":54,"tag":75,"props":1638,"children":1640},{"href":1639},"..\u002F..\u002Fdocs\u002Fsetup\u002Fsandbox-troubleshooting.md#test-cannot-bind-to-a-localhost-port",[1641,1646],{"type":54,"tag":84,"props":1642,"children":1644},{"className":1643},[],[1645],{"type":60,"value":239},{"type":60,"value":1647}," — Test cannot bind to a localhost port",{"type":60,"value":1173},{"type":54,"tag":377,"props":1650,"children":1652},{"id":1651},"probe-3-docker-podman-runtime-socket",[1653],{"type":60,"value":1654},"Probe 3 — Docker \u002F Podman runtime socket",{"type":54,"tag":69,"props":1656,"children":1657},{},[1658,1660,1665,1666,1671,1673,1678],{"type":60,"value":1659},"Tests whether the runtime CLI can talk to its daemon. Run for\neach of ",{"type":54,"tag":84,"props":1661,"children":1663},{"className":1662},[],[1664],{"type":60,"value":308},{"type":60,"value":310},{"type":54,"tag":84,"props":1667,"children":1669},{"className":1668},[],[1670],{"type":60,"value":316},{"type":60,"value":1672}," that is on ",{"type":54,"tag":84,"props":1674,"children":1676},{"className":1675},[],[1677],{"type":60,"value":324},{"type":60,"value":1679},"; ⊘ each that is\nnot installed (this is not a sandbox failure, just an absent\nprerequisite).",{"type":54,"tag":69,"props":1681,"children":1682},{},[1683],{"type":54,"tag":103,"props":1684,"children":1685},{},[1686],{"type":60,"value":451},{"type":54,"tag":453,"props":1688,"children":1690},{"className":455,"code":1689,"language":457,"meta":458,"style":458},"for rt in docker podman; do\n  if ! command -v \"$rt\" > \u002Fdev\u002Fnull 2>&1; then\n    echo \"PROBE: ${rt}-runtime → ⊘ ($rt not on PATH)\"\n    continue\n  fi\n  out=$(\"$rt\" info > \u002Fdev\u002Fnull 2>&1 && echo ok || echo \"fail:$?\")\n  case \"$out\" in\n    ok)\n      echo \"PROBE: ${rt}-runtime → ✓ (${rt} info returned)\" ;;\n    fail:*)\n      err=$(\"$rt\" info 2>&1 >\u002Fdev\u002Fnull | head -2 | tr '\\n' ' ')\n      echo \"PROBE: ${rt}-runtime → ✗ ($out: $err)\"\n      ;;\n  esac\ndone\n",[1691],{"type":54,"tag":84,"props":1692,"children":1693},{"__ignoreMap":458},[1694,1732,1784,1834,1842,1850,1938,1962,1974,2032,2049,2139,2192,2200,2207],{"type":54,"tag":464,"props":1695,"children":1696},{"class":466,"line":467},[1697,1702,1707,1712,1717,1722,1727],{"type":54,"tag":464,"props":1698,"children":1699},{"style":471},[1700],{"type":60,"value":1701},"for",{"type":54,"tag":464,"props":1703,"children":1704},{"style":493},[1705],{"type":60,"value":1706}," rt ",{"type":54,"tag":464,"props":1708,"children":1709},{"style":471},[1710],{"type":60,"value":1711},"in",{"type":54,"tag":464,"props":1713,"children":1714},{"style":528},[1715],{"type":60,"value":1716}," docker",{"type":54,"tag":464,"props":1718,"children":1719},{"style":528},[1720],{"type":60,"value":1721}," podman",{"type":54,"tag":464,"props":1723,"children":1724},{"style":477},[1725],{"type":60,"value":1726},";",{"type":54,"tag":464,"props":1728,"children":1729},{"style":471},[1730],{"type":60,"value":1731}," do\n",{"type":54,"tag":464,"props":1733,"children":1734},{"class":466,"line":514},[1735,1740,1744,1749,1754,1758,1763,1767,1771,1776,1780],{"type":54,"tag":464,"props":1736,"children":1737},{"style":471},[1738],{"type":60,"value":1739},"  if",{"type":54,"tag":464,"props":1741,"children":1742},{"style":477},[1743],{"type":60,"value":554},{"type":54,"tag":464,"props":1745,"children":1746},{"style":518},[1747],{"type":60,"value":1748}," command",{"type":54,"tag":464,"props":1750,"children":1751},{"style":528},[1752],{"type":60,"value":1753}," -v",{"type":54,"tag":464,"props":1755,"children":1756},{"style":477},[1757],{"type":60,"value":490},{"type":54,"tag":464,"props":1759,"children":1760},{"style":493},[1761],{"type":60,"value":1762},"$rt",{"type":54,"tag":464,"props":1764,"children":1765},{"style":477},[1766],{"type":60,"value":501},{"type":54,"tag":464,"props":1768,"children":1769},{"style":477},[1770],{"type":60,"value":654},{"type":54,"tag":464,"props":1772,"children":1773},{"style":528},[1774],{"type":60,"value":1775}," \u002Fdev\u002Fnull",{"type":54,"tag":464,"props":1777,"children":1778},{"style":477},[1779],{"type":60,"value":664},{"type":54,"tag":464,"props":1781,"children":1782},{"style":471},[1783],{"type":60,"value":511},{"type":54,"tag":464,"props":1785,"children":1786},{"class":466,"line":539},[1787,1792,1796,1801,1806,1811,1816,1821,1825,1830],{"type":54,"tag":464,"props":1788,"children":1789},{"style":518},[1790],{"type":60,"value":1791},"    echo",{"type":54,"tag":464,"props":1793,"children":1794},{"style":477},[1795],{"type":60,"value":490},{"type":54,"tag":464,"props":1797,"children":1798},{"style":528},[1799],{"type":60,"value":1800},"PROBE: ",{"type":54,"tag":464,"props":1802,"children":1803},{"style":477},[1804],{"type":60,"value":1805},"${",{"type":54,"tag":464,"props":1807,"children":1808},{"style":493},[1809],{"type":60,"value":1810},"rt",{"type":54,"tag":464,"props":1812,"children":1813},{"style":477},[1814],{"type":60,"value":1815},"}",{"type":54,"tag":464,"props":1817,"children":1818},{"style":528},[1819],{"type":60,"value":1820},"-runtime → ⊘ (",{"type":54,"tag":464,"props":1822,"children":1823},{"style":493},[1824],{"type":60,"value":1762},{"type":54,"tag":464,"props":1826,"children":1827},{"style":528},[1828],{"type":60,"value":1829}," not on PATH)",{"type":54,"tag":464,"props":1831,"children":1832},{"style":477},[1833],{"type":60,"value":536},{"type":54,"tag":464,"props":1835,"children":1836},{"class":466,"line":582},[1837],{"type":54,"tag":464,"props":1838,"children":1839},{"style":471},[1840],{"type":60,"value":1841},"    continue\n",{"type":54,"tag":464,"props":1843,"children":1844},{"class":466,"line":603},[1845],{"type":54,"tag":464,"props":1846,"children":1847},{"style":471},[1848],{"type":60,"value":1849},"  fi\n",{"type":54,"tag":464,"props":1851,"children":1852},{"class":466,"line":628},[1853,1858,1863,1867,1871,1875,1880,1884,1888,1893,1898,1902,1907,1911,1915,1919,1924,1929,1933],{"type":54,"tag":464,"props":1854,"children":1855},{"style":493},[1856],{"type":60,"value":1857},"  out",{"type":54,"tag":464,"props":1859,"children":1860},{"style":477},[1861],{"type":60,"value":1862},"=$(",{"type":54,"tag":464,"props":1864,"children":1865},{"style":641},[1866],{"type":60,"value":501},{"type":54,"tag":464,"props":1868,"children":1869},{"style":493},[1870],{"type":60,"value":1762},{"type":54,"tag":464,"props":1872,"children":1873},{"style":641},[1874],{"type":60,"value":501},{"type":54,"tag":464,"props":1876,"children":1877},{"style":528},[1878],{"type":60,"value":1879}," info",{"type":54,"tag":464,"props":1881,"children":1882},{"style":477},[1883],{"type":60,"value":654},{"type":54,"tag":464,"props":1885,"children":1886},{"style":528},[1887],{"type":60,"value":1775},{"type":54,"tag":464,"props":1889,"children":1890},{"style":477},[1891],{"type":60,"value":1892}," 2>&1",{"type":54,"tag":464,"props":1894,"children":1895},{"style":477},[1896],{"type":60,"value":1897}," &&",{"type":54,"tag":464,"props":1899,"children":1900},{"style":518},[1901],{"type":60,"value":725},{"type":54,"tag":464,"props":1903,"children":1904},{"style":528},[1905],{"type":60,"value":1906}," ok",{"type":54,"tag":464,"props":1908,"children":1909},{"style":477},[1910],{"type":60,"value":1254},{"type":54,"tag":464,"props":1912,"children":1913},{"style":518},[1914],{"type":60,"value":725},{"type":54,"tag":464,"props":1916,"children":1917},{"style":477},[1918],{"type":60,"value":490},{"type":54,"tag":464,"props":1920,"children":1921},{"style":528},[1922],{"type":60,"value":1923},"fail:",{"type":54,"tag":464,"props":1925,"children":1926},{"style":493},[1927],{"type":60,"value":1928},"$?",{"type":54,"tag":464,"props":1930,"children":1931},{"style":477},[1932],{"type":60,"value":501},{"type":54,"tag":464,"props":1934,"children":1935},{"style":477},[1936],{"type":60,"value":1937},")\n",{"type":54,"tag":464,"props":1939,"children":1940},{"class":466,"line":637},[1941,1945,1949,1954,1958],{"type":54,"tag":464,"props":1942,"children":1943},{"style":471},[1944],{"type":60,"value":688},{"type":54,"tag":464,"props":1946,"children":1947},{"style":477},[1948],{"type":60,"value":490},{"type":54,"tag":464,"props":1950,"children":1951},{"style":493},[1952],{"type":60,"value":1953},"$out",{"type":54,"tag":464,"props":1955,"children":1956},{"style":477},[1957],{"type":60,"value":501},{"type":54,"tag":464,"props":1959,"children":1960},{"style":471},[1961],{"type":60,"value":706},{"type":54,"tag":464,"props":1963,"children":1964},{"class":466,"line":682},[1965,1970],{"type":54,"tag":464,"props":1966,"children":1967},{"style":528},[1968],{"type":60,"value":1969},"    ok",{"type":54,"tag":464,"props":1971,"children":1972},{"style":477},[1973],{"type":60,"value":1937},{"type":54,"tag":464,"props":1975,"children":1976},{"class":466,"line":709},[1977,1982,1986,1990,1994,1998,2002,2007,2011,2015,2019,2024,2028],{"type":54,"tag":464,"props":1978,"children":1979},{"style":518},[1980],{"type":60,"value":1981},"      echo",{"type":54,"tag":464,"props":1983,"children":1984},{"style":477},[1985],{"type":60,"value":490},{"type":54,"tag":464,"props":1987,"children":1988},{"style":528},[1989],{"type":60,"value":1800},{"type":54,"tag":464,"props":1991,"children":1992},{"style":477},[1993],{"type":60,"value":1805},{"type":54,"tag":464,"props":1995,"children":1996},{"style":493},[1997],{"type":60,"value":1810},{"type":54,"tag":464,"props":1999,"children":2000},{"style":477},[2001],{"type":60,"value":1815},{"type":54,"tag":464,"props":2003,"children":2004},{"style":528},[2005],{"type":60,"value":2006},"-runtime → ✓ (",{"type":54,"tag":464,"props":2008,"children":2009},{"style":477},[2010],{"type":60,"value":1805},{"type":54,"tag":464,"props":2012,"children":2013},{"style":493},[2014],{"type":60,"value":1810},{"type":54,"tag":464,"props":2016,"children":2017},{"style":477},[2018],{"type":60,"value":1815},{"type":54,"tag":464,"props":2020,"children":2021},{"style":528},[2022],{"type":60,"value":2023}," info returned)",{"type":54,"tag":464,"props":2025,"children":2026},{"style":477},[2027],{"type":60,"value":501},{"type":54,"tag":464,"props":2029,"children":2030},{"style":477},[2031],{"type":60,"value":798},{"type":54,"tag":464,"props":2033,"children":2034},{"class":466,"line":801},[2035,2040,2045],{"type":54,"tag":464,"props":2036,"children":2037},{"style":528},[2038],{"type":60,"value":2039},"    fail:",{"type":54,"tag":464,"props":2041,"children":2042},{"style":477},[2043],{"type":60,"value":2044},"*",{"type":54,"tag":464,"props":2046,"children":2047},{"style":477},[2048],{"type":60,"value":1937},{"type":54,"tag":464,"props":2050,"children":2051},{"class":466,"line":835},[2052,2057,2061,2065,2069,2073,2077,2081,2085,2090,2095,2100,2105,2109,2113,2118,2123,2127,2131,2135],{"type":54,"tag":464,"props":2053,"children":2054},{"style":493},[2055],{"type":60,"value":2056},"      err",{"type":54,"tag":464,"props":2058,"children":2059},{"style":477},[2060],{"type":60,"value":1862},{"type":54,"tag":464,"props":2062,"children":2063},{"style":641},[2064],{"type":60,"value":501},{"type":54,"tag":464,"props":2066,"children":2067},{"style":493},[2068],{"type":60,"value":1762},{"type":54,"tag":464,"props":2070,"children":2071},{"style":641},[2072],{"type":60,"value":501},{"type":54,"tag":464,"props":2074,"children":2075},{"style":528},[2076],{"type":60,"value":1879},{"type":54,"tag":464,"props":2078,"children":2079},{"style":477},[2080],{"type":60,"value":1892},{"type":54,"tag":464,"props":2082,"children":2083},{"style":477},[2084],{"type":60,"value":654},{"type":54,"tag":464,"props":2086,"children":2087},{"style":528},[2088],{"type":60,"value":2089},"\u002Fdev\u002Fnull",{"type":54,"tag":464,"props":2091,"children":2092},{"style":477},[2093],{"type":60,"value":2094}," |",{"type":54,"tag":464,"props":2096,"children":2097},{"style":641},[2098],{"type":60,"value":2099}," head",{"type":54,"tag":464,"props":2101,"children":2102},{"style":528},[2103],{"type":60,"value":2104}," -2",{"type":54,"tag":464,"props":2106,"children":2107},{"style":477},[2108],{"type":60,"value":2094},{"type":54,"tag":464,"props":2110,"children":2111},{"style":641},[2112],{"type":60,"value":769},{"type":54,"tag":464,"props":2114,"children":2115},{"style":477},[2116],{"type":60,"value":2117}," '",{"type":54,"tag":464,"props":2119,"children":2120},{"style":528},[2121],{"type":60,"value":2122},"\\n",{"type":54,"tag":464,"props":2124,"children":2125},{"style":477},[2126],{"type":60,"value":779},{"type":54,"tag":464,"props":2128,"children":2129},{"style":477},[2130],{"type":60,"value":2117},{"type":54,"tag":464,"props":2132,"children":2133},{"style":477},[2134],{"type":60,"value":2117},{"type":54,"tag":464,"props":2136,"children":2137},{"style":477},[2138],{"type":60,"value":1937},{"type":54,"tag":464,"props":2140,"children":2141},{"class":466,"line":891},[2142,2146,2150,2154,2158,2162,2166,2171,2175,2179,2184,2188],{"type":54,"tag":464,"props":2143,"children":2144},{"style":518},[2145],{"type":60,"value":1981},{"type":54,"tag":464,"props":2147,"children":2148},{"style":477},[2149],{"type":60,"value":490},{"type":54,"tag":464,"props":2151,"children":2152},{"style":528},[2153],{"type":60,"value":1800},{"type":54,"tag":464,"props":2155,"children":2156},{"style":477},[2157],{"type":60,"value":1805},{"type":54,"tag":464,"props":2159,"children":2160},{"style":493},[2161],{"type":60,"value":1810},{"type":54,"tag":464,"props":2163,"children":2164},{"style":477},[2165],{"type":60,"value":1815},{"type":54,"tag":464,"props":2167,"children":2168},{"style":528},[2169],{"type":60,"value":2170},"-runtime → ✗ (",{"type":54,"tag":464,"props":2172,"children":2173},{"style":493},[2174],{"type":60,"value":1953},{"type":54,"tag":464,"props":2176,"children":2177},{"style":528},[2178],{"type":60,"value":919},{"type":54,"tag":464,"props":2180,"children":2181},{"style":493},[2182],{"type":60,"value":2183},"$err",{"type":54,"tag":464,"props":2185,"children":2186},{"style":528},[2187],{"type":60,"value":720},{"type":54,"tag":464,"props":2189,"children":2190},{"style":477},[2191],{"type":60,"value":536},{"type":54,"tag":464,"props":2193,"children":2194},{"class":466,"line":950},[2195],{"type":54,"tag":464,"props":2196,"children":2197},{"style":477},[2198],{"type":60,"value":2199},"      ;;\n",{"type":54,"tag":464,"props":2201,"children":2202},{"class":466,"line":959},[2203],{"type":54,"tag":464,"props":2204,"children":2205},{"style":471},[2206],{"type":60,"value":956},{"type":54,"tag":464,"props":2208,"children":2209},{"class":466,"line":1366},[2210],{"type":54,"tag":464,"props":2211,"children":2212},{"style":471},[2213],{"type":60,"value":2214},"done\n",{"type":54,"tag":69,"props":2216,"children":2217},{},[2218],{"type":54,"tag":103,"props":2219,"children":2220},{},[2221],{"type":60,"value":973},{"type":54,"tag":975,"props":2223,"children":2224},{},[2225,2243],{"type":54,"tag":979,"props":2226,"children":2227},{},[2228],{"type":54,"tag":983,"props":2229,"children":2230},{},[2231,2235,2239],{"type":54,"tag":987,"props":2232,"children":2233},{},[2234],{"type":60,"value":991},{"type":54,"tag":987,"props":2236,"children":2237},{},[2238],{"type":60,"value":996},{"type":54,"tag":987,"props":2240,"children":2241},{},[2242],{"type":60,"value":1001},{"type":54,"tag":1003,"props":2244,"children":2245},{},[2246,2267,2288,2309],{"type":54,"tag":983,"props":2247,"children":2248},{},[2249,2258,2262],{"type":54,"tag":1010,"props":2250,"children":2251},{},[2252],{"type":54,"tag":84,"props":2253,"children":2255},{"className":2254},[],[2256],{"type":60,"value":2257},"✓ \u003Crt> info returned",{"type":54,"tag":1010,"props":2259,"children":2260},{},[2261],{"type":60,"value":1023},{"type":54,"tag":1010,"props":2263,"children":2264},{},[2265],{"type":60,"value":2266},"The CLI reached the daemon successfully.",{"type":54,"tag":983,"props":2268,"children":2269},{},[2270,2279,2283],{"type":54,"tag":1010,"props":2271,"children":2272},{},[2273],{"type":54,"tag":84,"props":2274,"children":2276},{"className":2275},[],[2277],{"type":60,"value":2278},"✗ fail:1: Cannot connect to the Docker daemon …",{"type":54,"tag":1010,"props":2280,"children":2281},{},[2282],{"type":60,"value":1077},{"type":54,"tag":1010,"props":2284,"children":2285},{},[2286],{"type":60,"value":2287},"Daemon socket not readable from inside the sandbox.",{"type":54,"tag":983,"props":2289,"children":2290},{},[2291,2300,2304],{"type":54,"tag":1010,"props":2292,"children":2293},{},[2294],{"type":54,"tag":84,"props":2295,"children":2297},{"className":2296},[],[2298],{"type":60,"value":2299},"✗ fail:1: connect: permission denied",{"type":54,"tag":1010,"props":2301,"children":2302},{},[2303],{"type":60,"value":1077},{"type":54,"tag":1010,"props":2305,"children":2306},{},[2307],{"type":60,"value":2308},"Same root cause, different stderr (Linux variant).",{"type":54,"tag":983,"props":2310,"children":2311},{},[2312,2321,2325],{"type":54,"tag":1010,"props":2313,"children":2314},{},[2315],{"type":54,"tag":84,"props":2316,"children":2318},{"className":2317},[],[2319],{"type":60,"value":2320},"⊘ \u003Crt> not on PATH",{"type":54,"tag":1010,"props":2322,"children":2323},{},[2324],{"type":60,"value":1133},{"type":54,"tag":1010,"props":2326,"children":2327},{},[2328],{"type":60,"value":2329},"Runtime not installed; not a sandbox restriction.",{"type":54,"tag":69,"props":2331,"children":2332},{},[2333,2337,2348],{"type":54,"tag":103,"props":2334,"children":2335},{},[2336],{"type":60,"value":1160},{"type":54,"tag":75,"props":2338,"children":2340},{"href":2339},"..\u002F..\u002Fdocs\u002Fsetup\u002Fsandbox-troubleshooting.md#docker--podman-command-fails-with-a-socket-error",[2341,2346],{"type":54,"tag":84,"props":2342,"children":2344},{"className":2343},[],[2345],{"type":60,"value":239},{"type":60,"value":2347}," — Docker \u002F Podman command fails with a socket error",{"type":60,"value":1173},{"type":54,"tag":62,"props":2350,"children":2352},{"id":2351},"after-the-report",[2353],{"type":60,"value":2354},"After the report",{"type":54,"tag":69,"props":2356,"children":2357},{},[2358],{"type":60,"value":2359},"If every probe is ✓ or ⊘:",{"type":54,"tag":2361,"props":2362,"children":2363},"blockquote",{},[2364],{"type":54,"tag":69,"props":2365,"children":2366},{},[2367,2369,2374,2376,2381],{"type":60,"value":2368},"All three probes pass (or are not applicable). The sandbox is\nnot currently blocking the known failure modes catalogued in\n",{"type":54,"tag":84,"props":2370,"children":2372},{"className":2371},[],[2373],{"type":60,"value":239},{"type":60,"value":2375},". If you hit a different\nsandbox-shaped failure, follow the catalog's ",{"type":54,"tag":146,"props":2377,"children":2378},{},[2379],{"type":60,"value":2380},"Adding a new\nentry",{"type":60,"value":2382}," section and (optionally) extend this skill with a fourth\nprobe so future runs catch the same shape automatically.",{"type":54,"tag":69,"props":2384,"children":2385},{},[2386],{"type":60,"value":2387},"If any probe is ✗:",{"type":54,"tag":2389,"props":2390,"children":2391},"ol",{},[2392,2397,2409,2421],{"type":54,"tag":115,"props":2393,"children":2394},{},[2395],{"type":60,"value":2396},"Surface every fail in one report (do not stop at the first).",{"type":54,"tag":115,"props":2398,"children":2399},{},[2400,2402,2407],{"type":60,"value":2401},"For each fail, print the troubleshooting-doc anchor link from\nthe probe's ",{"type":54,"tag":146,"props":2403,"children":2404},{},[2405],{"type":60,"value":2406},"On ✗ → remediation",{"type":60,"value":2408}," row above.",{"type":54,"tag":115,"props":2410,"children":2411},{},[2412,2414,2419],{"type":60,"value":2413},"Suggest the user open the catalog entry to read the symptom →\nroot cause → fix shape, then apply the settings.json widening\nthemselves. Do ",{"type":54,"tag":103,"props":2415,"children":2416},{},[2417],{"type":60,"value":2418},"not",{"type":60,"value":2420}," propose to apply the widening from this\nskill — settings.json widenings are sandbox-bypass-adjacent\nand need an explicit user-driven edit.",{"type":54,"tag":115,"props":2422,"children":2423},{},[2424,2426,2431],{"type":60,"value":2425},"After the user has applied the widening (in a separate flow),\nre-run ",{"type":54,"tag":84,"props":2427,"children":2429},{"className":2428},[],[2430],{"type":60,"value":57},{"type":60,"value":2432}," to confirm the probe now\npasses.",{"type":54,"tag":69,"props":2434,"children":2435},{},[2436,2438,2446],{"type":60,"value":2437},"If a probe surfaces a fail shape not catalogued in\n",{"type":54,"tag":75,"props":2439,"children":2440},{"href":232},[2441],{"type":54,"tag":84,"props":2442,"children":2444},{"className":2443},[],[2445],{"type":60,"value":239},{"type":60,"value":2447},":",{"type":54,"tag":2389,"props":2449,"children":2450},{},[2451,2456,2467],{"type":54,"tag":115,"props":2452,"children":2453},{},[2454],{"type":60,"value":2455},"Report the fail with the literal probe command + exit code +\nstderr.",{"type":54,"tag":115,"props":2457,"children":2458},{},[2459,2461,2465],{"type":60,"value":2460},"Suggest the user add a new entry to the catalog per its\n",{"type":54,"tag":146,"props":2462,"children":2463},{},[2464],{"type":60,"value":253},{"type":60,"value":2466}," section (symptom verbatim, root cause,\nfix, notes).",{"type":54,"tag":115,"props":2468,"children":2469},{},[2470],{"type":60,"value":2471},"Once the catalog has the new entry, extend this skill with a\nmatching probe in the same shape so the next doctor run\ncatches it automatically.",{"type":54,"tag":62,"props":2473,"children":2475},{"id":2474},"extending-the-skill-with-a-new-probe",[2476],{"type":60,"value":2477},"Extending the skill with a new probe",{"type":54,"tag":69,"props":2479,"children":2480},{},[2481],{"type":60,"value":2482},"When the catalog grows a new entry, add a matching probe section\nfollowing the shape above:",{"type":54,"tag":2389,"props":2484,"children":2485},{},[2486,2496,2506],{"type":54,"tag":115,"props":2487,"children":2488},{},[2489,2494],{"type":54,"tag":103,"props":2490,"children":2491},{},[2492],{"type":60,"value":2493},"Command",{"type":60,"value":2495}," — a short, deterministic, side-effect-free\none-liner (or short Python heredoc) that triggers the failure\nmode reliably.",{"type":54,"tag":115,"props":2497,"children":2498},{},[2499,2504],{"type":54,"tag":103,"props":2500,"children":2501},{},[2502],{"type":60,"value":2503},"Interpretation",{"type":60,"value":2505}," — a 3–5-row table mapping result strings\nto ✓ \u002F ✗ \u002F ⊘ \u002F ⚠.",{"type":54,"tag":115,"props":2507,"children":2508},{},[2509,2513,2515,2520],{"type":54,"tag":103,"props":2510,"children":2511},{},[2512],{"type":60,"value":2406},{"type":60,"value":2514}," — a direct link to the matching\nsection of ",{"type":54,"tag":84,"props":2516,"children":2518},{"className":2517},[],[2519],{"type":60,"value":239},{"type":60,"value":1173},{"type":54,"tag":69,"props":2522,"children":2523},{},[2524,2526,2531],{"type":60,"value":2525},"Keep probes narrowly scoped: each probe tests ",{"type":54,"tag":103,"props":2527,"children":2528},{},[2529],{"type":60,"value":2530},"one",{"type":60,"value":2532}," failure\nmode, not a bundle. A probe that conflates two restrictions\nmakes the report ambiguous when the result is ✗.",{"type":54,"tag":2534,"props":2535,"children":2536},"style",{},[2537],{"type":60,"value":2538},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2540,"total":2636},[2541,2555,2569,2583,2597,2613,2623],{"slug":2542,"name":2542,"fn":2543,"description":2544,"org":2545,"tags":2546,"stars":25,"repoUrl":26,"updatedAt":2554},"generate-cve-json","generate CVE JSON documents","Generate a CVE 5.x JSON document from an \u003Ctracker> tracking\nissue, ready to paste into the Vulnogram `#source` tab of the ASF CVE tool\nat https:\u002F\u002Fcveprocess.apache.org\u002Fcve5\u002F\u003CCVE-ID>#source. The conversion is\ndeterministic: same issue in, same JSON bytes out. Handles multiple\ncredits (one per line) and multiple references (URLs extracted from the\nissue's \"Public advisory URL\" and \"PR with the fix\" fields; the\n\"Security mailing list thread\" field is treated as internal-only and\nnever exported).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2547,2550,2551],{"name":2548,"slug":2549,"type":15},"Compliance","compliance",{"name":13,"slug":14,"type":15},{"name":2552,"slug":2553,"type":15},"Technical Writing","technical-writing","2026-07-12T08:35:41.218722",{"slug":2556,"name":2556,"fn":2557,"description":2558,"org":2559,"tags":2560,"stars":25,"repoUrl":26,"updatedAt":2568},"magpie-audit-finding-fix","fix findings from code audit tools","For a batch of findings from a non-security audit tool\n(`\u003Caudit-tool>` — ruff \u002F flake8 \u002F mypy \u002F pylint \u002F CodeQL \u002F\nApache Verum \u002F Apache Caer \u002F equivalent; full list in the body)\nagainst `\u003Cupstream>`, draft the smallest fix for each finding.\nRe-runs the tool after each batch to confirm the findings are\ncleared. Produces a commit and a hand-back artefact; never opens\na PR on autopilot or merges.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2561,2564,2567],{"name":2562,"slug":2563,"type":15},"Audit","audit",{"name":2565,"slug":2566,"type":15},"Code Analysis","code-analysis",{"name":23,"slug":24,"type":15},"2026-07-12T08:35:13.930479",{"slug":2570,"name":2570,"fn":2571,"description":2572,"org":2573,"tags":2574,"stars":25,"repoUrl":26,"updatedAt":2582},"magpie-ci-runner-audit","audit GitHub Actions workflow runner compatibility","Read-only audit of GitHub Actions workflow runner compatibility\nfor one repository, an explicit repository set, one Apache project\nwith multiple repositories, or the full Apache GitHub org. Finds\nobsolete GitHub-hosted runner labels and macOS runner\u002Ftool\narchitecture mismatches. Produces TSV evidence files; never edits\nworkflows, opens PRs, or posts comments.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2575,2576,2579],{"name":2562,"slug":2563,"type":15},{"name":2577,"slug":2578,"type":15},"CI\u002FCD","ci-cd",{"name":2580,"slug":2581,"type":15},"GitHub Actions","github-actions","2026-07-12T08:34:30.320965",{"slug":2584,"name":2584,"fn":2585,"description":2586,"org":2587,"tags":2588,"stars":25,"repoUrl":26,"updatedAt":2596},"magpie-committer-onboarding","onboard Apache project committers","Post-vote committer and PMC onboarding for Apache projects.\nWalks the nominator through every step from ICLA check to\nwelcome announcement for both incubating podlings and\ngraduated top-level projects.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2589,2592,2593],{"name":2590,"slug":2591,"type":15},"Management","management",{"name":17,"slug":18,"type":15},{"name":2594,"slug":2595,"type":15},"Process Documentation","process-documentation","2026-07-12T08:33:35.628029",{"slug":2598,"name":2598,"fn":2599,"description":2600,"org":2601,"tags":2602,"stars":25,"repoUrl":26,"updatedAt":2612},"magpie-contributor-activity-sweep","generate contributor activity reports","Read-only GitHub activity card for a named contributor on \u003Cupstream>.\nFetches PR authorship, code-review activity, issues, and PR\u002Fissue\ncomments over a configurable window. Limited to GitHub-visible\nactivity — the body documents the off-GitHub tracks the nominator\nmust supply separately. No readiness verdict is produced; use\ncontributor-nomination for a full nomination brief.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2603,2606,2609],{"name":2604,"slug":2605,"type":15},"Analytics","analytics",{"name":2607,"slug":2608,"type":15},"GitHub","github",{"name":2610,"slug":2611,"type":15},"Reporting","reporting","2026-07-12T08:33:41.715859",{"slug":2614,"name":2614,"fn":2615,"description":2616,"org":2617,"tags":2618,"stars":25,"repoUrl":26,"updatedAt":2622},"magpie-contributor-nomination","generate contributor nomination briefs","Read-only nomination brief for a named GitHub contributor on\n\u003Cupstream>. Aggregates GitHub activity across all contribution\ntracks plus maintainer-supplied off-GitHub signal, and flags\nvendor-neutrality context — the evidence a PMC needs to open\na committer or PMC nomination thread.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2619,2620,2621],{"name":20,"slug":21,"type":15},{"name":2607,"slug":2608,"type":15},{"name":2610,"slug":2611,"type":15},"2026-07-12T08:33:39.211745",{"slug":2624,"name":2624,"fn":2625,"description":2626,"org":2627,"tags":2628,"stars":25,"repoUrl":26,"updatedAt":2635},"magpie-contributor-sentiment","measure contributor sentiment on GitHub repositories","Measures contributor-sentiment signals on \u003Cupstream> over a\nconfigurable window: thread tone (first-response classification),\ntime-to-first-reply (median hours), first-PR retention\n(second-PR rate), and reviewer load (Gini coefficient). Compares\neach signal against a pre-adoption baseline and produces a\nstructured gate report used to decide whether a skill family is\nready to advance from experimental to stable.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2629,2630,2633,2634],{"name":2604,"slug":2605,"type":15},{"name":2631,"slug":2632,"type":15},"Communications","communications",{"name":20,"slug":21,"type":15},{"name":2607,"slug":2608,"type":15},"2026-07-12T08:34:09.204167",71,{"items":2638,"total":2787},[2639,2657,2671,2682,2693,2706,2724,2735,2745,2756,2766,2776],{"slug":2640,"name":2640,"fn":2641,"description":2642,"org":2643,"tags":2644,"stars":2654,"repoUrl":2655,"updatedAt":2656},"datafusion-python","write Apache DataFusion Python code","Use when the user is writing datafusion-python (Apache DataFusion Python bindings) DataFrame or SQL code. Covers imports, data loading, DataFrame operations, expression building, SQL-to-DataFrame mappings, idiomatic patterns, and common pitfalls.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2645,2648,2651],{"name":2646,"slug":2647,"type":15},"Data Analysis","data-analysis",{"name":2649,"slug":2650,"type":15},"Python","python",{"name":2652,"slug":2653,"type":15},"SQL","sql",593,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fdatafusion-python","2026-07-12T08:36:04.957626",{"slug":2658,"name":2658,"fn":2659,"description":2660,"org":2661,"tags":2662,"stars":2668,"repoUrl":2669,"updatedAt":2670},"bydbql","generate and execute BanyanDB BydbQL queries","Generate, validate, and optionally execute read-only BanyanDB BydbQL for STREAM, MEASURE, TRACE, and PROPERTY resources. Use when the user asks to query BanyanDB, translate natural language to BydbQL, inspect BanyanDB schema or data, validate BydbQL, or fetch raw BanyanDB records.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2663,2664,2667],{"name":2604,"slug":2605,"type":15},{"name":2665,"slug":2666,"type":15},"Database","database",{"name":2652,"slug":2653,"type":15},344,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fskywalking-banyandb","2026-07-12T08:31:01.294423",{"slug":2672,"name":2672,"fn":2673,"description":2674,"org":2675,"tags":2676,"stars":2668,"repoUrl":2669,"updatedAt":2681},"compiling","compile and build BanyanDB projects","Compile and build the SkyWalking BanyanDB project. Use when the user asks to compile, build, or generate code for this project.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2677,2680],{"name":2678,"slug":2679,"type":15},"Build","build",{"name":20,"slug":21,"type":15},"2026-07-12T08:31:06.373309",{"slug":2683,"name":2683,"fn":2684,"description":2685,"org":2686,"tags":2687,"stars":2668,"repoUrl":2669,"updatedAt":2692},"gh-pull-request","create GitHub pull requests for BanyanDB","Create a GitHub pull request for SkyWalking BanyanDB. Use when the user asks to create a PR, submit changes, or open a pull request.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2688,2689],{"name":2607,"slug":2608,"type":15},{"name":2690,"slug":2691,"type":15},"Pull Requests","pull-requests","2026-07-12T08:31:03.792415",{"slug":2694,"name":2694,"fn":2695,"description":2696,"org":2697,"tags":2698,"stars":2668,"repoUrl":2669,"updatedAt":2705},"vendor-update","update Go and Node.js vendor dependencies","Upgrade Go\u002FNode.js vendor dependencies and sync tool versions. Use whenever the user says \"upgrade dependencies\", \"update vendors\", \"vendor update\", \"run vendor-upgrade\", \"bump dependencies\", \"update packages\", or asks to run the `vendor-update` Make target. This skill also checks `scripts\u002Fbuild\u002Fversion.mk` after upgrading to see if any tracked tool versions need updating too, and removes stale binaries from `bin\u002F` when versions change.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2699,2702],{"name":2700,"slug":2701,"type":15},"Go","go",{"name":2703,"slug":2704,"type":15},"Node.js","node-js","2026-07-12T08:31:02.555555",{"slug":2707,"name":2707,"fn":2708,"description":2709,"org":2710,"tags":2711,"stars":2721,"repoUrl":2722,"updatedAt":2723},"cayenne-cgen","generate Cayenne entity Java classes","Use this skill whenever the user wants to (re)generate Cayenne entity Java classes from a DataMap. Trigger on phrases like 'generate Java classes', 'regenerate entities', 'run cgen', 'create the entity classes', 'why is the Artist class missing fields', 'where did the `_Abstract*` classes come from', 'sync the entity classes with the model', or any request to materialize Java from the DataMap. Also trigger as a follow-up after modeling changes (someone added an entity, attribute, or relationship and now the Java side is stale). This skill exclusively uses the `mcp__cayenne__cgen_run` MCP tool — it does NOT use `mvn cayenne:cgen` or the Gradle cgen task.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2712,2715,2718],{"name":2713,"slug":2714,"type":15},"Data Modeling","data-modeling",{"name":2716,"slug":2717,"type":15},"Java","java",{"name":2719,"slug":2720,"type":15},"ORM","orm",343,"https:\u002F\u002Fgithub.com\u002Fapache\u002Fcayenne","2026-07-12T08:32:33.575211",{"slug":2725,"name":2725,"fn":2726,"description":2727,"org":2728,"tags":2729,"stars":2721,"repoUrl":2722,"updatedAt":2734},"cayenne-db-import","import database schema into Cayenne DataMaps","Use this skill when the user wants to import database schema metadata into a Cayenne DataMap — the *model\u002Fmapping only*, not names or Java classes. Trigger on phrases like 'reverse engineer the database', 'import the schema', 'generate a DataMap from my DB', 'add the new tables from the DB into the model', 'import the customer table', 'create entities from these tables', or any request to read database metadata to populate or update a DataMap's XML. This is for *full schema* or *bulk table* import; one-off a-la-carte entity additions belong in the cayenne-modeling skill. IMPORTANT — scope: this imports the mapping ONLY; it does not clean up the Object-layer names or (re)generate Java classes. When the user wants their whole project brought in line with the DB ('sync my project with the database', 'my schema changed, update everything', 'update my entities\u002Fclasses from the DB'), that is the end-to-end `cayenne-full-db-sync` skill, which runs this import and then name cleanup and class generation. To regenerate classes alone use `cayenne-cgen`. The skill runs reverse engineering directly via the `mcp__cayenne__dbimport_run` MCP tool when a DBConnector is already configured; otherwise it opens the CayenneModeler GUI via `mcp__cayenne__open_project` to configure the connection first.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2730,2731,2732,2733],{"name":2665,"slug":2666,"type":15},{"name":2716,"slug":2717,"type":15},{"name":2719,"slug":2720,"type":15},{"name":2652,"slug":2653,"type":15},"2026-07-19T05:40:33.655062",{"slug":2736,"name":2736,"fn":2737,"description":2738,"org":2739,"tags":2740,"stars":2721,"repoUrl":2722,"updatedAt":2744},"cayenne-full-db-sync","synchronize Cayenne projects with database","Use this skill when the user wants to bring their WHOLE Cayenne project in line with the database in one shot — the mapping, the Object-layer names, and the generated Java classes together. This is the end-to-end 'sync with the DB' workflow, and it orchestrates three skills in order: `cayenne-db-import` (import schema metadata into the DataMap) → `cayenne-model-naming` (polish the just-imported names) → `cayenne-cgen` (regenerate Java classes). Trigger on holistic phrases like 'sync my project with the database', 'sync with the DB', 'my schema changed, update everything', 'update my entities\u002Fclasses from the database', 'reverse engineer and regenerate the classes', 'import the new tables and rebuild the entities', 'full DB sync', 'bring the model and classes up to date with the DB'. The distinguishing signal is scope: the user wants the whole project (mapping + names + Java code), not just one stage. For the *model\u002Fmapping only* (no name cleanup, no class generation) use `cayenne-db-import`; to (re)generate classes alone use `cayenne-cgen`; to clean names alone use `cayenne-model-naming`. Uses the `mcp__cayenne__dbimport_run` and `mcp__cayenne__cgen_run` MCP tools via the sub-skills; does NOT use Maven or Gradle goals.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2741,2742,2743],{"name":2665,"slug":2666,"type":15},{"name":2716,"slug":2717,"type":15},{"name":2719,"slug":2720,"type":15},"2026-07-19T06:03:49.112969",{"slug":2746,"name":2746,"fn":2747,"description":2748,"org":2749,"tags":2750,"stars":2721,"repoUrl":2722,"updatedAt":2755},"cayenne-model-naming","clean up Cayenne object-layer names","Use this skill to clean up Object-layer names in a Cayenne DataMap — ObjEntity, ObjAttribute, and ObjRelationship names, plus DbRelationship names (the first-class unit of relationship cleanup — every FK has one whether or not an ObjRelationship was generated; the ObjRelationship name is synced to it when one exists) — so they read as descriptive, consistent Java. Trigger on phrases like 'clean up the model names', 'fix the entity names', 'these names look ugly', 'make the names descriptive', 'normalize the ObjEntity\u002Fattribute\u002Frelationship names', 'why is this relationship called team1', 'rename entities to be consistent', 'the import produced Gametype instead of GameType'. Invoke it on an explicit user request, or as a manual follow-up after a `cayenne-db-import` to polish the just-imported additions — it is never triggered automatically. IMPORTANT: this is a LIGHT polish pass — CayenneModeler's reverse-engineering already produces good names for the common case; only improve the specific things its deterministic algorithm cannot (run-together names with no separators like `gametype`, meaningless numbered names like `team1` from multiple relationships between two tables, and a common entity prefix that leaks into relationship names like `aaOrders`). Do NOT rewrite names that are already correct. This is Obj-layer naming polish; for structural model edits use `cayenne-modeling`, and for regenerating classes afterward use `cayenne-cgen`.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2751,2752,2753,2754],{"name":2713,"slug":2714,"type":15},{"name":2665,"slug":2666,"type":15},{"name":2716,"slug":2717,"type":15},{"name":2719,"slug":2720,"type":15},"2026-07-22T05:35:32.342548",{"slug":2757,"name":2757,"fn":2758,"description":2759,"org":2760,"tags":2761,"stars":2721,"repoUrl":2722,"updatedAt":2765},"cayenne-modeler","manage Cayenne projects with CayenneModeler","Use this skill when the user explicitly wants to open CayenneModeler (the GUI) on a Cayenne project, or when the modeling task is inherently visual — reverse engineering (delegated to cayenne-db-import), bulk relationship layout, multi-entity visual refactoring. Trigger on phrases like 'open the Modeler', 'open in CayenneModeler', 'launch the GUI', 'edit visually', 'show me the project in the Modeler'. Do NOT trigger as a fallback for ordinary a-la-carte XML edits — those belong in the cayenne-modeling skill, which is faster and doesn't require the user to context-switch.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2762,2763,2764],{"name":2713,"slug":2714,"type":15},{"name":2716,"slug":2717,"type":15},{"name":2719,"slug":2720,"type":15},"2026-07-12T08:32:37.199428",{"slug":2767,"name":2767,"fn":2768,"description":2769,"org":2770,"tags":2771,"stars":2721,"repoUrl":2722,"updatedAt":2775},"cayenne-modeling","edit and extend Cayenne ORM models","Use this skill whenever the user wants to edit, inspect, or extend the Cayenne ORM model in a project — adding or modifying entities, attributes, relationships, embeddables, named queries, stored procedures, or DataNodes. Trigger on phrases like 'add an ObjEntity', 'add a DbEntity', 'add a relationship', 'expose this column as an attribute', 'create a new DataMap', 'add a named query', 'create an embeddable', 'add a stored procedure', 'change the attribute type', 'mark this column as nullable', 'rename this entity', or any mention of a Cayenne `*.map.xml` or `cayenne-*.xml` file. Also trigger when the user references modeling concepts (ObjEntity, DbEntity, ObjAttribute, DbAttribute, ObjRelationship, DbRelationship, Embeddable, dbEntityName, deleteRule, db-attribute-path, db-relationship-path, defaultPackage) in the context of a Cayenne-using app. This is the *primary* skill for a-la-carte ORM model manipulation — direct XML edits, not the Modeler GUI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2772,2773,2774],{"name":2665,"slug":2666,"type":15},{"name":2716,"slug":2717,"type":15},{"name":2719,"slug":2720,"type":15},"2026-07-19T05:40:32.6889",{"slug":2777,"name":2777,"fn":2778,"description":2779,"org":2780,"tags":2781,"stars":2721,"repoUrl":2722,"updatedAt":2786},"cayenne-query","write and modify Cayenne database queries","Use this skill whenever the user wants to write or modify a Cayenne query — fetching entities by criteria, joining, prefetching to avoid N+1, ordering, paginating, aggregating, or running raw SQL through Cayenne. Trigger on phrases like 'query for X', 'fetch all artists where ...', 'write an ObjectSelect', 'use SQLSelect', 'use SelectById', 'add a prefetch', 'get distinct values', 'count rows', 'find by ID', 'load by primary key', 'build a Cayenne expression', 'why am I getting N+1', 'how do I paginate', 'select a single column', 'select columns into a DTO', 'named query in the DataMap'. Do NOT trigger for modeling changes (use cayenne-modeling) or runtime bootstrap (use cayenne-runtime).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2782,2783,2784,2785],{"name":2665,"slug":2666,"type":15},{"name":2716,"slug":2717,"type":15},{"name":2719,"slug":2720,"type":15},{"name":2652,"slug":2653,"type":15},"2026-07-12T08:32:35.072322",108]