Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 37 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1471,9 +1471,11 @@ harness, model, and effort, its Reviewer line ending in `, shadow` for the
shadow, the session and round, the score and rationale, the tier it raised the
risk to and why, its tally, each finding with
its location, and the last round's findings with their dispositions. The
tally, as `- Rounds: 3; findings 4 (high 1, medium 3): fixed 3, refuted 1, open 0`,
counts the reviewer's rounds on the branch and each finding it raised once,
by its latest severity, however many rounds keep it open. A finding counts
tally, as `- Rounds: 3; first round 2 (medium 2); findings 4 (high 1, medium 3): fixed 3, refuted 1, open 0`,
counts the reviewer's rounds on the branch, its first round's findings as that
round graded them, and each finding it raised once,
by its latest severity, however many rounds keep it open. A tally begun before
it kept first rounds leaves that part out. A finding counts
for the reviewer that raised it when a new size pick's reviewer fixes or
refutes it, but one that reviewer keeps open becomes its own, since its round
reports it again. `--new` drops the findings it leaves unsettled from the
Expand Down Expand Up @@ -1590,11 +1592,16 @@ prompt or reply. Since another repository may use the same branch name, the
session must also be this repository's, as the repositories token-max resolved
for it on its own host name, or, once its checkout is deleted, those resolved
there for another session in that exact directory, as a Codex log records
(never a parent's, which a nested clone may not share); otherwise it stays
(never a parent's, which a nested clone may not share). A sub-agent or
spawned session that names no PR's branch, as one in a detached checkout,
takes the PR of the session that spawned it, unless its own repository is
known to be another; otherwise it stays
unattributed. A session is classifying when the PR's `## Review` record names
it as the [risk classifier](#risk-tiers), reviewing when the record names it as
a reviewer or Codex marks it a review, implementing when its first request since
`--since` came before the PR opened, and iterating otherwise, so a session
a reviewer or Codex marks it a review, its parent's role when both are on the
same PR, so a review's sub-agents count as reviewing, implementing when its
first request since `--since` came before the PR opened, and iterating
otherwise, so a session
that opened a PR before `--since` and kept working on it reads as iterating. Each PR shows its `## Models` size, its risk tier and
whether a reviewer raised it, and its implementers, and as `unread:` each Implementer line it cannot read; each reviewer the
`quest review` record names, with its latest round and score and its tally of
Expand Down Expand Up @@ -1622,19 +1629,36 @@ a bot resolving its own thread or a later review leaving it out, and as
unanswered otherwise.

Rollups follow: spend by size, role, harness, model, and effort; accuracy
by size and implementer, which sums the tallies but the shadow's, so it counts
by size and implementer, which sums the tallies but the shadow's, and their
first rounds over the PRs whose every such tally records one, so it counts
every finding the routed reviewers caught before merge, while the shadow's
findings measure an effort step rather than the writer. Since a branch's tallies span every PR from it, only the
PR whose record holds its latest tally, by the most rounds and then the newest,
counts them, and a record written before tallies
counts as unreviewed. An `Implementer:` line's own size, as
`(iterate, XS)`, counts over the PR's; the writer A/B by size and arm, with
the same outcomes and every session's spend, counting a sized PR only when
each of its `Implementer:` lines names the same arm; each risk tier's PRs, how many merged,
how many a reviewer raised, and how many a later PR's `## Caused by` names,
which shows whether the tiers predict what breaks; and, over the merged PRs, each online
`(iterate, XS)`, counts over the PR's. The writer A/B reports by size and arm,
with the same outcomes and every session's spend, counting a sized PR only when
each of its `Implementer:` lines names the same arm. Each implementer also carries its
writing sessions' cost on the merged PRs they were found on, so cost per merged
PR divides by those PRs, not the ones no host reported: a PR's spend on a
model goes to its line of that model, of the same effort where both name one,
and spend on a model no line names, such as a sub-agent on a smaller model,
to the line that took the most. Spend that fits several lines goes to the
first line when an implementing session spent it and to the later ones when an
iterating one did. Local reviewers roll up the same way, by the
PR's size and each reviewer's harness, model, effort, and shadow mark: PRs
reviewed, tallies, first rounds, and reviewing cost per PR, where a session
the record names, or its sub-agent, goes to that reviewer. Spend still left
fitting several, such as a routed and a shadow reviewer at one effort whose
sessions no record names, is split evenly among them and reported as `split`.
Each risk tier's PRs, how many merged,
how many a reviewer raised, and how many a later PR's `## Caused by` names
show whether the tiers predict what breaks. Over the merged
PRs come each online
reviewer's coverage, final heads reviewed, findings per PR reviewed, and
answers. Sessions on no PR here, from any
answers. A hand-back counts only while its draft is open, so a merged PR
never shows one.
Sessions on no PR here, from any
repository or agent token-max reads, total on an `Unattributed` line. `--pr` and
`--quest` narrow the report to one PR or one quest's branch, and `--json`
prints it as one object. Without `token-max` on `PATH`, it says how to install
Expand Down
11 changes: 8 additions & 3 deletions quest/m0/routing-evidence/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,14 @@ Readout, the agent's choices for the implementer to revisit:
chooses to.
- Carry the tallies into [the model check](/quest/m1/model-check.md)'s
baseline.
- Publish the arms' cost and quality as
[the cost-against-quality charts](/quest/m0/routing-evidence/charts.md) quest describes,
and link them with the recommendations.
- Chart the arms' cost against quality as
[the model check](/quest/m1/model-check.md)'s chart procedure describes,
one point per arm, and link the charts with the recommendations. Its
`quest usage --json` rows give each arm's cost per merged PR and
first-round findings, and each shadow pair's cost and findings per PR.
Only tallies begun after
[moq-dev/quest#721](https://github.com/moq-dev/quest/pull/721) merged
record a first round, so count first rounds only over those.

Baseline from the 2026-11-11 audit, at API list price:

Expand Down
76 changes: 0 additions & 76 deletions quest/m0/routing-evidence/charts.md

This file was deleted.

35 changes: 35 additions & 0 deletions quest/m0/routing-evidence/handbacks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# [S] Count hand-backs on merged PRs

## Goal

`quest usage` counts a PR as handed back when any version of its body had a
`## Waiting` (or `## Decisions needed`) section while it was a draft, merged
PRs included, so the writer A/B's and the model check's hand-back measure
sees every PR rather than only drafts still open.

## Plan

Decided 2026-11-14 (user, /quest-run, from
[moq-dev/quest#721](https://github.com/moq-dev/quest/pull/721)'s
follow-ups): add this quest rather than drop the measure.

Today `handedBack` in `src/cli/usage.ts` reads only the current body of an
open draft. `quest ready` and hand edits remove `## Waiting` before merge,
so every merged PR reads 0.

Recommended (agent's choice): read each PR's body history from GitHub
(GraphQL `userContentEdits`, whose entries carry each earlier body) where
`quest usage` already reads the PR, and count a hand-back when an earlier
body had a hand-back section, using `handedBack` from `src/core/claim.ts`.
It works on PRs merged before this lands and needs no change to the skills
or `quest ready`. The alternative, having `quest ready` record hand-backs
in `## Models`, counts only PRs readied after it lands and trusts every
writer to keep the record. Batch the history reads with the existing PR
query so `--since` over a week stays within the GraphQL rate limit.

Count each PR once, however many times it was handed back, and report the
count in the `accuracy` and per-PR rows as today.

## Related

- [Model check](/quest/m1/model-check.md) - charts hand-backs per PR
100 changes: 83 additions & 17 deletions quest/m1/model-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,81 @@ checkpoints and outages to count by hand:
maintainer with its tally, as a decision in the PR, rather than changing
it unasked. Replacing a stale model id with the same vendor's newer one,
below, needs no decision, as this check always did.
- Chart cost against quality for every writer and reviewer cell, as decided
2026-11-11 (user, /quest-plan, moq-dev/quest#642's follow-ups), so a
routing change is read off the frontier rather than tables. The agent
running the check makes the charts itself, from the saved
`quest usage --since <date> --json` (with `--ssh` for each host that runs
agents) and the benchmark table below. The charts are an artifact of the
run, and no chart code goes into `quest`. It draws them as Mermaid
charts in its PR body, which GitHub renders and any harness can write
(user, 2026-11-14, /quest-run on
[moq-dev/quest#721](https://github.com/moq-dev/quest/pull/721); rejected:
images in a secret gist, a claude.ai page made by hand). Mermaid's
quadrant charts scale both axes to 0-1, so each title gives the scales
and each point's label carries its PR count. The body also puts every
plotted number in tables, so a reviewer can check the charts. Each
chart names its date range, the command, and each point's PR count.
Points too thin for the run's variance estimate stay on the chart,
marked thin in their label, never dropped. Cells whose
`Implementer:` effort is `unknown` stay separate points. The charts:
- Writers, one point per `accuracy` row (size, model, effort): cost per
merged PR, `spent.cost / spent.pulls`, against each quality measure
on its own chart. The measures are first-round findings per PR
(`firstRounds.findings` over `firstRounds.pulls`), review rounds per
reviewed PR (`tally.rounds / reviewed`), hand-backs per PR
(`handedBack / pulls`, which counts only drafts still open until
[hand-backs on merged PRs](/quest/m0/routing-evidence/handbacks.md)
lands), and later
`## Caused by` escapes per merged PR (`fixes / merged`).
- Local reviewers, one point per `reviewers` row (PR size, harness,
model, effort, shadow): cost per PR reviewed, `spent.cost /
spent.pulls`, against findings per reviewed PR (`tally.findings` over
`reviewed`) and the share fixed, `tally.fixed` over the findings
settled one way or another (fixed, refuted, or settled).
- Online reviewers, which run on flat plans and so have no cost per
review, on a chart of their own: one point per `online` row, coverage
(`reviewed / merged`) against findings per reviewed PR, labelled with
its acceptance (`accepted / findings`).
- Published benchmarks, one chart per suite in the table below: score
against that suite's cost per task, for the same models and efforts,
with the frontier drawn. Benchmark and PR metrics differ, so compare
where each cell sits on each chart's frontier, not its values; flag a
cell on the frontier in one and not the other.
- Published benchmarks, refreshed each run: rows with a stated effort, each
with its source and the date it was read. Cost is per task in the suite's
own terms; `~` marks a value derived from the source's prose.

| Suite | Model | Effort | Score | $ per task | Read |
|---|---|---|---|---|---|
| [mypriors](https://mypriors.com/adamholter) 10-benchmark index, subscription cost | Haiku 5.5 | high | 30 | 0.0034 | 2026-11-09 |
| mypriors | Haiku 5.5 | xhigh | 34.6 | 0.0053 | 2026-11-09 |
| mypriors | Sonnet 5.5 | medium | 30.7 | 0.012 | 2026-11-09 |
| mypriors | Opus 5.5 | low | 34.7 | 0.015 | 2026-11-09 |
| mypriors | Opus 5.5 | medium | 48 | 0.037 | 2026-11-09 |
| mypriors | Opus 5.5 | high | 51.7 | 0.052 | 2026-11-09 |
| mypriors | Opus 5.5 | xhigh | 57.3 | 0.092 | 2026-11-09 |
| mypriors | gpt-6.1-sol | low | 34.8 | 0.0094 | 2026-11-09 |
| mypriors | gpt-6.1-sol | medium | 46.3 | 0.021 | 2026-11-09 |
| mypriors | gpt-6.1-sol | high | 50.3 | 0.034 | 2026-11-09 |
| mypriors | gpt-6.1-sol | xhigh | 52.5 | 0.045 | 2026-11-09 |
| mypriors | Fable 5.2 | medium | 56 | 3.8 | 2026-11-09 |
| [Anthropic's cost guide](https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence), SWE-bench Pro 478-problem subset, % solved | Sonnet 5.5 | medium | ~80.6 | ~0.057 | 2026-11-13 |
| Anthropic, SWE-bench Pro | Sonnet 5.5 | high | 87.6 | ~0.096 | 2026-11-13 |
| Anthropic, SWE-bench Pro | Opus 5.5 | low | 87.4 | 0.11 | 2026-11-13 |
| Anthropic, SWE-bench Pro | Opus 5.5 | medium | 92.8 | 0.21 | 2026-11-13 |
| Anthropic, SWE-bench Pro | Opus 5.5 | high | 95.3 | 0.29 | 2026-11-13 |
| Anthropic, SWE-bench Pro | Opus 5.5 | xhigh | 96.7 | 0.74 | 2026-11-13 |
| [Artificial Analysis](https://artificialanalysis.ai/models/comparisons/claude-sonnet-5-5-high-vs-claude-opus-5-5-low), Terminal-Bench 4.0, % | Haiku 5.5 | xhigh | 29.3 | 0.25 | 2026-11-11 |
| Artificial Analysis, Terminal-Bench 4.0 | Sonnet 5.5 | medium | 29.8 | 0.78 | 2026-11-11 |
| Artificial Analysis, Terminal-Bench 4.0 | Sonnet 5.5 | high | 43.9 | 1.64 | 2026-11-13 |
| Artificial Analysis, Terminal-Bench 4.0 | Opus 5.5 | low | 31.3 | 0.98 | 2026-11-13 |

Anthropic gives Sonnet high's cost per solved task ($0.11), Sonnet
medium as about 7 points lower at about 59% of high's cost per task, and
calls its figures directional. Its guide also has rows on internal
suites without a cost per task, which stay out. The `max` rows stay out
too, since `quest agent` and `quest review` refuse `max`.

- Read [routing evidence](/quest/m0/routing-evidence/README.md)'s readout
and baseline first: its shadow reviews and writer A/B measure the cells
Expand Down Expand Up @@ -80,25 +155,16 @@ checkpoints and outages to count by hand:
effort (6 of the 20 lines said `unknown`).
- Changed after that run rather than on tallies (maintainer, 2026-11-09):
XS writes on Haiku xhigh instead of high. Tally that cell fresh. The
source was [mypriors.com/adamholter](https://mypriors.com/adamholter)'s
score against subscription cost per task, a 10-benchmark index read
off its chart (score, then $ per task), which this check compares each
cell with again:
- Haiku 5.5: high 30, $0.0034; xhigh 34.6, $0.0053.
- Sonnet 5.5: medium 30.7, $0.012; below the frontier at every effort,
so rejected for XS then, though Anthropic's
source was the mypriors rows of the benchmark table above:
- Sonnet 5.5 sat below the frontier at every effort, so it was rejected
for XS then, though Anthropic's
[model guide](https://claude.dev/blog/which-claude-model-should-you-build-with/)
favors it for scoped coding.
- Opus 5.5: low 34.7, $0.015; medium 48, $0.037; high 51.7, $0.052;
xhigh 57.3, $0.092; max 58.9, $0.15.
- gpt-6.1-sol: low 34.8, $0.0094; medium 46.3, $0.021; high 50.3,
$0.034; xhigh 52.5, $0.045.
- Fable 5.2: medium 56, $3.8; max 64.6, $26.5. Rejected for XL, which
stays on Opus xhigh, on the frontier; zero-data-retention
organizations may also be refused Fable.
- S looks lopsided: Opus low scores well below its Sol medium fallback
(34.7 against 46.3) for $0.006 less a task. Check its tallies before
moving it.
- Fable 5.2 was rejected for XL, which stays on Opus xhigh, on the
frontier; zero-data-retention organizations may also be refused
Fable.
- S looked lopsided: Opus low scored well below its Sol medium fallback
(34.7 against 46.3) for $0.006 less a task.
- Changed again (maintainer, 2026-11-11): XS writes on Sonnet high
instead of Haiku xhigh, since two Haiku XS agents in a row on
[moq-dev/quest#643](https://github.com/moq-dev/quest/pull/643) died
Expand Down
Loading
Loading