[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7CT628CSXN5680EEAFT3FXB":3,"skill-same:01M7CT628CSXN5680EEAFT3FXB":50},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":14,"repositoryHtmlUrl":27,"repositoryHomepageUrl":6,"ownerHtmlUrl":28,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":29,"install":30,"resources":43},"01M7CT628CSXN5680EEAFT3FXB","polly-e2e-dev",null,"End-to-end test the polly multi-agent coding orchestrator's critical user journeys (CUJs). Two halves — a deterministic mock-LLM driver (polly_cuj.py) that boots a throwaway local server + mock LLM and asserts the substrate (boot, bridged sys_* tool dispatch, the blast_radius \u002F spawn_bounds \u002F headless_subagent_purpose_guard guardrails, fan-out delegation), and a live real-CLI recipe (real claude\u002Fcodex\u002Fpi, real worktrees\u002FPRs) for polly's actual judgment. Load when developing, testing, or debugging examples\u002Fpolly — its config.yaml, the claude_code\u002Fcodex\u002Fpi sub-agents, the investigate\u002Ffanout\u002Fcross-review skills, or the omnigent.inner.nessie.policies guardrails — or reproducing a polly orchestration bug.","roland-id-au\u002Fomniagent","roland-id-au","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F2590653?v=4","01M7CT4DEBVK4R185WFWCWN4JD","Buck Chancey","01M7CT4DFGWX49CGE347EF4V6T",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Froland-id-au\u002Fomniagent\u002Fblob\u002Fdeploy\u002Froland-id-au-omniagent\u002F.claude\u002Fskills\u002Fpolly-e2e-dev\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: polly-e2e-dev\ndescription: End-to-end test the polly multi-agent coding orchestrator's critical user journeys (CUJs). Two halves — a deterministic mock-LLM driver (polly_cuj.py) that boots a throwaway local server + mock LLM and asserts the substrate (boot, bridged sys_* tool dispatch, the blast_radius \u002F spawn_bounds \u002F headless_subagent_purpose_guard guardrails, fan-out delegation), and a live real-CLI recipe (real claude\u002Fcodex\u002Fpi, real worktrees\u002FPRs) for polly's actual judgment. Load when developing, testing, or debugging examples\u002Fpolly — its config.yaml, the claude_code\u002Fcodex\u002Fpi sub-agents, the investigate\u002Ffanout\u002Fcross-review skills, or the omnigent.inner.nessie.policies guardrails — or reproducing a polly orchestration bug.\n---\n\n# polly orchestrator: end-to-end CUJ dev & testing\n\n`polly` (`examples\u002Fpolly\u002F`) is a multi-agent **coding orchestrator**: a\n`claude-sdk` \"brain\" that writes no code itself and delegates everything to three\ncoding sub-agents — `claude_code` (claude-native), `codex` (codex-native), and\n`pi` (headless, multi-model). Its critical user journeys are orchestration\nbehaviors, not single-turn answers:\n\n- **roster preflight** — first turn runs `command -v claude codex pi`, routes\n  only to workers whose CLI resolved.\n- **investigate** — read-only work fanned to `explore`\u002F`search` sub-agents;\n  synthesize from their reports.\n- **fanout** — independent tasks, each in its own git worktree + sub-agent, each\n  opening its own PR.\n- **cross-review** — an implementer's diff is verified by a **different-vendor**\n  sub-agent (diff + contract only); blocking issues become fix-tasks.\n- **plan gate \u002F inbox** — pull the human in at the plan gate; supervise via the\n  inbox + autowake, never busy-poll.\n- **guardrails** (`omnigent.inner.nessie.policies`) — `blast_radius` (deny\n  force-push \u002F `rm -rf \u002F`), `spawn_bounds` (cap dispatches per turn),\n  `headless_subagent_purpose_guard` (every dispatch needs `args.purpose`).\n\nThis skill tests those CUJs two ways. Use **both** — they cover different things:\n\n| Half | What it proves | Needs |\n|------|----------------|-------|\n| **Mock loop** (`polly_cuj.py`) | The **substrate\u002Fmechanics** — the brain is *scripted*, so this proves bundle load, server-side policy resolution, bridged `sys_*` tool dispatch, the guardrail DENYs, and fan-out — deterministically, with no creds | nothing (mock LLM) |\n| **Live recipe** | polly's **judgment** — does the real brain preflight, decompose, delegate, cross-review, and pull in the human correctly | real `claude`\u002F`codex`\u002F`pi` + model creds + network |\n\n> Like the sibling harness skills, turns run from your **current checkout**\n> (`omni run \u003Cbundle> --server \u003Curl>` = local runner + remote server), so testing\n> exercises exactly the code you're on.\n\n## Interpreter\n\nThe driver and CLI need the repo's Python ≥3.12 env. If `.venv\u002F` is missing,\ncreate it once from the checkout:\n\n```bash\nuv run --frozen python -c \"import omnigent; print('ok')\"   # builds .venv\n```\n\nThen use `.venv\u002Fbin\u002Fpython` \u002F `.venv\u002Fbin\u002Fomni` below.\n\n---\n\n## Part A — the deterministic mock loop (`polly_cuj.py`)\n\nThe driver boots a throwaway local Omnigent server (which carries\n`omnigent.inner.nessie.policies` — the module polly's guardrails resolve) plus\nthe repo's mock-LLM server, rewrites the polly bundle to the `openai-agents`\nharness wired to the mock, then runs `omnigent run` turns where the brain is\n*scripted* (text or tool calls). It prints one `SUMMARY {json}` per scenario and\nexits non-zero if any check failed.\n\n```bash\n.venv\u002Fbin\u002Fpython .claude\u002Fskills\u002Fpolly-e2e-dev\u002Fpolly_cuj.py --list-scenarios\n.venv\u002Fbin\u002Fpython .claude\u002Fskills\u002Fpolly-e2e-dev\u002Fpolly_cuj.py --scenario all\n.venv\u002Fbin\u002Fpython .claude\u002Fskills\u002Fpolly-e2e-dev\u002Fpolly_cuj.py --scenario guardrail_purpose --keep\n```\n\nRead the result with `… | grep '^SUMMARY' | python -m json.tool`. Each run takes\n~45–55s for all five scenarios; no credentials or egress are required.\n\n### Scenario catalog\n\n| Scenario | Scripts the brain to… | Hard check |\n|---|---|---|\n| `boot` | reply with text | exit 0 + non-trivial reply (bundle load, server-side policy resolve, turn completes) |\n| `tool_dispatch` | call `sys_os_shell` to write a sentinel | the file appears on disk (bridged `sys_*` dispatch works; `blast_radius` ALLOWs benign shell) |\n| `guardrail_purpose` | `sys_session_send` with **no** `args.purpose` | tool output carries `Denied by policy: … must declare what kind of work it is` (`headless_subagent_purpose_guard`) |\n| `guardrail_blast_radius` | `sys_os_shell(\"git push --force …\")` | tool output carries `Denied by policy: … blast-radius policy` |\n| `fanout_dispatch` | emit 7 `sys_session_send` in one turn | 6 dispatch handles created and the seventh is denied by `spawn_bounds` |\n\n### The verifiable before→after loop\n\nThe driver exists for a *loop*, not a one-shot. To prove a fix:\n\n1. On the **unfixed** code, run the scenario → a check is `false` (baseline).\n2. Make the change.\n3. Run the **same** scenario → the check **flips** to `true`.\n\nA fix is \"verifiable\" only if a check flips. If it doesn't flip, you can't prove\nthe change did anything — keep working. To cover a new mechanism, add a\n`scenario_*` function + a row in `_SCENARIOS` (each builds a bundle, scripts the\nmock, runs a turn, and asserts an **observable effect** — a session item, a deny\nsentinel, a file on disk).\n\n### What the mock loop can and can't prove\n\nIt tests **mechanics** because the brain is scripted: tool dispatch, the\nguardrail gate, session persistence, fan-out plumbing. It does **not** test\npolly's judgment (whether the *real* brain preflights, decomposes, picks the\nright vendor, cross-reviews). That is the live recipe.\n\n---\n\n## Part B — the live recipe (real claude\u002Fcodex\u002Fpi)\n\n### Prereqs (check first)\n\n1. **You're on the branch you want to test.**\n2. **A Claude provider for the brain** (`omni setup`, or `ANTHROPIC_API_KEY`, or\n   a Databricks default). Verify booleans only — never print keys.\n3. **Worker CLIs on PATH** — this *is* the roster preflight:\n   ```bash\n   command -v claude codex pi || true\n   ```\n   A worker is launchable only if its binary resolved. Cross-review needs **two\n   different vendors** available.\n4. **Network egress** to the model backends; **`gh`** authed if you want real PRs.\n\n### Run a live turn\n\n```bash\n.venv\u002Fbin\u002Fomni server --background && .venv\u002Fbin\u002Fomni server status   # prints $SERVER, e.g. http:\u002F\u002F127.0.0.1:6767\nSERVER=http:\u002F\u002F127.0.0.1:6767\ntimeout 280 .venv\u002Fbin\u002Fomni run examples\u002Fpolly \\\n  -p \"Investigate how the runner enforces tool-call policies and report file:line evidence.\" \\\n  --server \"$SERVER\" 2>&1\n```\n\nAlways pass `--server \"$SERVER\"`; omitting it routes to the configured **remote**\ndeploy, which may be stale and reject parts of the bundle.\n\n### Observe CUJs (CLI + HTTP API + filesystem)\n\nGrab the session id, then read the transcript and the side effects:\n\n```bash\nSID=$(curl -s \"$SERVER\u002Fv1\u002Fsessions?kind=default&order=desc&limit=1\" | python -c \"import sys,json;print(json.load(sys.stdin)['data'][0]['id'])\")\ncurl -s \"$SERVER\u002Fv1\u002Fsessions\u002F$SID\u002Fitems\"          | python -m json.tool | tail -60   # brain transcript + tool calls\ncurl -s \"$SERVER\u002Fv1\u002Fsessions\u002F$SID\u002Fchild_sessions\" | python -m json.tool             # dispatched sub-agents\ngit worktree list                                  # fanout: one per task\ncat .polly\u002Fregistry.json 2>\u002Fdev\u002Fnull               # polly's task list\ngh pr list --author \"@me\"                          # each implementer opens its own PR\n```\n\n### Per-CUJ live playbook\n\n| CUJ | Drive it | Look for |\n|---|---|---|\n| roster preflight | first live turn on a box missing a CLI | polly tells you which worker is unavailable; routes around it |\n| investigate | prompt a read-only question (\"explain\u002Faudit\u002Fwhy does X…\") | `child_sessions` with `purpose: explore\u002Fsearch`; answer cites their reports, not polly's own deep reads |\n| fanout | prompt 2–3 independent changes | one worktree + one sub-agent + one PR per task |\n| cross-review | let an implementer finish | a **different-vendor** reviewer child with `purpose: review`; blocking issues sent back to the **same** implementer session |\n| plan gate \u002F inbox | a multi-step task | polly pauses for human approval at the plan gate; ends its turn after dispatch and is autowoken by the inbox (no busy-poll) |\n| guardrails (ASK) | a task that pushes\u002Fmerges | the runner surfaces an approval card; `ask_timeout: 86400` keeps it open |\n\nFor the guardrail **DENY** set (force-push, `rm -rf \u002F`, unmarked dispatch,\nfan-out cap), prefer the **mock loop** — it's deterministic and creates no real\nside effects.\n\n---\n\n## CUJ coverage map\n\n| CUJ | Mock loop | Live recipe |\n|---|---|---|\n| boot \u002F turn completes | `boot` | any live turn |\n| bridged `sys_*` dispatch | `tool_dispatch` | tool calls in `…\u002Fitems` |\n| `headless_subagent_purpose_guard` | `guardrail_purpose` ✅ | (deny — prefer mock) |\n| `blast_radius` | `guardrail_blast_radius` ✅ | ASK card on push\u002Fmerge |\n| `spawn_bounds` | `fanout_dispatch` ✅ | verify cap live |\n| fanout delegation | `fanout_dispatch` (handles) | `child_sessions` + worktrees + PRs |\n| investigate \u002F cross-review \u002F plan gate \u002F inbox | — (needs judgment) | live playbook above |\n\n---\n\n## Known sharp edges (found while building this skill — verify, may change)\n- **Two deny formats.** Bridged `sys_*` tools surface a denial as\n  `{\"error\": \"Denied by policy: \u003Creason>\"}`; SDK function tools use\n  `[Denied by policy: \u003Cname>] {json}`. Both share the `Denied by policy:`\n  marker — match on that plus a policy-specific reason fragment (the driver does).\n- **Live fan-out needs the worker CLIs.** In the mock loop, sub-agents are\n  rewritten to `openai-agents` so a dispatch needs no binary. Live, a missing\n  `claude`\u002F`codex`\u002F`pi` makes that worker fail to boot — treat it as UNAVAILABLE.\n- **Default server gotcha.** `config.yaml`'s `server:` points at a remote deploy;\n  always pass `--server \"$SERVER\"` for local testing.\n\n## Code & tests\n\n- **Bundle \u002F prompt \u002F guardrails:** `examples\u002Fpolly\u002Fconfig.yaml`\n- **Sub-agents:** `examples\u002Fpolly\u002Fagents\u002F{claude_code,codex,pi}\u002Fconfig.yaml`\n- **Orchestration skills:** `examples\u002Fpolly\u002Fskills\u002F{investigate,fanout,cross-review}\u002FSKILL.md`\n- **Guardrail policies:** `omnigent\u002Finner\u002Fnessie\u002Fpolicies.py`\n- **Runner-side gate:** `omnigent\u002Frunner\u002Fpolicy.py`; server-side tool-call\n  enforcement: `omnigent\u002Fserver\u002Froutes\u002Fsessions.py`\n- **Mock LLM server:** `tests\u002Fserver\u002Fintegration\u002Fmock_llm_server.py`\n\n```bash\n# Existing pytest e2e for polly (mock-LLM) — complementary to this skill:\nuv run --frozen --group test python -m pytest \\\n  tests\u002Fe2e\u002Ftest_polly_e2e.py \\\n  tests\u002Fe2e\u002Ftest_polly_cost_advisor_e2e.py \\\n  tests\u002Fe2e\u002Ftest_polly_subagent_model_e2e.py -q\n```\n\n## Teardown — non-negotiable\n\nThe driver reaps everything it starts, including the per-conversation\n`omnigent.host._daemon_entry` \u002F `runner._entry` \u002F `harnesses._runner`\nsubprocesses an `omni run` turn spawns (a plain server SIGTERM leaves these\norphaned). The sweep is scoped to this interpreter, so it never touches another\nworktree. After a **live** session, sweep manually:\n\n```bash\n.venv\u002Fbin\u002Fomni server stop\npgrep -af \"$(pwd)\u002F.venv\u002Fbin\u002Fpython -m omnigent\" | grep -E \"_entry|_runner|_daemon\" || echo clean\n```\n\n## Honesty\n\nIf a worker CLI, credential, or egress isn't available, say the live CUJ was\n**skipped** — don't claim it passed. The strongest evidence is a reproduced\nbaseline plus the flipped check (mock loop) or the observed round trip in\n`…\u002Fitems` + `…\u002Fchild_sessions` (live). Report the real `SUMMARY` lines, not a\nsummary of a summary.\n","# polly orchestrator: end-to-end CUJ dev & testing\n\n`polly` (`examples\u002Fpolly\u002F`) is a multi-agent **coding orchestrator**: a\n`claude-sdk` \"brain\" that writes no code itself and delegates everything to three\ncoding sub-agents — `claude_code` (claude-native), `codex` (codex-native), and\n`pi` (headless, multi-model). Its critical user journeys are orchestration\nbehaviors, not single-turn answers:\n\n- **roster preflight** — first turn runs `command -v claude codex pi`, routes\n  only to workers whose CLI resolved.\n- **investigate** — read-only work fanned to `explore`\u002F`search` sub-agents;\n  synthesize from their reports.\n- **fanout** — independent tasks, each in its own git worktree + sub-agent, each\n  opening its own PR.\n- **cross-review** — an implementer's diff is verified by a **different-vendor**\n  sub-agent (diff + contract only); blocking issues become fix-tasks.\n- **plan gate \u002F inbox** — pull the human in at the plan gate; supervise via the\n  inbox + autowake, never busy-poll.\n- **guardrails** (`omnigent.inner.nessie.policies`) — `blast_radius` (deny\n  force-push \u002F `rm -rf \u002F`), `spawn_bounds` (cap dispatches per turn),\n  `headless_subagent_purpose_guard` (every dispatch needs `args.purpose`).\n\nThis skill tests those CUJs two ways. Use **both** — they cover different things:\n\n| Half | What it proves | Needs |\n|------|----------------|-------|\n| **Mock loop** (`polly_cuj.py`) | The **substrate\u002Fmechanics** — the brain is *scripted*, so this proves bundle load, server-side policy resolution, bridged `sys_*` tool dispatch, the guardrail DENYs, and fan-out — deterministically, with no creds | nothing (mock LLM) |\n| **Live recipe** | polly's **judgment** — does the real brain preflight, decompose, delegate, cross-review, and pull in the human correctly | real `claude`\u002F`codex`\u002F`pi` + model creds + network |\n\n> Like the sibling harness skills, turns run from your **current checkout**\n> (`omni run \u003Cbundle> --server \u003Curl>` = local runner + remote server), so testing\n> exercises exactly the code you're on.\n\n## Interpreter\n\nThe driver and CLI need the repo's Python ≥3.12 env. If `.venv\u002F` is missing,\ncreate it once from the checkout:\n\n```bash\nuv run --frozen python -c \"import omnigent; print('ok')\"   # builds .venv\n```\n\nThen use `.venv\u002Fbin\u002Fpython` \u002F `.venv\u002Fbin\u002Fomni` below.\n\n---\n\n## Part A — the deterministic mock loop (`polly_cuj.py`)\n\nThe driver boots a throwaway local Omnigent server (which carries\n`omnigent.inner.nessie.policies` — the module polly's guardrails resolve) plus\nthe repo's mock-LLM server, rewrites the polly bundle to the `openai-agents`\nharness wired to the mock, then runs `omnigent run` turns where the brain is\n*scripted* (text or tool calls). It prints one `SUMMARY {json}` per scenario and\nexits non-zero if any check failed.\n\n```bash\n.venv\u002Fbin\u002Fpython .claude\u002Fskills\u002Fpolly-e2e-dev\u002Fpolly_cuj.py --list-scenarios\n.venv\u002Fbin\u002Fpython .claude\u002Fskills\u002Fpolly-e2e-dev\u002Fpolly_cuj.py --scenario all\n.venv\u002Fbin\u002Fpython .claude\u002Fskills\u002Fpolly-e2e-dev\u002Fpolly_cuj.py --scenario guardrail_purpose --keep\n```\n\nRead the result with `… | grep '^SUMMARY' | python -m json.tool`. Each run takes\n~45–55s for all five scenarios; no credentials or egress are required.\n\n### Scenario catalog\n\n| Scenario | Scripts the brain to… | Hard check |\n|---|---|---|\n| `boot` | reply with text | exit 0 + non-trivial reply (bundle load, server-side policy resolve, turn completes) |\n| `tool_dispatch` | call `sys_os_shell` to write a sentinel | the file appears on disk (bridged `sys_*` dispatch works; `blast_radius` ALLOWs benign shell) |\n| `guardrail_purpose` | `sys_session_send` with **no** `args.purpose` | tool output carries `Denied by policy: … must declare what kind of work it is` (`headless_subagent_purpose_guard`) |\n| `guardrail_blast_radius` | `sys_os_shell(\"git push --force …\")` | tool output carries `Denied by policy: … blast-radius policy` |\n| `fanout_dispatch` | emit 7 `sys_session_send` in one turn | 6 dispatch handles created and the seventh is denied by `spawn_bounds` |\n\n### The verifiable before→after loop\n\nThe driver exists for a *loop*, not a one-shot. To prove a fix:\n\n1. On the **unfixed** code, run the scenario → a check is `false` (baseline).\n2. Make the change.\n3. Run the **same** scenario → the check **flips** to `true`.\n\nA fix is \"verifiable\" only if a check flips. If it doesn't flip, you can't prove\nthe change did anything — keep working. To cover a new mechanism, add a\n`scenario_*` function + a row in `_SCENARIOS` (each builds a bundle, scripts the\nmock, runs a turn, and asserts an **observable effect** — a session item, a deny\nsentinel, a file on disk).\n\n### What the mock loop can and can't prove\n\nIt tests **mechanics** because the brain is scripted: tool dispatch, the\nguardrail gate, session persistence, fan-out plumbing. It does **not** test\npolly's judgment (whether the *real* brain preflights, decomposes, picks the\nright vendor, cross-reviews). That is the live recipe.\n\n---\n\n## Part B — the live recipe (real claude\u002Fcodex\u002Fpi)\n\n### Prereqs (check first)\n\n1. **You're on the branch you want to test.**\n2. **A Claude provider for the brain** (`omni setup`, or `ANTHROPIC_API_KEY`, or\n   a Databricks default). Verify booleans only — never print keys.\n3. **Worker CLIs on PATH** — this *is* the roster preflight:\n   ```bash\n   command -v claude codex pi || true\n   ```\n   A worker is launchable only if its binary resolved. Cross-review needs **two\n   different vendors** available.\n4. **Network egress** to the model backends; **`gh`** authed if you want real PRs.\n\n### Run a live turn\n\n```bash\n.venv\u002Fbin\u002Fomni server --background && .venv\u002Fbin\u002Fomni server status   # prints $SERVER, e.g. http:\u002F\u002F127.0.0.1:6767\nSERVER=http:\u002F\u002F127.0.0.1:6767\ntimeout 280 .venv\u002Fbin\u002Fomni run examples\u002Fpolly \\\n  -p \"Investigate how the runner enforces tool-call policies and report file:line evidence.\" \\\n  --server \"$SERVER\" 2>&1\n```\n\nAlways pass `--server \"$SERVER\"`; omitting it routes to the configured **remote**\ndeploy, which may be stale and reject parts of the bundle.\n\n### Observe CUJs (CLI + HTTP API + filesystem)\n\nGrab the session id, then read the transcript and the side effects:\n\n```bash\nSID=$(curl -s \"$SERVER\u002Fv1\u002Fsessions?kind=default&order=desc&limit=1\" | python -c \"import sys,json;print(json.load(sys.stdin)['data'][0]['id'])\")\ncurl -s \"$SERVER\u002Fv1\u002Fsessions\u002F$SID\u002Fitems\"          | python -m json.tool | tail -60   # brain transcript + tool calls\ncurl -s \"$SERVER\u002Fv1\u002Fsessions\u002F$SID\u002Fchild_sessions\" | python -m json.tool             # dispatched sub-agents\ngit worktree list                                  # fanout: one per task\ncat .polly\u002Fregistry.json 2>\u002Fdev\u002Fnull               # polly's task list\ngh pr list --author \"@me\"                          # each implementer opens its own PR\n```\n\n### Per-CUJ live playbook\n\n| CUJ | Drive it | Look for |\n|---|---|---|\n| roster preflight | first live turn on a box missing a CLI | polly tells you which worker is unavailable; routes around it |\n| investigate | prompt a read-only question (\"explain\u002Faudit\u002Fwhy does X…\") | `child_sessions` with `purpose: explore\u002Fsearch`; answer cites their reports, not polly's own deep reads |\n| fanout | prompt 2–3 independent changes | one worktree + one sub-agent + one PR per task |\n| cross-review | let an implementer finish | a **different-vendor** reviewer child with `purpose: review`; blocking issues sent back to the **same** implementer session |\n| plan gate \u002F inbox | a multi-step task | polly pauses for human approval at the plan gate; ends its turn after dispatch and is autowoken by the inbox (no busy-poll) |\n| guardrails (ASK) | a task that pushes\u002Fmerges | the runner surfaces an approval card; `ask_timeout: 86400` keeps it open |\n\nFor the guardrail **DENY** set (force-push, `rm -rf \u002F`, unmarked dispatch,\nfan-out cap), prefer the **mock loop** — it's deterministic and creates no real\nside effects.\n\n---\n\n## CUJ coverage map\n\n| CUJ | Mock loop | Live recipe |\n|---|---|---|\n| boot \u002F turn completes | `boot` | any live turn |\n| bridged `sys_*` dispatch | `tool_dispatch` | tool calls in `…\u002Fitems` |\n| `headless_subagent_purpose_guard` | `guardrail_purpose` ✅ | (deny — prefer mock) |\n| `blast_radius` | `guardrail_blast_radius` ✅ | ASK card on push\u002Fmerge |\n| `spawn_bounds` | `fanout_dispatch` ✅ | verify cap live |\n| fanout delegation | `fanout_dispatch` (handles) | `child_sessions` + worktrees + PRs |\n| investigate \u002F cross-review \u002F plan gate \u002F inbox | — (needs judgment) | live playbook above |\n\n---\n\n## Known sharp edges (found while building this skill — verify, may change)\n- **Two deny formats.** Bridged `sys_*` tools surface a denial as\n  `{\"error\": \"Denied by policy: \u003Creason>\"}`; SDK function tools use\n  `[Denied by policy: \u003Cname>] {json}`. Both share the `Denied by policy:`\n  marker — match on that plus a policy-specific reason fragment (the driver does).\n- **Live fan-out needs the worker CLIs.** In the mock loop, sub-agents are\n  rewritten to `openai-agents` so a dispatch needs no binary. Live, a missing\n  `claude`\u002F`codex`\u002F`pi` makes that worker fail to boot — treat it as UNAVAILABLE.\n- **Default server gotcha.** `config.yaml`'s `server:` points at a remote deploy;\n  always pass `--server \"$SERVER\"` for local testing.\n\n## Code & tests\n\n- **Bundle \u002F prompt \u002F guardrails:** `examples\u002Fpolly\u002Fconfig.yaml`\n- **Sub-agents:** `examples\u002Fpolly\u002Fagents\u002F{claude_code,codex,pi}\u002Fconfig.yaml`\n- **Orchestration skills:** `examples\u002Fpolly\u002Fskills\u002F{investigate,fanout,cross-review}\u002FSKILL.md`\n- **Guardrail policies:** `omnigent\u002Finner\u002Fnessie\u002Fpolicies.py`\n- **Runner-side gate:** `omnigent\u002Frunner\u002Fpolicy.py`; server-side tool-call\n  enforcement: `omnigent\u002Fserver\u002Froutes\u002Fsessions.py`\n- **Mock LLM server:** `tests\u002Fserver\u002Fintegration\u002Fmock_llm_server.py`\n\n```bash\n# Existing pytest e2e for polly (mock-LLM) — complementary to this skill:\nuv run --frozen --group test python -m pytest \\\n  tests\u002Fe2e\u002Ftest_polly_e2e.py \\\n  tests\u002Fe2e\u002Ftest_polly_cost_advisor_e2e.py \\\n  tests\u002Fe2e\u002Ftest_polly_subagent_model_e2e.py -q\n```\n\n## Teardown — non-negotiable\n\nThe driver reaps everything it starts, including the per-conversation\n`omnigent.host._daemon_entry` \u002F `runner._entry` \u002F `harnesses._runner`\nsubprocesses an `omni run` turn spawns (a plain server SIGTERM leaves these\norphaned). The sweep is scoped to this interpreter, so it never touches another\nworktree. After a **live** session, sweep manually:\n\n```bash\n.venv\u002Fbin\u002Fomni server stop\npgrep -af \"$(pwd)\u002F.venv\u002Fbin\u002Fpython -m omnigent\" | grep -E \"_entry|_runner|_daemon\" || echo clean\n```\n\n## Honesty\n\nIf a worker CLI, credential, or egress isn't available, say the live CUJ was\n**skipped** — don't claim it passed. The strongest evidence is a reproduced\nbaseline plus the flipped check (mock loop) or the observed round trip in\n`…\u002Fitems` + `…\u002Fchild_sessions` (live). Report the real `SUMMARY` lines, not a\nsummary of a summary.\n",{"name":5,"description":7},"deploy\u002Froland-id-au-omniagent","83ee3dcd78468bbe3baf4bb264a0c99a53aa0fec",".claude\u002Fskills\u002Fpolly-e2e-dev","https:\u002F\u002Fgithub.com\u002Froland-id-au\u002Fomniagent","https:\u002F\u002Fgithub.com\u002Froland-id-au","2026-09-16 03:15:34",{"source":8,"skillName":5,"commands":31,"prompt":41,"zipAvailable":42},[32,35,38],{"tool":33,"command":34},"npx","npx skills add roland-id-au\u002Fomniagent --skill polly-e2e-dev",{"tool":36,"command":37},"bunx","bunx skills add roland-id-au\u002Fomniagent --skill polly-e2e-dev",{"tool":39,"command":40},"pnpm","pnpm dlx skills add roland-id-au\u002Fomniagent --skill polly-e2e-dev","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Froland-id-au\u002Fomniagent\u002Fblob\u002Fdeploy\u002Froland-id-au-omniagent\u002F.claude\u002Fskills\u002Fpolly-e2e-dev\u002FSKILL.md",true,[44],{"path":45,"resourceType":46,"resourceTypeDesc":47,"sizeBytes":48,"sourceHtmlUrl":49},"polly_cuj.py","SCRIPT","脚本",26719,"https:\u002F\u002Fgithub.com\u002Froland-id-au\u002Fomniagent\u002Fblob\u002Fdeploy\u002Froland-id-au-omniagent\u002F.claude\u002Fskills\u002Fpolly-e2e-dev\u002Fpolly_cuj.py",[51,58,65,72,77,82],{"skillNo":52,"name":53,"nameZh":6,"description":54,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":55,"categories":56,"keywords":57,"publishedAt":19},"01M7CTDVNPM78AJ051GVDB44X5","deep-research","Research checklist and source-quality guidance for the archer e2e fixture.","https:\u002F\u002Fgithub.com\u002Froland-id-au\u002Fomniagent\u002Fblob\u002Fdeploy\u002Froland-id-au-omniagent\u002Fwork\u002Fomnigent-main\u002Ftests\u002Fresources\u002Fexamples\u002Farcher\u002Fskills\u002Fdeep-research\u002FSKILL.md",[],[],{"skillNo":59,"name":60,"nameZh":6,"description":61,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":62,"categories":63,"keywords":64,"publishedAt":19},"01M7CTDS8SPN8P5GK1Q4SCSY7K","pi-e2e-xyz-greet-c4a8d5","Test greeter — pi skills e2e. The unique suffix c4a8d5 appears in the skill name so a string match in the agent's output proves Pi loaded this skill.","https:\u002F\u002Fgithub.com\u002Froland-id-au\u002Fomniagent\u002Fblob\u002Fdeploy\u002Froland-id-au-omniagent\u002Fwork\u002Fomnigent-main\u002Ftests\u002Fresources\u002Fagents\u002Fpi_skills_none\u002Fskills\u002Fpi-e2e-xyz-greet-c4a8d5\u002FSKILL.md",[],[],{"skillNo":66,"name":67,"nameZh":6,"description":68,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":69,"categories":70,"keywords":71,"publishedAt":19},"01M7CTDP4R9F06966W78WNZS2Y","pi-e2e-xyz-count-d2f6e1","Test counter — pi skills e2e. The unique suffix d2f6e1 appears in the skill name so a string match in the agent's output proves Pi loaded this skill.","https:\u002F\u002Fgithub.com\u002Froland-id-au\u002Fomniagent\u002Fblob\u002Fdeploy\u002Froland-id-au-omniagent\u002Fwork\u002Fomnigent-main\u002Ftests\u002Fresources\u002Fagents\u002Fpi_skills_none\u002Fskills\u002Fpi-e2e-xyz-count-d2f6e1\u002FSKILL.md",[],[],{"skillNo":73,"name":60,"nameZh":6,"description":61,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":19},"01M7CTDKP4W1Q18ZCY0XANDSEG","https:\u002F\u002Fgithub.com\u002Froland-id-au\u002Fomniagent\u002Fblob\u002Fdeploy\u002Froland-id-au-omniagent\u002Fwork\u002Fomnigent-main\u002Ftests\u002Fresources\u002Fagents\u002Fpi_skills_list\u002Fskills\u002Fpi-e2e-xyz-greet-c4a8d5\u002FSKILL.md",[],[],{"skillNo":78,"name":67,"nameZh":6,"description":68,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":19},"01M7CTDFBMA3EBZNV7J380THGP","https:\u002F\u002Fgithub.com\u002Froland-id-au\u002Fomniagent\u002Fblob\u002Fdeploy\u002Froland-id-au-omniagent\u002Fwork\u002Fomnigent-main\u002Ftests\u002Fresources\u002Fagents\u002Fpi_skills_list\u002Fskills\u002Fpi-e2e-xyz-count-d2f6e1\u002FSKILL.md",[],[],{"skillNo":83,"name":60,"nameZh":6,"description":61,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":84,"categories":85,"keywords":86,"publishedAt":19},"01M7CTDCVTXTG72BKEV2HY7M6W","https:\u002F\u002Fgithub.com\u002Froland-id-au\u002Fomniagent\u002Fblob\u002Fdeploy\u002Froland-id-au-omniagent\u002Fwork\u002Fomnigent-main\u002Ftests\u002Fresources\u002Fagents\u002Fpi_skills_all\u002Fskills\u002Fpi-e2e-xyz-greet-c4a8d5\u002FSKILL.md",[],[]]