fix(evals): remove synthetic system prompt hints, install skills natively per harness (AI-1034) - #180
Draft
claude[bot] wants to merge 3 commits into
Draft
fix(evals): remove synthetic system prompt hints, install skills natively per harness (AI-1034)#180claude[bot] wants to merge 3 commits into
claude[bot] wants to merge 3 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
claude
Bot
force-pushed
the
fix/remove-eval-prompt-hints
branch
from
August 7, 2026 16:37
f2952bb to
ecfee71
Compare
The eval harness handed every agent a synthetic system prompt. For the three CLI harnesses that prompt described a tool surface they do not have (`bash`, `files_read`) and coached them on how to end a turn — both of which bias exactly what an eval is supposed to measure: out-of-the-box behaviour. The CLI engine now treats the system prompt as optional. When it is empty, nothing is staged and nothing is passed: - `engine` writes `$HOME/.eval/system-prompt.txt` only for a non-empty prompt, and leaves `RunnerExecArgs.systemPromptPath` undefined otherwise. - claude-code omits `--append-system-prompt-file` entirely. - codex and opencode, which have no system-prompt flag, stop prepending a block (and its blank-line separator) to the *user* prompt. `LocalStackSessionArgs` gains a required `agent: AgentHarnessId` so the sandbox layer can tell a CLI harness from the in-process ai-sdk one. Refs AI-1034, #164 Co-Authored-By: Claude <noreply@anthropic.com>
…listing (AI-1034) Skills were installed with a flagless `skills add`, which — finding no agent CLI installed yet — falls back to every one of the 71 agents the CLI knows. That scattered ~53 stray roots across the workspace (`.adal`, `.factory`, and non-dotted `data/` and `skills/` among them), and the workspace is exported into run artifacts and scored. It is also order-dependent: had an agent CLI been installed first, the fallback would have quietly stopped producing `.claude/skills` altogether. `skills add` now names the three CLI harnesses explicitly, which installs into exactly the two project scopes they discover natively: - `.claude/skills/` — Claude Code - `.agents/skills/` — Codex and OpenCode This is the actual fix for Codex, which does not read `.claude/skills` at all and therefore saw no skills in any eval. All three are installed unconditionally: the ids collapse to two directories, an unused copy costs a few kilobytes, and no agent id has to be threaded through `createAgentEnvironment` for correctness. Argument order matters — `--agent` is variadic, so the source directory must precede it and `--skill` terminates the list. `--copy` stays: symlink mode skips agents whose top-level directory does not already exist. With each CLI discovering, advertising and loading skills itself, `buildSkillsPrompt` becomes ai-sdk-only, like `buildToolSurfaceAddendum`. The block it rendered told agents to read `.claude/skills/<name>/SKILL.md` with `files_read` — a path Codex cannot see and a tool no CLI harness has. The post-install check now verifies every agent scope, so a skill missing from one of them fails loudly instead of leaving that harness silently skill-less. Refs AI-1034, #164 Co-Authored-By: Claude <noreply@anthropic.com>
… (AI-1034) Prompt assembly moves out of `run-eval.ts` (an entry script that runs `main()` on import, so it cannot be unit-tested) into `harness/system-prompt.ts`, keyed on `exp.agent.id`. Every block is now ai-sdk-only — the task framing, the tool-surface addendum, the skills listing — so a CLI harness assembles to `''` and the engine stages no system prompt file. The two "end your turn with a short summary" sentences are gone from both modes: stopping behaviour is part of what is measured. `runOne` now returns the exact assembled `systemPrompt`, so it lands in `results/<experiment>/<eval>.json` and what an agent was told is verifiable from the artifacts. It was previously unrecorded for every CLI harness. `export-results.ts` builds an explicit whitelist, so it does not reach the published web data. `apps/framework` gains a `test` script (`vitest run harness`), wired into `check`, so the prompt-assembly tests have a runner. Refs AI-1034, #164 Co-Authored-By: Claude <noreply@anthropic.com>
claude
Bot
force-pushed
the
fix/remove-eval-prompt-hints
branch
from
August 7, 2026 16:46
ecfee71 to
a2873a2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested via Slack thread
Closes AI-1034 (linear) and #164.
An eval is supposed to measure what an agent does out of the box. The harness was undercutting that in two ways: it prepended a system prompt of its own invention to every agent, and it installed skills where only one of the three CLI harnesses could find them.
Before
Every agent — Claude Code, Codex, OpenCode, and the in-process
ai-sdkone — received a harness-authored system prompt:bashtool andfiles_*tools. Those tools only exist forai-sdk; the CLI harnesses never see them and work the workspace with their own built-ins, so the text named tools they do not have.## Available skillsblock listing each skill and instructing the agent tofiles_read.claude/skills/<name>/SKILL.md. Again anai-sdk-only tool, and for Codex a path it cannot see at all.Codex and OpenCode have no system-prompt flag, so all of that was glued onto the user prompt — the task the model reads.
Skills were installed with a flagless
skills add. With no agent CLI installed yet, that CLI falls back to every one of the 71 agents it knows: ~53 stray roots in the workspace (.adal,.factory,.windsurf, … plus non-dotteddata/andskills/). The workspace is exported into run artifacts and is what gets scored. Only.claude/skillswas ever verified, and only.claude/skillswas advertised — but Codex does not read.claude/skills, so Codex runs effectively had no skills, whatever the injected listing claimed.After
--append-system-prompt-fileis omitted, and nothing is prepended to the user prompt. The user prompt is exactly the eval's prompt.ai-sdkis unchanged in substance — it is the one harness with no system prompt of its own, so it still gets task framing, the tool-surface description, and either the skills listing (local-stack,files_read) or theload_skilltool (tools mode). The two turn-ending sentences are gone for it too..claude/skills/for Claude Code,.agents/skills/for Codex and OpenCode. Each CLI then discovers, advertises and loads them through its own mechanism — Codex injects its own<skills_instructions>block, OpenCode exposes itsskilltool. Skills are genuinely available to Codex for the first time.results/<experiment>/<eval>.json, so what an agent was told is now verifiable from the artifacts.How
packages/core/src/agents/engine.tstreats the system prompt as optional: empty means no staged file andsystemPromptPath: undefined. The three runners drop their respective mechanisms for passing it. Prompt assembly moves out ofrun-eval.ts(an entry script that callsmain()at import, so untestable) intoapps/framework/harness/system-prompt.ts, keyed onexp.agent.id; every block isai-sdk-only, so a CLI harness assembles to''.buildSkillsPromptgains the sameagentguardbuildToolSurfaceAddendumalready has.packages/sandbox/src/skills.tsnames the harnesses explicitly:Two details are load-bearing and covered by tests.
--agentis variadic, so the source directory must come before it —skills add --agent codex <dir>swallows<dir>as an agent name and dies withMissing required argument: source— and--skillterminates the agent list.--copystays because symlink mode skips any agent whose top-level directory does not already exist.All three agents are installed unconditionally rather than threading
exp.agent.iddown to the installer. The three ids collapse to two directories, an unused one costs a few kilobytes of copied files, and this keeps a single code path. Naming them explicitly also removes a latent time bomb: the flagless fallback is install-order dependent, and had an agent CLI been installed before skills, it would have silently stopped producing.claude/skills.The post-install check now verifies every agent scope, so a skill missing from one fails loudly rather than leaving that harness quietly skill-less.
Skill-usage scoring is unaffected — the extractor regex matches any
<anything>skills/<name>/SKILL.mdpath, so it handles.agents/skills/…as readily as.claude/skills/….Verification
Automated:
pnpm format:checkclean;@supabase-evals/framework6/6,@supabase-evals/core111/111,@supabase-evals/sandbox49/49;pnpm typecheckclean. New coverage asserts that a CLI harness assembles to an empty prompt even with skills installed, thatai-sdkstill gets its listing, that the install command carries all three agents in the correct argument order, and that a skill missing from any agent scope throws.Two pre-existing failures on
mainare untouched and unrelated: the framework smoke test (needsOPENAI_API_KEY) andapps/web'seval-results.test.ts > describes each experiment the same way on every one of its runs(a data problem in the on-hold results JSON).Not verified here: no Docker daemon, so
packages/sandbox/test/docker.test.ts— including the updated multi-scope install assertions — did not run, and no real eval was executed. The CLI behaviour the change relies on was established by executing the pinned binaries directly (skills@1.5.11,@openai/codex@0.138.0,opencode-ai@1.18.5):codex debug prompt-inputfinds.agents/skillsand not.claude/skills, andopencode serve+GET /skillfinds both.Prompt-level verification is now possible for the first time. The assembled
systemPromptis recorded in the run artifacts — it previously was not, for any CLI harness — so a single narrow dispatch is enough to confirm the prompt an agent actually received:A single eval × experiment pair takes roughly 4–6 minutes. Then read
systemPromptout ofresults/<experiment>/<eval>.json— it should be""forclaude-code,codexandopencode— and confirm the skills the agent loaded came from its own harness listing.Expected impact on numbers
This changes what every CLI-harness agent is told, so benchmark numbers are expected to move — in both directions. Codex in particular gains working skills where it previously had none. Published numbers are not comparable across this change until a full results refresh lands.
Results JSON is deliberately untouched in this PR: a refresh is already in flight, and this branch must not conflict with it. Refresh after merge, then compare.
Open item
The team AI Policy doc could not be reviewed: the Notion page is not shared with the "Claude Tag General Agent Access" integration.
Generated by Claude Code