Skip to content

test(review): run the fanout reviewer-diversity eval and post its probe result #12151

Closed

Description

@kyle-sexton

Parent #7584's done-when reads "The fanout eval slice carries a Probe result: comment before the act-on cap merges"; this is that slice. It runs the cases #12139, #12143 and #12144 add, after #12138 gives fanout's report its ### Spec and ### Standards headings. The owner approved the Q160 eval as recommended on 2026-10-15 (poteto-review decision row 99), and its decision rule was fixed before the run, as stated below. The parent's decisions read "act-on cap per heading (setting from the Q160 eval)" (D101), and the eval's rule yields no cap number. The Issue Triage session decided, under the owner's standing direction and within D101 (not an owner decision), that this run also reports, per heading, the largest position of the planted defect, and that a follow-up child sets the default cap from that number: the smallest cap that keeps every planted defect inside "act on", the bar Lauren Tan's PR #100 used ("the smallest version that kept every planted dimension at full panel recall"). The lane cannot run claude plugin eval, so a host with the claude CLI runs this. The eval passes are model usage under the Claude subscriptions or the accounts' promotional API credits, which the owner's standing direction calls "Not cost, so spend it freely" (docs/contracts/loop-lane/README.md:351); each pass still sets a --max-cost-usd ceiling.

Done when

  • A one-fixture pilot runs for each arm at --runs 1 before the full run.
    • When the Codex arms cannot run inside the eval sandbox, they run outside the harness on the same fixture branches, are graded with the same grader prompts, and are labeled lower rigor.
  • claude plugin eval runs every fanout-diversity-* case at three runs per arm, plus lens once with no plugin as the floor. Each pass sets a --max-cost-usd ceiling.
  • Before any score counts, each type: llm grader passes the /evals:plugin-eval judge calibration (90% agreement on its labeled samples) with an Opus judge. Only VALID runs count.
  • A comment on this issue whose first line starts with Probe result: gives:
    • the CLI version and the ceiling used;
    • per arm: VALID run count, recall (the share of defect-fixture runs naming the planted defect at medium or higher) and high-or-critical false positives per run;
    • the defects only one arm caught;
    • per arm and per heading (### Spec, ### Standards), the largest position, counted from 1 within that heading, at which the planted defect appears across VALID runs, or none when no fixture plants a defect of that heading's axis;
    • a verdict for each rule:
      • (2) an arm replaces lens as the default only if its recall beats L by at least 10 points, with a noise-report interval that excludes 0, and its high-or-critical false positives per run exceed L's by no more than 0.5;
      • (3) add /codex:review to the default sweep if L+X beats L by the same rule;
      • (4) if M does not beat L, record that same-vendor model diversity adds nothing measurable here, and that the panel's placement moves from fanout's model mode to the Codex reviewer;
      • (5) when recall is within noise, the cheaper arm wins.
  • The probe result is also committed: a PR adds the Probe result: verdict line to each fanout-diversity-* case's description, adds a .changes/review/*.md fragment with bump: none, and closes this issue.
  • When a verdict changes the fanout_diversity default, adds Codex to the default sweep, or moves the panel's placement, an issue for that change is filed as a sub-issue of review: spec-first fanout and ratchet move to toolchain #7584, with Parent: #7584 in its body, and is linked in the comment.
  • An issue that adds the per-heading act-on cap setting, with its default taken from the per-heading positions above (for the arm the verdict keeps as default), is filed as a sub-issue of review: spec-first fanout and ratchet move to toolchain #7584 with Parent: #7584 in its body, and is linked in the comment. A heading reported none is named in it as having no evidence.

Out of scope

  • Setting an act-on cap value in this slice.
  • Changing fanout's behavior in this slice.

Parent: #7584

Activity

  1. added theissue type on Nov 1, 2026
  2. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    host-runNeeds an unattended run on a host; the host runner takes it, not a person or the issue lane.
    on Nov 1, 2026
  3. kyle-sexton commented on Nov 2, 2026

    @kyle-sexton
    MemberAuthor

    Carried from #12139 by the Issue Triage session: #12169 (c3bf4c1) left one item of #12139's arm criterion open, and it belongs with this host run because a claude plugin eval run has no Codex login.

  4. added
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    on Nov 2, 2026
  5. github-actions commented on Nov 2, 2026

    @github-actions
    Contributor
    No description provided.
  6. melodic-automation-lanes commented on Nov 2, 2026

    @melodic-automation-lanes
    Contributor

    The work-resolve-issue run that agent-ready started waited in its slot past a change to its lane workflow files on main, so it stopped before any model turn. The run's report-outcome removed and added agent-ready back to start a fresh run on main's workflow files. If this run ends the same way, it re-fires the issue again, waiting longer each time.

  7. 7 remaining items

  8. github-actions commented on Nov 2, 2026

    @github-actions
    Contributor
    No description provided.
  9. github-actions commented on Nov 2, 2026

    @github-actions
    Contributor
    No description provided.
  10. removed
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    on Nov 2, 2026
  11. melodic-automation-lanes commented on Nov 2, 2026

    @melodic-automation-lanes
    Contributor

    The work-resolve-issue lane stopped on this issue (host-only): the run reports the work needs a host run the lane cannot make.
    It added host-run and removed agent-ready: an agent run on a host builds it, and it waits on no decision from a person.

    In the run's words:

    host-only: every done-when item of #12151 depends on running claude plugin eval over the fanout-diversity-* cases (pilot at --runs 1, three runs per arm plus the lens floor, Opus judge calibration of each llm grader) and, per the carried comment from #12139, on a Codex login for the X arms (mx, lx). The issue itself states the lane cannot run claude plugin eval and that a host with the claude CLI runs it, and it carries the host-run label. The Probe result comment, the committed verdict lines, the changelog fragment and the follow-up sub-issues of #7584 all take their content from that run's results, so this lane cannot produce any of them without inventing numbers.

    What the run says it did not do:

    • Pilot and full claude plugin eval runs, grader judge calibration, the Probe result comment, the committed verdict lines and .changes/review fragment, and the follow-up sub-issues of #7584: all need the host eval run
    • Making the X arms (mx, lx) runnable with a Codex login, the item carried from #12139: needs a host with a Codex login, or a decision recorded in plugins/review/evals/fanout-diversity.md after the host run picks its harness

    Run: https://github.com/melodic-software/claude-code-plugins/actions/runs/41408649137

    To hand it back to the lane, remove host-run and add agent-ready again.

  12. github-actions commented on Nov 2, 2026

    @github-actions
    Contributor

    Intake triage did not triage this issue after 2 dispatches, so the sweep no longer dispatches it and labeled it needs-triage for a maintainer. Triage it by hand, and read the runs for why intake did not:

  13. github-actions commented on Nov 2, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: scoped
    Basis: automated intake triage; the lanes App applied this class.

    Size: Medium
    Complexity: Medium
    Uncertainty: Knowable
    Flags: none
    Blocked by: none

    Understood: this slice runs the fanout-diversity-* evals on a host with the claude CLI. It then posts a Probe result: comment with recall, false positives, per-heading defect positions and rule verdicts. It also commits the verdict lines in a PR and files the follow-up issues. The host run is a done-when item that an unattended lane run can't do, so admission routes it to host-run. Nothing is missing from the issue text. The eval passes draw on prepaid or subscription usage, so I've raised no cost flag. I found no likely duplicates.

    Automated triage, applied by the lanes App.

  14. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Nov 2, 2026
  15. self-assigned this
    on Nov 2, 2026
  16. kyle-sexton commented on Nov 2, 2026

    @kyle-sexton
    MemberAuthor
    No description provided.
  17. kyle-sexton commented on Nov 2, 2026

    @kyle-sexton
    MemberAuthor

    Probe result: L and M tie at 24/24 recall; lens stays the default; the Codex arms are not measurable under codex 1.0.6.

    Run. Claude Code 2.1.316, claude plugin eval over the 24 L and M cases, three runs per case, Opus subject and Opus judge, --scaffold --allow-tools Bash Write Workflow, TMPDIR under /run/user/<uid> (#12422: under /tmp or /var/tmp the run's Bash cannot write its workspace). Ceilings: L pass 150 USD (spent 73.63, including the no-plugin floor), M pass 100 USD (spent 45.78). One-fixture pilot at --runs 1 for each arm first.

    Judge calibration. calibrate-judge.py build skips file-focus graders, so each labeled sample was written to .work/eval/findings.md by a scaffold and the unchanged grader judged it: 120 labels (the original 48 plus 72 borderline samples now committed) x 3 runs, Opus judge, 360/360 agreement, every one of the 24 graders 100%.

    L (lens) M (model: opus, sonnet) Floor (no plugin)
    VALID runs 36/36 36/36 36
    Recall (planted defect named at IMPORTANT or CRITICAL) 24/24 24/24 0/24 (it wrote a report in 5 of 36 runs)
    High-or-critical false positives per run 0.00 (0 runs) 0.03 (1 run, 1 finding) n/a
    Decoy runs with no IMPORTANT+ finding 3/12 5/12
    Cost per run 1.90 USD 1.27 USD
    • Paired over the 12 cases, M minus L on the case score: +0.01, 95% interval -0.03 to +0.05 (noise report, arm check regraded as below).
    • Defects only one arm caught: none. Both arms caught all 8 in every run.
    • Largest position of the planted defect within its heading, across VALID runs: L ### Spec 1, ### Standards 1; M ### Spec 1, ### Standards 1. It landed under Spec in 33 of 48 runs and under Standards in 15, always at report rank 1. No fixture lacks a heading, so neither heading reads none.

    Verdicts.

    • (2) Not met: neither arm's recall beats L by 10 points (difference 0), so lens stays the default.
    • (3) Not measurable: every codex 1.0.6 command, /codex:review included, sets disable-model-invocation: true, so the model cannot run fanout's Codex surface (owner decision, 2026-11-02). fix(review): dispatch fanout's Codex surface through a path the model may run #12495 makes it runnable.
    • (4) M does not beat L: same-vendor model diversity adds nothing measurable here. The panel placement move to the Codex reviewer is filed blocked by fix(review): dispatch fanout's Codex surface through a path the model may run #12495, so it cannot make a default of a reviewer that does not run.
    • (5) Recall is equal, so rule (5) would pick M (33% cheaper). Rule (2)'s "only if" governs a change of default, and both arms are at ceiling, so the result is recorded as no difference measured. Decided on the evidence under the owner's standing direction; harder fixtures are filed to separate the arms.

    Grader fixes found in the run (committed in the PR): the arm check required the layer label (docs/conventions/review.yaml), but fanout's spec (SKILL.md:66) fixes only fanout_diversity: <value> (<layer>) and runs often write (repository); 7 of 36 M runs that ran model mode with two tiers failed on that wording, and were regraded VALID offline with the corrected pattern. Without --allow-tools Workflow, every arm silently ran fanout's main-thread fallback.

    Follow-ups under #7584: #12503 (act-on cap, default 1 per heading), #12504 (panel placement to the Codex reviewer, blocked by #12495), #12505 (harder fixtures and the two ground-truth axis labels).

  18. kyle-sexton commented on Nov 2, 2026

    @kyle-sexton
    MemberAuthor

    Addendum to the probe result: what the decoys show below CRITICAL.

    The false-positive figure above counts only CRITICAL findings. Every IMPORTANT or CRITICAL finding on the 4 decoy fixtures (24 reports) was then checked against the fixture's code. One agent labeled them; the labels had no second review.

    L M
    Runs with an IMPORTANT+ finding on a correct change 9/12 7/12
    IMPORTANT+ findings 16 15
    False, or a ground-truth not_defects claim 0 0
    True, but already on main 3 7
    A design or coverage preference with no failing input 12 7
    True and about the changed lines 1 1
    • So fanout is not quiet on correct code at IMPORTANT, but none of the 31 findings is false. 19 of 31 are preferences, and 10 are real bugs the change did not introduce. An IMPORTANT finding alone is not evidence that a change is wrong.
    • The two findings about the changed lines make the same claim: dropping await removes the loadProfile frame from async stack traces (return-promise). No request gets a different response.
    • The closest calls were labeled preference: a missing ORDER BY tie-breaker (sort-column), commit-message reasoning (typed-user) and a hypothetical later try/catch trap (return-promise). Counting all three as about the changed lines raises runs with such a finding from L 1/12 and M 1/12 to L 6/12 and M 5/12.
    • Four L rows say a doc-drift crosswalk (Stale maps to IMPORTANT) set their tier, in two of them over a reviewer's SUGGESTION.

    Correction to the cap evidence: every fixture plants one defect in a small diff, so the defect landing at position 1 is close to guaranteed and does not support a cap of 1. #12503 is now blocked by #12505, which adds multi-defect fixtures.

  19. kyle-sexton commented on Nov 2, 2026

    @kyle-sexton
    MemberAuthor

    Done-when met or decided: one-fixture pilots for each arm, full L and M passes at three runs per case with the no-plugin floor and ceilings, Opus judge calibration (360/360), the Probe result: comment (#12151 (comment), addendum 6589390007), verdict lines and bump: none fragment in #12507, and follow-ups #12503, #12504 and #12505 under #7584. The X arms were recorded as not measurable by owner decision (2026-11-02). #12514 has since made Codex dispatchable, and #12495 carries their rerun; its result updates rule (3).

  20. kyle-sexton commented on Nov 3, 2026

    @kyle-sexton
    MemberAuthor

    Probe result: rule (3) is not met. Codex adds no measurable recall at ceiling, so /codex:review stays out of the default sweep. Lower rigor: the X arms ran outside claude plugin eval.

    Run. Claude Code 2.1.316, codex plugin 1.0.6, after #12514. One claude -p per run (Opus subject, three runs per fixture per arm, 72 runs), on the same fixtures and scaffolds as L and M, with the host's own Codex login: a login copied into a run's home would be readable by the model under test. Ceiling 250 USD for the subject runs, 125.67 spent; Codex's own usage is not in that figure. The unchanged recall.md and false-positive.md graded each report through claude plugin eval with an Opus judge: byte-identical to the L and M arms' (cmp), the same 24 graders calibrated at 360/360.

    A run counts as VALID only when the arm check matched and the trace holds the script's codex: ran. The two checks agreed on all 72.

    L+X M+X L (harness) M (harness)
    VALID runs 35/36 36/36 36/36 36/36
    Recall (planted defect at IMPORTANT or CRITICAL) 23/23 24/24 24/24 24/24
    High-or-critical false positives per run 0.09 (3 runs) 0.06 (2 runs) 0.00 0.03
    Decoy runs with no IMPORTANT+ finding 3/12 6/12 3/12 5/12
    Claude cost per run, USD (Codex usage not included) 2.20 1.29 1.90 1.27
    IMPORTANT+ findings only Codex raised / all IMPORTANT+ 0/152 1/123
    • Paired recall delta over the 8 defect fixtures: L+X minus L 0 points, M+X minus M 0 points (interval 0 to 0: every arm is at ceiling).
    • Paired delta in runs failing the false-positive grader, over 12 fixtures: L+X minus L +8.3 points (95% normal -8.0 to +24.7); M+X minus M +2.8 points (-2.7 to +8.2).
    • Defects only Codex caught: none.
    • None of the 5 CRITICAL rows behind the false-positive figures lists Codex as a surface: 3 are one sort-column duplication finding from code-reviewer and architecture-guardian, and 2 are from model: tiers.
    • The one Codex-only finding (stock-race, one M+X run, from the adversarial review): no regression test covers two concurrent reservations. True, since the fixture has no tests, but a coverage preference with no failing input (the addendum's labels; one agent, no second review).
    • The one invalid run, price-cents L+X index 0, printed codex: skipped (Codex CLI not logged in), and the arm check correctly refused it. It was the first run after the host freeze and the driver restart at 23:37Z; why its login check failed is UNVERIFIED. It was not rerun, so that cell has n=2.

    Verdicts.

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

Metadata

Metadata

Assignees

Labels

host-runNeeds an unattended run on a host; the host runner takes it, not a person or the issue lane.needs-triageNot yet classified. Floor until a type and one priority tier are set.priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

Type

Fields

Work status

agent-ready

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions