test(evals): show what an agent does with the analytics gate on first contact - #312
angeloashmore wants to merge 1 commit into
Conversation
… contact The analytics gate refuses an agent's command until it passes --analytics-task-id and --analytics-intent, and explains how on stderr. No eval covered that moment. Every eval but know-the-cli installs the Prismic skill, which states the options up front, so the agent never judges the gate on its own; know-the-cli drops the skill but also drops the CLI, so no command runs. This eval keeps the CLI and drops the skill. It asserts that no call is rejected for missing the options, and that the agent does not raise them with the user. Both fail today. The opening command is always rejected, which costs a call and a turn in every agent session. In a weekly ecosystem eval, Claude Code read the refusal as a prompt injection, declined to comply and reported the CLI as untrustworthy instead of running it again. Sampled out of harness, claude-opus-5 raised the options with the user in about half of 33 runs, ranging from a note on method to a privacy warning about sending the user's request to analytics. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ANFuYqfG55YAJUNNREVgE6
|
Closing — superseded. This eval asserted that no command is ever rejected by the gate, which encoded a design that was rejected: the id has to be on the first command, so an agent starting a request will always have its opening command refused. A refused command never ran, so it costs a call and loses no data, and asserting on it made a working design permanently red. What replaced it, on a realistic two-request task of ~14 commands, run with and without the skill:
Two harness changes came out of it and are worth keeping either way: A new PR will carry the eval alongside the CLI change. Generated by Claude Code |
This is the first of two stacked draft PRs. This one only measures; #313 (stacked on it) changes the CLI. Open them side by side to compare.
Why
In a weekly ecosystem eval, Claude Code ran
npx prismic whoami, hit the analytics gate, and wrote this to the user instead of running the command again:Codex, same sandbox, same message, complied and passed the options on all 20 of its CLI calls. So the gate splits agents by how cautious they are, and the analytics it collects are biased by that.
No eval could see this. Every eval except
know-the-cliinstalls the Prismic skill, whose item 7 states the options up front, so the agent never has to judge the gate on its own.know-the-clidrops the skill but also drops the CLI, so no command ever runs. The quadrant where the bug lives — CLI present, skill absent — had no coverage:installCli: trueinstallCli: falseinstallSkill: trueinstallSkill: falseknow-the-cliWhat this adds
evals/trust-the-cli.eval.ts, cold start (installSkill: false), acrossclaude-sonnet-5andclaude-opus-5. Two assertions:evals/it.tsgainsoutputsonAgentResult(the tool results the agent read), which assertion 1 needs — argv alone cannot show whether a call was rejected.Result on this branch
3 of 6 trials fail. The three that pass ran
prismic --helpfirst, met the options in the AGENTS section, and never tripped the gate; the three that fail went straight to a command:Evidence behind the judge criterion
Sampled out of harness (real
claude -p, fresh config, no skill, realprismic@1.19.0, Prismic MCP connected and answering, Vercel authenticated — the ecosystem sandbox as closely as I could rebuild it):claude-opus-5claude-sonnet-5Opus, unprompted:
One caveat, stated plainly: none of those 94 runs reproduced the full refusal from the ecosystem eval — every one complied in the end. I matched Claude Code version (2.1.276), model, prompt, MCP, effort and system prompt; the only difference I could still measure was a 12.8k-character auto-memory block the sandbox had and I could not enable locally, since it is server-gated. So the refusal is the tail of this distribution, not something this eval will catch every run. What it does catch deterministically is the rejected call, which is the same root cause.
🤖 Generated with Claude Code
https://claude.ai/code/session_01ANFuYqfG55YAJUNNREVgE6