Plan: Accuracy & Insight Push (June 2026)
Six tasks to take the suite from "instrumented" to "publishable evidence" for
oak's core pitch. Ordering is driven by one shared dependency: remote
plumbing. Tasks 1, 3, and 5 all need the harness to stand up disposable
remotes (oak server-side, git local-bare or GitHub). Build that once in
oakbench, then the lanes are thin.
Repos required (blocking β request before Phase 1)
| Repo | Where | Purpose | Lifecycle |
|---|---|---|---|
oak/bench-fleet-tmp | oak org | Branch storms from the agent-fleet lane (N workers Γ M commits Γ runs). Kept separate from oak/oak-benchmarks-tmp so fleet garbage never pollutes the mount lane's timing repo. | Disposable; deletable/recreatable any time |
oak/bench-sync-tmp | oak org | Push-divergence / pull-with-upstream-changes scenarios (task 5) and the full task-loop pushes (task 3). | Disposable |
oak/bench-large-mirror | oak org | Large-repo fixture for mount-vs-clone (task 2). Seeded once from a generated fixture; read-mostly afterward. | Long-lived, read-only after seeding |
bench-large-mirror | GitHub | Byte-identical mirror of the above, the git side of mount-vs-clone. | Long-lived, read-only after seeding |
bench-task-loop-tmp | GitHub | Optional but recommended: git's agent-default push target for the task-loop lane, so git pays real git push like oak pays real oak push. Local-bare remains the core-equivalent track. | Disposable |
Large-mirror fixture spec (generated by a new scripts/make_large_fixture.py,
deterministic seed so both mirrors are identical): ~30k files across a
realistic tree (src/, docs/, vendored deps), ~300 MB working tree including a
handful of 20β100 MB binaries, ~500 commits of synthetic history. Big enough
that full git clone visibly pays for bytes an agent never reads; small
enough to re-seed in minutes.
Phase 0 β shared remote plumbing (oakbench/remotes.py)
Lift what already exists in bench.py (OAK_BENCH_REMOTE resolution at
bench.py:400, disposable branch namespacing at bench.py:431-449,
local-bare git remote setup at bench.py:566-576) into a shared module:
resolve_oak_remote(purpose)β owner/repo from env (OAK_BENCH_FLEET_REPO,OAK_BENCH_SYNC_REPO, falling back toOAK_BENCH_REMOTE), or a structured skip reason. Skips stay returncode-77 rows naming the env var (skips are work items).make_git_bare_remote(tmpdir)β untimed local bare repo (core-equivalent track) andresolve_git_github_remote()fromGIT_BENCH_REMOTEenv (agent-default track).disposable_branch(bench_id, scenario, subject, run)β the existing collision-safe namescheme, shared by all lanes.- Transport honesty: every row touching a remote records
transport: local_file | networkand the server identity. Network rows are never aggregated with local-file rows (AGENTS.md already mandates this forremote.net.*; the new lanes inherit the rule).
Tests: tests/test_remotes.py (resolution, skip reasons, branch-name
uniqueness). Run row_parity.py against a pre-change bench.py run to prove
the lift is measurement-identical (ADR-0005 discipline).
Task 1 β agent-fleet lane: oak workspace-per-task
Today: parallel_contention.py:425-439 hard-skips non-git subjects in
workspace_per_task mode. Git mode already emits setup_ms, merge_ms,
marginal_workspace_disk_kb, commit throughput, lost-update detection, and
integrity (parallel_contention.py:535-554).
Build:
- Untimed setup: push the contention fixture to
oak/bench-fleet-tmpon a disposable branch (one per run). - Per worker i: timed
oak mount/space creation of workspace i β record per-workspacesetup_msand a new run-leveltime_to_nth_workspace_mscurve (cumulative wall time until N workspaces are usable β this is the fleet-spinup headline number). Git comparator gets the same curve computed from its existing worktree setup timings, so the metric lands on both subjects simultaneously (ADR-0005: new metric, additive, no renames). - Marginal disk: reuse the mount lane's
disk.usageprobe (mount_probe.py:439-511β visible vs allocated bytes, entry count) so lazy hydration's near-zero marginal disk is measured the same way in both lanes. Git worktrees keepworkspace_disk_kbas-is. - Commit storm: same disjoint-file edit/commit loop; oak workers commit and push their workspace branch.
- Merge throughput: merge N branches back (git: existing merge step; oak:
its merge/integrate flow against the remote), emit
merge_ms,merges_clean,merge_conflictsfor both. - Integrity pass: payload survival in the merged result + oak's closest
fsck analog,
measurement_sourcenamed accordingly.
Honesty constraint: git worktrees are local; oak workspaces hit the
network. Rows carry transport; the summary presents the comparison with the
asymmetry stated, and optionally adds a clone_per_task git mode (clone from
local bare per worker) as the transport-comparable third column. Do not bury
this β it is the first question a skeptical reader asks.
Flags/env: OAK_BENCH_FLEET_REPO=oak/bench-fleet-tmp, existing
--workers 2,8,32 --modes workspace_per_task.
Deliverable claim shape: "N agents Γ isolated workspaces: time-to-32nd-workspace X s vs Y s; marginal disk per workspace X MB vs Y MB; merge throughput X/s vs Y/s (oak network-backed, git local β see methodology)."
Task 2 β mount-vs-clone with a git comparator
Today: mount lane is oak-only (scenarios/mount.yaml:45-174, no git
scenarios); docs/benchmark-coverage.md lists no mount-vs-clone plan.
Build:
- Seed
oak/bench-large-mirrorand GitHubbench-large-mirrorfrom the same generated fixture (Phase 0 fixture script). Verify byte-identity with a manifest hash committed to both. - New lane scenarios β new names, not edits to existing mount ops
(ADR-0005):
acquire.coldwith subjects:oak mount oak/bench-large-mirrorβ first targeted file readgit clone <github-url>(stock) β same file readgit clone --filter=blob:none(partial clone, tuned-git credibility)git clone --depth 1(shallow)- optionally
git clone+sparse-checkout set <task-path>
- Metrics per subject:
time_to_first_read_ms(command start β target file bytes in hand),bytes_transferred(oak: existingbytes_hydratedparsing atmount_probe.py:327-347; git: pack bytes from clone stderrReceiving objects/.gitsize delta),disk_total_bytes,time_to_task_ready_ms(tree listable + task path readable). - Follow-up scenario
acquire.task_scoped: agent needs 3 files in one subdirectory β oak hydrates ~those bytes; git pays the whole clone (or the partial-clone fetch chatter). This is the marketing picture. - Network honesty: GitHub's CDN vs oak.space are different networks. Mitigate: interleave reps, record server + timestamps, report medians of β₯5 reps, and state the caveat in the summary. The claim is about the acquisition model (lazy vs eager), which dominates network variance at this repo size β but say so rather than assume it.
Deliverable claim shape: "Start working on a 300 MB repo: oak mount X s / Y MB hydrated vs git clone X s / 300 MB (and partial clone X s) β time-to-first-read and bytes-to-first-read, 5 reps, medians."
Task 3 β full oak task-loop end-to-end
Today: workflow_ab.py workflows are single-checkout, no remote, no
mount; the signature motion (mount β edit β commit β push β desc β end β
remount for follow-up) is only exercised piecemeal by the mount lane's
task_lifecycle_loop.
Build: new workflow-ab-style lane (likely its own script,
scripts/task_loop.py, sharing oakbench policy) with one scenario per
subject family, agent-default track:
- oak native:
oak mount(fromoak/bench-sync-tmp) β edit βoak commitβoak pushβoak descβoak endβ remount for a follow-up task β second edit/commit/push. - git native:
git clone(GitHubbench-task-loop-tmp) orgit worktree addfrom an existing checkout β branch β edit β commit β push β PR-less desc analog (commit message /git pushoutput) βgit worktree removeβ new worktree for follow-up. - Core-equivalent variant runs git against a local bare remote so the mechanics claim survives without GitHub network in the loop.
Metrics: per-phase operation rows plus a task_loop.total row: wall
time, tool-call count (envelope-priced β this lane is where oak's
fewer-calls-per-motion compounds), estimated cost-weighted tokens, and
followup_warm_delta_ms (second task on warm caches vs first β the remount
story). Oracle: payload present on the remote branch, workspace cleanly
ended, follow-up edit visible.
Why a separate lane: the command sequences are not semantically
equivalent step-by-step (desc/end have no git twin), so this is explicitly
agent-default-track, whole-task-cost evidence β exactly the framing
docs/command-semantics.md exists to police.
Task 4 β real-agent runs
Today: adapters exist (agent_workflow.py:570-642), token extraction
handles all provider field variants (agent_workflow.py:737-786), but only
mock has ever run; stream formats for current CLI versions are unverified.
Build (no new repos needed):
- Adapter shakeout: one manual run per installed CLI
(
--agents available), single rep,bugfix_test_loop, both subjects. Verify: stream parses,usageevents found (provider-reported tokens non-null), turn_metrics populated, oracle passes. Fix adapter drift against current CLI flags before burning tokens on reps. - Token-extraction goldens: capture one real transcript per CLI into
tests/golden fixtures (scrubbed) so adapter drift is caught bytest_stream_adapters.pyinstead of mid-campaign. - The campaign:
--agents claude[,codex,cursor_agent] --subjects git,oak_installed --workflows bugfix_test_loop --runs 5 --agent-environment minimal --randomize-agent-order --randomize-subject-order --instruction-level zero-shotthen the same atcheat-sheet. Never aggregate across levels (existing contract). Budget estimate before launch: runs Γ agents Γ subjects Γ levels β 40 tasks; cap with--timeout-seconds 900and a per-campaign dollar estimate printed up front. - The story metrics: zero-shot vs cheat-sheet deltas in success rate,
help_calls_total,unknown_command_failures_total,turns_to_recovery/tokens_to_recoveryβ the "git is in pretraining, oak isn't, and AGENTS.md closes the gap" measurement. - Stretch (post-campaign): run task 5's divergence workflow and task 3's loop under real agents β recovery-cost numbers from real transcripts are the credibility ceiling for the whole drop.
Transcripts/JSONL stay out of the repo (data-hygiene rules); keep run artifacts under an external/ignored dir with the run manifest.
Task 5 β sync & divergence recovery
Today: vcs_error_recovery covers only empty-commit and
unknown-subcommand (workflow_ab.py:413-433). No remote plumbing exists in
workflow_ab. ADR-0005 forbids changing vcs_error_recovery's meaning β these
are new workflows, not extensions.
Build: new workflow vcs_sync_recovery (uses Phase 0 remotes; git β
local bare for core-equivalent + optional GitHub for agent-default; oak β
oak/bench-sync-tmp):
sync.push_divergence: checkout A and B from the same remote; A edits + pushes; B edits + pushes β rejected. Then the recovery arc: whatever the error output tells you to do (git: pull/rebase or--force-with-leasedecision; oak: its divergence flow β the exact trap hit three times in real use on 2026-06-11). Steps carryexpected_returncodesadmitting the failure; recovery steps follow.sync.pull_upstream_changes: clean pull with upstream commits, and dirty pull (local uncommitted edits) variant.sync.non_ff_after_amend: amend/rewrite local tip after pushing, push again β the second-most-common agent trap.
Metrics (this is the "error output is a prompt" lane): per-failure
error_output_tokens (the rejected push's stderr, cost-weighted as model
input), recovery_steps_count, recovery_tokens_total, and an
error_actionability check: does the error text literally contain the
command that fixes it? (boolean per subject, measurement_source: stderr_contains_recovery_command). Real-agent turns_to_recovery already
exists for task 4 to consume on these same workflows.
Task 6 β pre-publish calibration & tuned-git (gate, runs last)
- Calibration: capture real per-style outputs from a standard run
(status, diff, log, push-rejection stderr β per subject), run
token_calibration.pywithtiktokenavailable (optional import, allowed under ADR-0001) per style group, plus--envelopeto validate the envelope constants. Output: calibration factors table committed todocs/and cited next to every published token delta; if any factor moves a published cross-subject delta's sign or order, the table uses calibrated numbers, not char/4. - Tuned-git everywhere public: every public table includes
git_untracked_cacheANDgit_fsmonitorrows (verifyfsmonitor--daemonhealth on the darwin runner; it is the load-bearing comparator for wide-tree claims). Wire--git-modes untracked_cache,fsmonitorinto the canonical publish-run invocation. - Publish checklist: small
docs/publish-checklist.md(orscripts/publish_gate.pythat greps result sets): calibration run β, tuned modes present β, no aggregation across instruction levels or transports β, nulls rendered as unmeasured β, every skip row accounted for β, tail-percentile sample-count honesty β.
Sequencing
Phase 0 oakbench/remotes.py + fixture generator + repo creation β blocks 1,2,3,5
Phase 1 Task 1 (fleet lane) Task 5 (sync recovery) [parallel]
Phase 2 Task 2 (mount-vs-clone) Task 3 (task loop) [parallel]
Phase 3 Task 4 (real agents: shakeout β goldens β campaign,
then rerun tasks 3/5 workflows under real agents)
Phase 4 Task 6 (calibration + tuned-git + publish gate)
Each phase lands with instrument tests (python3 -m unittest discover -s tests) and, where existing lanes are touched, a row_parity.py proof.