|
| 1 | +# Persona-optimization baseline: two Luna agents at xhigh on Databricks. |
| 2 | +# One drives and one navigates; both persona bytes are independently pinned. |
| 3 | +# |
| 4 | +# This is the controlled comparison the mixed-model team manifest cannot make. |
| 5 | +# Against tb-solo-luna it holds the model, the serving path, the price sheet, the |
| 6 | +# generation settings and the trial budget fixed, and varies exactly one thing: |
| 7 | +# how many agents share the container. Any delta in score, cost, tokens or |
| 8 | +# wall-clock is attributable to the pairing itself. |
| 9 | +# |
| 10 | +# The driver is the orchestrator because the roster allows exactly one, and |
| 11 | +# because the driver is the agent the harness must wake with the task and the |
| 12 | +# only one permitted to publish `DONE:`. The navigator is read-only by persona, |
| 13 | +# not by permission — both agents get the same tools and the same filesystem, |
| 14 | +# so the write boundary is instruction-enforced and worth checking in the |
| 15 | +# transcripts rather than assuming. |
| 16 | +# |
| 17 | +# Expect this to cost more than solo per task even where it scores the same: |
| 18 | +# two agents, and every handoff re-sends context. That is the measurement, not |
| 19 | +# a defect. |
| 20 | +# |
| 21 | +# Endpoint names are exact Databricks serving-endpoint names; provider/host/key |
| 22 | +# resolve via testbed/endpoints/databricks-live.json. |
| 23 | +schema_version: "1" |
| 24 | +condition: tb-peer-2luna-xhigh |
| 25 | +roster: |
| 26 | + - id: driver |
| 27 | + kind: orchestrator |
| 28 | + role: driver |
| 29 | + count: 1 |
| 30 | + endpoint: databricks-gpt-5-6-luna |
| 31 | + model_revision: gpt-5.6-luna |
| 32 | + prompt: |
| 33 | + path: personas/bench/peer-driver.md |
| 34 | + sha256: 1cf4d1cbf4093dd0d9b1a6a7ccd9a875c39621d0bab3ddec7e0bb23177761149 |
| 35 | + generation: |
| 36 | + thinking_effort: xhigh |
| 37 | + |
| 38 | + - id: navigator |
| 39 | + kind: worker |
| 40 | + # Read verbatim by both personas out of the "Your team" table — peer-driver |
| 41 | + # addresses `navigator` and peer-navigator addresses `driver`. Renaming |
| 42 | + # either role here silently breaks the pairing: the @mention resolves to |
| 43 | + # nobody, the send still reports success, and the trial stalls to timeout. |
| 44 | + role: navigator |
| 45 | + count: 1 |
| 46 | + endpoint: databricks-gpt-5-6-luna |
| 47 | + model_revision: gpt-5.6-luna |
| 48 | + prompt: |
| 49 | + path: personas/bench/peer-navigator.md |
| 50 | + sha256: dcf2ae226b5967067687060871438397125e54b8c412f69076eb2a8edd56d2c5 |
| 51 | + generation: |
| 52 | + thinking_effort: xhigh |
| 53 | + |
| 54 | +prices: |
| 55 | + # Repriced 2026-07-30: luna 1.0/0.1/6.0 -> 0.20/0.02/1.20 (-80%). |
| 56 | + # Sol, Opus 5, Sonnet and Haiku did not move. This changes the |
| 57 | + # condition hash, so a cell that ran before this date carries the old |
| 58 | + # hash and the old rates in its receipts -- that mismatch is expected, |
| 59 | + # not corruption. Restate a completed cell's cost with |
| 60 | + # benchmark-runs/tools/reprice.py, which re-prices the measured tokens |
| 61 | + # at a new sheet. Never edit a receipt: the tokens are the |
| 62 | + # measurement, the price sheet is only an overlay on them. |
| 63 | + # Operator-supplied list prices, doc 04 §7, identical to tb-solo-luna's luna |
| 64 | + # figures — holding them equal is what makes the solo-versus-pair cost *ratio* |
| 65 | + # sound. See tb-solo-luna.yaml for why cache_read_rate is 0.0 (DB10). |
| 66 | + databricks-gpt-5-6-luna: |
| 67 | + input_per_million_usd: 0.2 |
| 68 | + cached_input_per_million_usd: 0.02 |
| 69 | + output_per_million_usd: 1.2 |
| 70 | + # Fallback only; superseded by the provider's measured cache split, with |
| 71 | + # `accounting_cache_read_tokens_are_measured` recording which was used. 0.0 |
| 72 | + # keeps an unmeasured run conservative. |
| 73 | + # |
| 74 | + # Caching is load-bearing for this condition in a way it is not for a solo |
| 75 | + # one: the pair's cost is driven by re-sent context, which is exactly what a |
| 76 | + # prefix cache serves. |
| 77 | + cache_read_rate: 0.0 |
| 78 | +trial_budget: |
| 79 | + # Matches tb-solo-luna exactly. A pair genuinely needs longer than a solo agent |
| 80 | + # — every handoff is a round trip — but giving it a larger budget would confound |
| 81 | + # the comparison, and this value does not bind anyway: Harbor enforces each |
| 82 | + # task's own `[agent] timeout_sec`, which tops out at 12000s across |
| 83 | + # Terminal-Bench 2.1, scaled by the study's 3x timeout multiplier. Both |
| 84 | + # conditions therefore run against the task's own clock, which is the only |
| 85 | + # budget the comparison can honestly share. |
| 86 | + timeout_seconds: 36000 |
| 87 | + |
| 88 | +environment: |
| 89 | + # Identical in every condition, including the solo baselines. Harbor enforces |
| 90 | + # a task's declared resources as hard Docker limits, and the Buzz stack runs |
| 91 | + # *inside* that container, so a 3-agent roster would otherwise fit three |
| 92 | + # buzz-acp/buzz-agent/buzz-dev-mcp process groups plus the task's own work |
| 93 | + # into the 1 vCPU and 2 GB most Terminal-Bench tasks ask for. A team that |
| 94 | + # thrashes there has been penalised for memory pressure rather than for |
| 95 | + # coordinating badly — a confound in precisely what this study measures. |
| 96 | + # |
| 97 | + # Raising it only for the team tiers would trade that confound for a worse |
| 98 | + # one, so the solos carry it too and every cell is measured on identical |
| 99 | + # hardware. |
| 100 | + # |
| 101 | + # 4 and 8192 are the *maxima* the dataset declares (cpus: 83x1, 3x2, 3x4; |
| 102 | + # memory_mb: 68x2048, 13x4096, 8x8192), and that is not a coincidence. Harbor |
| 103 | + # replaces rather than raises — environments/base.py assigns |
| 104 | + # `task_env_config.cpus = override_cpus` outright — so any smaller value would |
| 105 | + # quietly shrink the 8 tasks that ask for 8 GB and the 3 that ask for 4 CPUs. |
| 106 | + # Every task therefore gets at least what it requested, and most get more. |
| 107 | + # |
| 108 | + # storage_mb is deliberately absent: all 89 tasks already declare 10240, so an |
| 109 | + # override would restate the status quo and add a knob with nothing to say. |
| 110 | + override_cpus: 4 |
| 111 | + override_memory_mb: 8192 |
0 commit comments