Some scenarios cannot run automatically because drill has no harness adapter for the target — the Codex App desktop client has no CLI or tmux entry point the way claude and codex do. These scenarios are marked manual: true in their YAML and use a human-in-the-loop protocol.
Three phases. The agent never runs Codex App directly. The tester never writes a verdict by hand.
verify.criteria, writes a verdict JSON, saves to results/<scenario>/codex-app/YYYY-MM-DD-manual/verdict.json.Deliver as one self-contained message to the tester:
Exact repo state Codex App should be launched against. Pull from setup.notes if present, otherwise translate setup.helpers + setup.assertions into prose. Include: which repo/directory, branch, whether to expect a worktree vs normal checkout, any required/forbidden files (e.g. .gitignore entries).
Render turn 1's intent as a natural first-person message the tester can paste verbatim into Codex App. Don't leak internal test language like "Do NOT say 'create a worktree'" — that's instruction for the test author, not the end user. Convert it to what a real user would actually type.
Example:
Intent: "Ask the agent to use the worktree skill to get set up for a notifications feature. Do NOT say 'create a worktree' — just reference the skill by name."
Rendered prompt: "hey, can you use the worktree skill to get me set up for a notifications feature?"
For each additional turn, give the tester a short decision rule — not a verbatim script. E.g. "If the agent asks a clarifying question like branch name, answer concisely. If it stops to ask whether you want a worktree at all, tell it you already asked for the skill and it should proceed."
Ask the tester to paste back:
git worktree list, directory tree, branch state)For each criterion in verify.criteria, write one entry:
{
"criterion": "<verbatim from scenario>",
"passed": true | false,
"evidence": "<quoted snippet from transcript>",
"rationale": "<only if passed is inconclusive or needs context>"
}
Rules:
evidence. No paraphrasing.passed: false with rationale explaining what was missing. Don't guess.Save to results/<scenario>/codex-app/YYYY-MM-DD-manual/verdict.json:
{
"scenario": "<scenario-name>",
"backend": "codex-app",
"manual": true,
"user_posture": "<spec-aware|naive|...>",
"passed": <true iff every criterion.passed is true>,
"criteria": [ ... ],
"notes": "<optional: cross-criterion observations>"
}
Matches the format of the existing results/worktree-codex-app-detached-head/codex-app/2026-04-09-manual/verdict.json.
manual: trueDo NOT use this procedure for scenarios drill can run itself (claude, codex, gemini backends) — use drill run instead.
$CODEX_HOME/worktrees/) is load-bearing for worktree scenarios. The same prompt gives different results in a normal checkout.