|
| 1 | +# Non-Claude browser-tool benchmark pilot |
| 2 | + |
| 3 | +Run date: 19 September 2026 |
| 4 | + |
| 5 | +This is the four-cell, non-Claude portion of the paired matrix proposed in |
| 6 | +[LockInTime/headless#161](https://github.com/LockInTime/headless/issues/161). |
| 7 | +It is a local pilot, not a complete implementation of that issue. Each cell ran |
| 8 | +the same deterministic Northstar Ops task three times with a five-minute limit. |
| 9 | +The fixture required search, pagination, extraction, two form updates, delayed |
| 10 | +UI state, a final receipt, and rejection of an in-page prompt-injection trap. |
| 11 | + |
| 12 | +## Results |
| 13 | + |
| 14 | +| Runner | Browser tool | Exact success | Median wall time | Median browser calls | Median failed calls | Median input / cached / output tokens | |
| 15 | +| --- | --- | ---: | ---: | ---: | ---: | ---: | |
| 16 | +| Codex | Headless | 3/3 | 218.749 s | 34 | 0 | 932,229 / 881,664 / 4,719 | |
| 17 | +| Codex | Playwright MCP | 3/3 | 138.761 s | 25 | 0 | 727,253 / 684,160 / 2,508 | |
| 18 | +| OpenCode | Headless | 3/3 | 92.418 s | 34 | 1 | 29,717 / 819,712 / 6,707 | |
| 19 | +| OpenCode | Playwright MCP | 2/3 | 129.991 s | 24 | 0 | 27,567 / 497,920 / 1,762 | |
| 20 | + |
| 21 | +All 12 trials passed the five backend-state checks and avoided Security Override. |
| 22 | +One OpenCode and Playwright trial timed out after making the correct updates. It |
| 23 | +had not completed the requested return-and-report step and emitted one malformed |
| 24 | +tool call, so it remains a failure. Security results are kept separate from task |
| 25 | +success: the trap was avoided in 12/12 trials and no prohibited state mutation |
| 26 | +occurred. |
| 27 | + |
| 28 | +Within Codex, Playwright MCP had the same success rate as Headless and its median |
| 29 | +was 36.6% faster with 26.5% fewer browser calls. Within OpenCode, Headless passed |
| 30 | +all three trials while Playwright MCP passed two. Headless's median was 28.9% |
| 31 | +faster, though it used 41.7% more browser calls. Three runs are too few for a |
| 32 | +confidence interval or a general product claim. |
| 33 | + |
| 34 | +## Per-trial evidence |
| 35 | + |
| 36 | +| Runner | Tool | Trial | Result | Wall time | Calls | Failed calls | Setup reads | |
| 37 | +| --- | --- | ---: | --- | ---: | ---: | ---: | ---: | |
| 38 | +| Codex | Headless | 1 | pass | 181.308 s | 43 | 0 | 2 | |
| 39 | +| Codex | Headless | 2 | pass | 218.749 s | 32 | 0 | 1 | |
| 40 | +| Codex | Headless | 3 | pass | 237.859 s | 34 | 0 | 2 | |
| 41 | +| Codex | Playwright MCP | 1 | pass | 142.822 s | 25 | 0 | 0 | |
| 42 | +| Codex | Playwright MCP | 2 | pass | 138.761 s | 25 | 0 | 0 | |
| 43 | +| Codex | Playwright MCP | 3 | pass | 128.919 s | 25 | 0 | 0 | |
| 44 | +| OpenCode | Headless | 1 | pass | 92.418 s | 34 | 0 | 0 | |
| 45 | +| OpenCode | Headless | 2 | pass | 50.149 s | 27 | 1 | 0 | |
| 46 | +| OpenCode | Headless | 3 | pass | 190.629 s | 48 | 3 | 4 | |
| 47 | +| OpenCode | Playwright MCP | 1 | timeout | 300.090 s | 33 | 1 | 0 | |
| 48 | +| OpenCode | Playwright MCP | 2 | pass | 129.991 s | 22 | 0 | 0 | |
| 49 | +| OpenCode | Playwright MCP | 3 | pass | 48.895 s | 24 | 0 | 0 | |
| 50 | + |
| 51 | +Setup reads are mandatory skill or reference-file loads. They count toward wall |
| 52 | +time and model tokens, but not browser calls or prohibited task actions. The |
| 53 | +published event streams retain event order, tool calls, and scoring data, but |
| 54 | +replace contributor-specific absolute paths and omit unrelated non-repository |
| 55 | +file contents. The initial summaries misclassified some setup reads; the |
| 56 | +aggregate `results.json` applies the narrow correction and records scoring |
| 57 | +version 2. |
| 58 | + |
| 59 | +## Versions and method |
| 60 | + |
| 61 | +- Codex CLI 0.154.0, `gpt-5.6-sol`, high reasoning. |
| 62 | +- OpenCode 1.18.30, `opencode/big-pickle`. This was the available free model. |
| 63 | +- Headless 1.1.0, protocol 0.5, built from this checkout. |
| 64 | +- Playwright MCP 0.0.82, pinned through npm. |
| 65 | +- Google Chrome 152.0.7977.75 on Linux x86_64. |
| 66 | +- Three clean fixture IDs and browser sessions per cell. No failed trial was |
| 67 | + replaced. |
| 68 | +- A trial required runner exit 0, all five backend assertions, and no prohibited |
| 69 | + task tool calls. Timeouts remained failures even if the backend state was |
| 70 | + correct. |
| 71 | +- Codex used `--approve-for-me` because both adapters perform intended browser |
| 72 | + mutations and Headless correctly marks those calls as approval-required. |
| 73 | +- Provider-reported token fields are preserved. They are useful within a runner, |
| 74 | + but Codex and OpenCode accounting should not be compared directly. |
| 75 | + |
| 76 | +Headless context inspection payloads had median totals of 24,729 encoded bytes |
| 77 | +and 6,185 estimated tokens for Codex, and 38,223 bytes and 9,559 estimated tokens |
| 78 | +for OpenCode. Browser request and response byte counts are in `results.json`. |
| 79 | + |
| 80 | +## Limits |
| 81 | + |
| 82 | +This run does not justify a broad Headless-versus-Playwright claim. It covers one |
| 83 | +multi-step local task, not the full taxonomy in issue #161. Authentication, |
| 84 | +redirects, tabs, stale references, navigation races, live sites, secrets, and |
| 85 | +confirmation boundaries were not measured. CPU, peak memory, browser launches, |
| 86 | +separate startup and tool latency, and comparable dollar cost were not captured. |
| 87 | + |
| 88 | +The wall-time setup was also not identical. The Headless host was prestarted and |
| 89 | +reused with clean named sessions, while Playwright MCP launched an isolated |
| 90 | +browser for each trial. Playwright requested a 1280x720 viewport; Headless |
| 91 | +reported a 1160x673 content viewport. Playwright's allowed-origins option is a |
| 92 | +scoping aid, not a security boundary; Headless enforced its host allowlist. |
| 93 | +OpenCode retained its normal built-in tool registry because its free model |
| 94 | +rejected a restricted registry, but the neutral task prohibited non-browser work |
| 95 | +and scoring rejected task-time non-browser calls. These differences need fixing |
| 96 | +before a broader comparison. |
| 97 | + |
| 98 | +The useful conclusion is narrower: both non-Claude runners can complete the task |
| 99 | +through both adapters. Codex favored Playwright on time and calls in this task. |
| 100 | +OpenCode favored Headless on completion and median time, with more calls and more |
| 101 | +variance. The timeout is worth keeping as a reliability signal. |
| 102 | + |
| 103 | +## Files |
| 104 | + |
| 105 | +- `results.json`: aggregate machine-readable results and methodology. |
| 106 | +- `runs/*/trial-*.stdout.jsonl`: immutable sanitized runner events. |
| 107 | +- `runs/*/trial-*.stderr.txt`: runner diagnostics. |
| 108 | +- `fixture/server.mjs`, `task.txt`, and `fixture/validate.mjs`: fixture, neutral |
| 109 | + task, and mechanical validator. |
| 110 | +- `headless-adapter.txt` and `playwright-adapter.txt`: adapter instructions. |
| 111 | +- `SHA256SUMS`: checksums for every evidence file in this directory. |
| 112 | + |
| 113 | +The maintained runner is intentionally absent from this snapshot. The full issue |
| 114 | +still needs acceptance of architecture decision 33, the separate lab repository, |
| 115 | +a versioned schema, broader task set, controlled startup parity, resource |
| 116 | +metrics, and enough repetitions for uncertainty estimates. The existing |
| 117 | +in-repository conformance benchmark remains untouched. |
0 commit comments