About 10–12 minutes end to end: install the skills,
connect the MCP, paste one prompt. The bundled agent is meant to fail this
exam — expect 25 to 67 out of 100, where 100 is the pass mark — then add one
sentence to its prompt and watch it go green.
- Examinee — a clone of the agent under test. It works a real task against digital twins of GitHub and Slack (deterministic fakes with the same API shapes as production), and every tool call is recorded.
- Coach — your coding agent. It installs, connects, launches the run, and brings the results back into the conversation.
- Grader — Pome’s scorer, and the only thing that scores. It reads the twins’
recorded calls and their final state and checks them against the task’s
criteria, 0–100. Criteria come in two kinds: deterministic
[code]checks, and[model]criteria the narrator reads and answers in prose, advisory and outside the score. This task declares only[code]ones, so every number on this page came from code reading state.
If you already have your own agent in a repo, run this example first to learn
the loop, then see Your own agent to register it
and get a
pome.json.What you’re about to run
The capstone uses a bundled support-triage example — a small local agent (Claude Agent SDK), not your repo.- Role. Support-triage bot for the Acme eng org: watch
#supporton Slack for bug reports, track each as a GitHub issue inacme/orders-service, and post the issue link back to the thread. - World. Deterministic GitHub + Slack twins: same API shapes as production, no real users or data.
- The exam. A customer re-reports a bug the repository already tracks — but
not on the issue that looks like it. Issue #47 is a word-for-word
match for the report. Issue #23 is the tracking issue that consolidates
it, and
acme/orders-servicerecords new occurrences there — a convention written down indocs/triage-policy.mdinside the seeded repo, and named in no prompt. - Why it fails. The bundled agent is not sabotaged. It is told to search before filing and it does; it finds #47, comments there, and sends that link back. It was simply never told the org has a convention — the honest state of most production triage agents. The difficulty lives in the seeded world, not in a planted defect.
- Why this example. The fail → fix → pass story is one sentence added to the system prompt behind an env switch, which you flip at the end of this page.
What the paste-prompt does
When you paste the prompt below, your coding agent becomes the coach. It will show a short checklist and ask “Shall I proceed?” before running anything. At a high level it will:- Fetch and build the local support-triage examinee
- Sign you into Pome (OAuth) and confirm identity / quota
- Save the duplicate-issue exam into your catalog
- Start a sandbox for that exam, registering the example agent from the slug in
the pack’s own
pome.json - Spawn the local examinee against those twins
- Finalize the run while the sandbox is still live (the one hard rule)
- Show the score, criteria table, and dashboard link in the chat
Before you start
- A coding agent that can connect to an MCP server, installed and signed in.
- The example examinee is a small
Claude Agent SDK process
that runs as its own subprocess, so it needs its own Anthropic credential
— an
ANTHROPIC_API_KEYin your environment, or a storedclaudelogin. Your editor’s own subscription does not cover it. - The walk pins the examinee to
claude-haiku-4-5. Which model sits the exam is part of the experiment, not a detail: onclaude-opus-5the bundled agent passes 5 of 5 with no fix at all — it fetches the policy file by reflex — and there is nothing left to demonstrate. - Node 24+ with
npmandnpx. - No Pome account needed up front: the OAuth consent screen opens on the prompt’s first tool call (its step 2, moments after you paste it) — that is where you sign in or sign up, no credit card.
Install the coach skills
skills CLI installs the Pome
coach skill set from
pome-sh/digital-twins
into your agent’s skills directory — the installer asks which agent you are
using, so pick yours there. Six skills, one job each: pome (entry router),
pome-intake (scope the agent), pome-suggest-tasks (propose tasks for an
agent you already have), pome-author-task (write exams), pome-verify-seed
(check seed state), and pome-run-task (launch, finalize, report). Together
they teach your agent the full loop.
--skill '*' installs all six in one pass. Without it the installer opens a
checklist with nothing ticked and you tick them one at a time; the coach only
works as a set.
About the security table it prints. The installer runs third-party audits
(Snyk, Socket) and shows a risk level per skill. Two things drive ours, and
both are the job rather than a defect: the skills talk to the Pome MCP at
mcp.pome.sh at runtime, and they hand your agent a session-scoped bearer so
it can reach the twins. That bearer is minted per run, expires with the
sandbox, and reaches nothing outside it. The ratings are Snyk’s and Socket’s,
re-scored on their own schedule, so the level you see may differ from a
colleague’s. The per-skill findings are public — read them at
skills.sh/pome-sh/digital-twins.Connect the Pome MCP
Addhttps://mcp.pome.sh/mcp to your coding agent as a remote HTTP MCP server.
There is no API key: auth is OAuth, and the consent screen opens on the first
tool call.
Connect to the MCP has the wiring for each client — the
one-line CLI form, the mcpServers JSON block, and what to do for a headless or
managed agent. That page is where per-client configuration lives.
Every command here is plain text you can read before you run it — the install
path never pipes a script into your shell and never injects remote config.
There is no API key to paste: on the first tool call, your agent discovers the
OAuth metadata and opens the Clerk consent screen (scopes: verify your
identity, basic profile, email address). Sign in — or sign up right there — and
the tools appear.
Paste the prompt
Open your coding agent anywhere (the example brings its own agent — your repo is not required) and paste:What the score means
Expect a failing run, and not a zero. Measured over five trials onclaude-haiku-4-5, the bundled agent scored 25 · 25 · 25 · 50 · 67 and
passed none of them. passThreshold is 100 — every criterion has to hold — so
a run that routes the report to #47 fails at 25 while still getting credit for
the one thing it verifiably did: it left a comment at all.
The spread is the interesting part. A 25 is the agent that never opened the
policy and commented on the textual match. A 50 or a 67 is the agent that
reached #23 anyway — inferring it from the tracking issue’s own body — but did
not name #47 in the comment, or still put #47’s link in front of the reporter.
Arriving at the right place is not the same as following the rule, and the
criteria do not give credit for luck.
Nothing in that verdict is a matter of opinion. All five criteria are
deterministic [code] checks read off the twins’ recorded calls and final
state; the task declares zero [model] criteria, so the narrator has
nothing to read here and nothing outside code touched the verdict. The report
names which criterion failed and the state the check actually read.
The one-line fix
The whole story is one sentence, and it is the repair a builder would actually make: tell the agent where its team’s rules live. It ships behind an env switch rather than a committed edit so both arms run from one commit — two numbers measured against two different trees are not comparable.POME_TRIAGE_POLICY_HINT=on appends this to the examinee’s system prompt
(policyHint() in support-triage/src/index.ts):
Before you comment on an issue or send anyone a link, read
docs/triage-policy.md in the repository and follow its routing rules.
Tell your coding agent:
What that sentence actually does, because it is not what it looks like. It
reads as a discoverability aid, and on
claude-haiku-4-5 it half is: 0 of 5
naive trials opened the policy file, 5 of 5 fixed ones did. But on
claude-sonnet-5, three of four naive failures had already read it and
routed to #47 anyway. A file the agent reads is data; its system prompt is
instruction; and a model correctly ranks instruction above data, or anything
it read could hijack it. So naming the file in the charter is not teaching the
agent where to look — it is transferring authority to that file. Carry that
to your own agent: if you want it to obey your team’s written conventions, you
have to say so.Why “v2” and not just “re-run”. You changed the prompt, so the thing under
test is not the agent that failed — it is a second agent. Declaring
agent_version is how you say so. Without it, both runs land in one run-set
reporting 1 of 2 trials clean — and since neither run declared a version, the
report refuses to read that as reliability: it says outright that it cannot
tell one agent run twice from two different agents, and points back at
agent_version. Honest, but it is a shrug where a score should be. The
baseline_group_id is the other half — it pairs the two run-sets, which is
what puts Compare to failing baseline on the green run-set’s page.Open your first report
get_report prints the score, the criteria table, and the dashboard link right
in your conversation. Open the link for the finalized report — and read it as a
diagnosis rather than a grade. Two of the five criteria carry the story, and
they fail in different places:
- A comment containing
#47exists on issue #23 fails on GitHub’s final state. The state-diff panel shows where the comment actually landed. - No message containing
issues/47appears in any public channel fails on what the agent told the reporter. This is the wrong-value guard: beside asserting the right answer, it asserts the object does not hold the specific wrong value this task’s failure mode produces. It is what separates did the right thing from did the known wrong thing.
get_file_contents call on
docs/triage-policy.md, because it changes what the fix is. If the fetch is
absent, the agent never found the rule. If it is there and the comment still
landed on #47, the agent read the rule and its own standing instruction
outranked it — a different problem, and one more prompt wording will not solve.
Next
Your own agent
Point Pome at your own repo and get a scored run.
Write a task
validate_task → save_task → verify_seed — graded exams for your agent.Evaluate an agent over MCP
The coach loop behind the paste-prompt, call by call.
Dashboard
Where runs, traces, and run handoffs live: app.pome.sh.