Skip to content

eval(headless): benchmark Maka, Codex, and Claude Code synchronously on DeepSeek V4 Flash #1970

Closed

Description

@Astro-Han

Problem

Users want a head-to-head comparison of Maka, Codex CLI, and Claude Code on the same DeepSeek V4 Flash runtime. The current headless harness supports only two arms per experiment, has no pinned Claude Code competitor adapter, and supports Codex only in its existing OpenAI composition. Two independent A/B runs would duplicate the Maka baseline and expose the result to round-to-round provider and infrastructure drift.

DeepSeek documents official integrations for both Claude Code and Codex, but the benchmark path does not yet implement those integration contracts.

Desired outcome

Extend the existing packages/headless Harbor/Pier path so one frozen Terminal-Bench 2.1 experiment schedules Maka, Codex CLI, and Claude Code as three synchronized arms for every task. All arms must use deepseek-v4-flash with the same task instruction, task snapshot, verifier, effort level, deadline policy, and declared execution policy; each agent retains its native system prompt and tool semantics.

The infrastructure must:

  • support native three-arm scheduling, resume identity, manifests, and reports without creating a parallel benchmark harness;
  • pin and verify an offline Linux/x64 Claude Code toolchain, route its Anthropic-compatible traffic through the existing credential proxy, and normalize its evidence into the existing cell contract;
  • configure the pinned Codex CLI with DeepSeek's official Responses API model catalog while keeping the real API key out of config files, command lines, logs, and task containers;
  • record comparable usage, cost, duration, tool-call, failure, and execution-identity evidence for all three arms.

Completion is accepted when a predeclared canary passes for all three arms and one full synchronized Terminal-Bench 2.1 run produces a checked-in docs/eval/ report containing per-arm Pass@1, token/cache usage, cost, duration, infrastructure failures, and per-task outcomes. Its manifest must record the benchmark snapshot, model/provider, effort, agent versions, toolchain and model-catalog fingerprints, and execution policy. Automated tests must cover both competitor integrations, secret boundaries, three-arm scheduling/resume, and report generation.

Alternatives or workarounds

Run Maka vs Codex and Maka vs Claude Code as separate A/B experiments. This reuses the current two-arm path, but it is not a synchronized three-way comparison and makes the shared Maka baseline vulnerable to run-to-run drift.

Activity

  1. Astro-Han commented on Aug 3, 2026

    @Astro-Han
    ContributorAuthor

    Claiming this. I’ll implement the synchronized three-arm harness on the existing packages/headless path: explicit agent/provider wire routing, DeepSeek support for Codex and a pinned Claude Code adapter, cohort scheduling with the existing pairwise summaries as projections, and the combined report/validation. I’ll open a draft PR when the implementation and canary-ready checks are complete.

  2. Astro-Han commented on Aug 4, 2026

    @Astro-Han
    ContributorAuthor

    Run log: infrastructure defects and operational interventions

    Recording what happened while producing the Terminal-Bench 2.1 numbers, so the report does not have to carry it. Everything here is either a harness defect we found and fixed, or an operational action taken outside git that a reader would need to know before reproducing the run.

    Harness defects found during the run

    All three were in the shared command-scope teardown, and all three were arm-directional: they can only fire for arms whose agent runs inside the task container, so the in-container arms absorbed failures the host-side arm could not.

    1. Teardown rewrote the agent's own exception (fix(headless): stop misfiling graded competitor cells as infrastructure failures #2090). cleanup_process_scope raised from a finally while the agent's exception was in flight, so an AgentTimeoutError reached Harbor as NonZeroAgentExitCodeError — a graded timeout recorded as an infrastructure failure. 17 claude-code cells in v7 were classified this way.

    2. The output replay had no teardown handle (fix(headless): reap the scoped command's output replay #2146). The wrapper captures a command's output and replays it after the command exits. When an agent-phase timeout stops the caller reading, that replay blocks in pipe_write forever and the exec never returns.

    3. Teardown itself was unbounded (fix(headless): bound teardown and mark the output replay #2151). Harbor's _run_docker_compose_command with timeout_sec=None is a bare await process.communicate(). A teardown that hung took the whole trial with it. Confirmed in production: two stalled cells' trial.log ends at Running command: <TERM cleanup> with no completion line, and their containers held zero scope leftovers — the hang was host-side, in the teardown exec. Observed stall: 1524 s.

      fix(headless): bound teardown and mark the output replay #2151 also fixed two defects found in review: the bridged executor in maka_agent.py had its own unbounded teardown exec, and the cleanup order let the wrapper fork a replay after the sweep had already passed it.

    Interventions outside git

    • Watchdog. An operational script polled for stalled cells and intervened. It is not in the repository. It fired 44 times (32 during v7, 11 during cc-repair, 1 during cc-forensic-v2) and it can only affect arms that run in a container, so it is arm-directional in the same direction as the defects above. Its behavior changed twice mid-benchmark: docker kill the container → "unstick" (kill scope leftovers, keep the container so the verifier can still run) → observe-only. Log: ~/.maka/eval/watchdog.log.
    • Code tree swapped mid-benchmark. The VM's checkout moved to 632b83c7 while a run was in flight; cells that started before and after that point ran different code. A second deploy (93470383, containing fix(headless): bound teardown and mark the output replay #2151) was done only after stopping the run first, so no run spans it.
    • /etc/docker/daemon.json edited on the VM, twice and out of git: an address-pool change, and "debug": true for forensics. The debug flag is still enabled and must be reverted; backup at /etc/docker/daemon.json.bak-forensic.
    • Host oversized to 32 cores, which changes achievable parallelism and is not part of any declared execution policy.

    Scoring and comparability caveats

    • Unequal retry budget. 17 cells received a third attempt while the other 72 received one. This is the anti-fishing property of pass@1 being unevenly applied, and it favors whichever arm occupied those 17.
    • Re-scored, not re-run. Some corrected outcomes were recovered from stored artifacts rather than re-run under the fixed harness. Those cells did not execute the fixed code path.
    • codex extract-elf was retrieved and re-judged separately from the normal path.
    • C1/C2 contamination between cohorts.
    • Network access is enabled asymmetry: this appeared in the codex arm only, so the arms did not see identical environment statements.
    • /opt/maka-agent mount leak: maka's own tree was visible inside the task container. Narrowing it is tracked separately.
    • Timed-out-but-passed base rate is 27–40%, which is why cells lost to infrastructure cannot be treated as failures — a stalled cell may well have passed.

    Security

    The provider API key is visible in plaintext in the VM's process list, passed via docker compose exec -e. No key reached git, logs, or artifacts, but the process-list exposure is real and should be closed before any further run on a shared host.

    Recurring operational failure worth naming

    Four separate times, a cleanup or probe command matched its own command line — pkill -f maka-harbor-command-scopes and pkill -f run-harness-ab both match the shell running them. Once it killed the remote shell mid-teardown; once it reported a phantom leftover of exactly 1. Any pkill -f / /proc sweep written against this harness needs the bracket trick or an explicit self-exclusion.

    Still open

    • Deploy verification: cc-recover-v2 is running on 93470383 with the watchdog in observe-only mode. If its log stays empty and no claude-code cell ends without a reward, fix(headless): bound teardown and mark the output replay #2151 is confirmed in production; if not, there is a hang path we have not found.
    • Architectural debt: three rounds of fixes on the same wrapper mechanism is evidence the mechanism is fragile, not that the fixes were wrong. The durable shape is a cancellable exec handle or an in-container supervisor owning the process tree (cgroup), rather than /proc sweeps plus PID files. That requires a Harbor/Pier API change.
  3. Astro-Han commented on Aug 5, 2026

    @Astro-Han
    ContributorAuthor

    Four-arm Terminal-Bench 2.1 run complete — results, and what the harness had to fix to produce them

    The four-arm comparison (Maka, Codex, Claude Code, Reasonix) around one DeepSeek V4 Flash model finished over all 89 tasks. Full report and per-task CSV in #2208; the harness changes it required are in #2177, now merged.

    Results. Codex 70/89 (78.65%), Maka 65/89 (73.03%), Claude Code 57/89 (64.04%), Reasonix 55/89 (61.80%). The Codex–Maka gap is not significant — 19 discordant pairs split 12/7, exact McNemar p = 0.359. Only Codex over Claude Code (p = 0.0072) and Codex over Reasonix (p = 0.0026) clear 0.05, and both survive Bonferroni. Maka has the lowest cost per pass ($0.03215).

    Two independent full runs agree, including on the non-significance. The earlier three-arm run over the same 89 tasks scored Codex 67, Maka 60, Claude Code 57, with Codex–Maka at p = 0.210. Codex is the only arm configured identically in both, and it is the informative one: 19% of its tasks changed outcome between the runs while its net score moved by 3. About a fifth of this suite is decided by run-to-run variation rather than by any property of the harness under test — that is the noise floor a five-task claim has to clear, and it does not.

    Where the spread actually comes from. On the 60 tasks where no arm exhausted its budget, the top three invert and land within 3.33 points: Claude Code 90.00%, Codex 88.33%, Maka 86.67%. Claude Code has the best conditional pass rate and the worst headline score because it ran out of budget on 26.97% of the suite — more than twice any other arm. The headline tracks whether an arm finishes, not whether it can solve the task.

    Topology decision. All four arms now run inside the task container. Maka previously ran host-side and bridged tool calls in, which made it the one arm compared under a different execution shape. Moving it exposed four defects, all fixed in #2177 — the two worth recording:

    • The economy axis was reporting 4% of real spend for one arm. The proxy discarded whatever the usage parser had read whenever a client hung up before [DONE]. Providers put the usage frame at the end of a stream but not after it, so it had usually already arrived. One arm was credited 1,088 output tokens against a true 27,633 — not a visible gap, a wrong number that read as fully metered. 40% of that arm's requests take this path.
    • Package-fetch noise was charged to whichever agent needed more packages. The same apt-get took 16 s or 300 s from the same host depending on which upstream path it landed on, against a 900 s budget. Redirecting to a regional mirror took one Maka cell from a 900 s timeout to a 111 s pass on an identical tool-call count.

    Contamination. One task is compromised: on db-wal-recovery, Maka deleted the encrypted WAL itself (opening the DB with the sqlite3 CLI triggered a WAL cleanup), then recovered by downloading the fixture from the public NousResearch/terminal-bench-2 dataset after matching main.db hashes. Codex passed the same task and attempted the same class of lookup against harbor-framework/terminal-bench-2, which 404s. Both pass, so it is a concordant pair: excluding it moves the scores to 64 and 69 and changes neither the gap nor any p-value. Claude Code is clean; the Reasonix hit is a false positive.

    Detection here only catches explicit benchmark-repo references. All four arms reach the network (Codex most, 430 requests across 52 domains). A stricter pass — comparing fetched response bodies against final artifacts on passing cells — has not been run.

    Caveats. Only the Codex arm is configured identically across the two runs; the four-arm configuration itself has one run. The 900 s budget is a material parameter that binds hardest on Claude Code. Reasonix contributes three unscored cells, so its comparisons rest on 86 shared tasks.

  4. Astro-Han commented on Aug 8, 2026

    @Astro-Han
    ContributorAuthor

    Closing as completed. The synchronized four-arm Terminal-Bench 2.1 run finished, #2177 landed the required harness work, and #2208 records the report, artifacts, and results. Further ablations or reruns should be tracked as their own experiments with frozen variables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions