Repository navigation
docs+experiment: RQGM verifier-bias analysis + diagnostic probe - #12
Merged
Merged
Conversation
Analysis of "The Red Queen Gödel Machine" (arXiv:2606.26294) for Alethic, produced by a 26-agent adversarial workflow and reduced to what is faithful to the paper's *demonstrated* results (3 of 4 substantive proposals failed their faithfulness skeptic — they rest on classic ensemble logic, not RQGM). Spine: Alethic's Verifier is the stationary criterion RQGM critiques, and Generator≈Verifier (both Opus) share blind spots that decoupling hides only at the trace level. There is no labeled (problem, solution, true_verdict) set anywhere, so "a verifier accepting a wrong proof" is currently unmeasurable. - docs/plans/2026-06-27-rqgm-verifier-bias.md: ranked adoptables (adopt / defer / reject), the grader-vs-reviewer (verify vs check) asymmetry, and the v4.0-gate link. - scripts/self_preference_probe.py: the #1 move — a measurement-only probe. Generates proof attempts of the false-claim anchors from opus vs an OpenRouter author, runs the real Opus verifier (K=1, optional K=5 consensus, optional reference-less check arm), reports false-positive rate + Fisher exact + Wilson CI. No orchestrator change. A null result (FPR=0) is a valid, decision-relevant outcome. Validated: probe imports/argparse clean; anchors load; lazy imports (OpenRouter/VerifierAgent/scipy) resolve; stats helpers correct. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: A. Friedrich <alex@f2media.de>
Ran the diagnostic's faithful core via Claude Code Task sub-agents (no API key, no per-token cost). Findings: - Author arm: Opus AND Haiku refuse both false-claim anchors and disprove them (even Haiku catches the Drude/Lorenz subtlety) -> weak-author arm is genuinely OpenRouter/package-only. - Verifier arm: a planted trap (correct algebra, Sommerfeld inputs mislabeled as classical Drude) -> 5/5 independent Opus verifiers INCORRECT, conf 0.93-0.97; K=1 == K=5. FPR = 0. Caught by existing VERIFIER_SYSTEM #16/#17 features. - Reassuring NULL for these anchors; caveats: N=1 trap, and skill route can't run the weak/cross-provider author arm (still package-only). Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: A. Friedrich <alex@f2media.de>
10-item audit via Task sub-agents (8 planted flaws across blatant/moderate/ subtle tiers + 2 correct controls), each verified by 5 Opus + 1 Sonnet + 1 Haiku decoupled verifiers (70 agents). Results: - Flaw catch-rate 8/8 at both K=1 and K=5; control false-reject 0/2. - Zero verifier disagreement -> K=5 never beat K=1 (consensus wasted on clear-cut items). - Sonnet AND Haiku scored 10/10 -> a cheap judge matches Opus (token lever). Honest caveat: 100%/0% with cheap models matching expensive ones means the battery (classic, in-distribution flaws) lacks discriminating power -- it shows the floor is above this difficulty, not that there's no ceiling. A real stress test needs NOVEL flaws and errors buried in long derivations. Net: two null-ish experiments weaken the verifier-bias/roster case and strengthen the cheap-judge token lever. Revised the recommended sequence accordingly (cheap-judge probe now #1; bias diagnostic/roster de-prioritised). Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: A. Friedrich <alex@f2media.de>
…r claim Self-correction (the prior commit overclaimed). An all-100% / zero-variance battery has NO discriminating power, so it supports NEITHER "weakens the verifier-bias case" NOR "cheap judge matches Opus": - Bias is UNTESTED — the instrument couldn't detect bias if present (absence of evidence != evidence of absence). - Haiku 10/10 beside Opus 10/10 = clears the same easy bar, not matches Opus at real difficulty. Load-bearing point: planted flaws can only sample the model's *articulable* errors (you can't plant a flaw you can't see); self-generation refused for the same reason. RQGM is about *correlated blind spots* — errors the model cannot see — unreachable by both designs. The only valid instrument is harvested real errors with ground truth (the Deferred labeled set), now promoted to rec #1. Kept (not inflated): the verifier accepted both correct controls incl. the surprising C2 and caught premise-type errors with correct reasoning -> mild evidence it is not trigger-happy. Not a quality verdict. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: A. Friedrich <alex@f2media.de>
…chor Implements rec #2 of the RQGM analysis — the only proposal whose faithfulness skeptic passed. The pooled solve_rate (solved / all problems) averaged two populations that answer different questions, hiding both. split_metrics() partitions by expected_solvable: - solve_rate -> solved / solvable problems (capability). REDEFINED; not comparable to a pre-split number. - false_claim_accept_rate -> the primary number. Every "proof" of a false claim is wrong by construction, so an accept is a false positive — the only metric in the repo that responds to verifier *bias* rather than variance. - false_claim_verdicts -> verdict histogram over the anchors. Errors are handled asymmetrically, deliberately. An errored solvable problem is a failure to solve and stays in the solve_rate denominator; an errored anchor produced no verdict and leaves the anchor denominator. The prior `not solved` test counted crashed anchors as correct rejections, biasing toward the reassuring answer: on a fixture with one error in each population it reports 50% rejection where the one anchor that returned a verdict was in fact accepted. reject_rate is NOT a false-premise detection rate — AgentResult.solved is false whenever a CORRECT verdict was missed, lumping genuine premise rejection with budget exhaustion. Documented in the docstring; false_claim_verdicts separates them. AgentResult carries no detection flag and none was invented. Anchor freeze uses two independent keys: - anchor_sha256: SHA-256 over (id, domain, problem, expected_solvable) sorted by id — which problem set was run. Order-invariant, edit-sensitive. - GATE_EPOCH = 2: a module constant, not a benchmark field — how outcomes were scored. A verifier-prompt/model change never touches the benchmark JSON, so only an epoch bump invalidates a comparison across one. Keeping it in code leaves the benchmark files untouched, as anchor-freeze discipline wants. Both helpers live in eval/harness.py and are imported by scripts/run_gate.py, which reimplemented the aggregation; its report() printed solved (over all problems) beside solve_rate, which now disagree, and is fixed to show solved/n_solvable, FPR, error count, and the sha/epoch. Tests: 11 new in test_eval.py, each written to fail against the naive implementation. Full suite 1380 passed; stash-verified zero new ruff (1==1) and zero new mypy (18==18) errors. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: A. Friedrich <alex@f2media.de>
Follow-up to the metric split. `correct_prediction` was `result.solved == expected_solvable` — one boolean meaning two different things depending on which population the problem is in, which is exactly the conflation split_metrics() removes at the aggregate level. It had no consumers (both sites were producers) and its verbose status line printed "OK" for a false-claim anchor that merely exhausted its iteration budget, sitting directly beside the new split aggregate. Removed from both producers and replaced with a population-aware status: ERROR / SOLVED / unsolved for solvable problems, ACCEPTED(FP) / rejected for anchors. The adjacent verdict= field distinguishes genuine premise rejection (major_flaw) from budget exhaustion (unsolved), which is the honest presentation given AgentResult carries no detection flag. Also syncs CLAUDE.md's Module Map for eval/harness.py, which still documented the pre-split return shape: adds split_metrics/anchor_sha256/GATE_EPOCH, the asymmetric error handling, and the note that solve_rate's denominator changed. Verified: no benchmark report schema exists under docs/schemas/ (only agent-result and consensus-result), so no schema is invalidated by the six new top-level report keys. 1380 tests pass; ruff 1==1 and mypy 18==18 vs baseline. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: A. Friedrich <alex@f2media.de>
These 25 files (276K) were the only measurement artifacts the project had
ever produced, and they were untracked — one `git clean -fd` from being lost.
Tracking them because two of them are load-bearing for the roadmap:
1. data/calibration/validation-report.json — the E-vs-F simulator FAILED its
own validation: criteria.overall_passed=false, aggregate_sim=0.031 vs
aggregate_real=0.967 (a 30x miss), spearman_rho=nan because the real data
sat at ceiling. The v3.8 PUCT direction was chosen on this instrument, so
the record of its failure belongs in the repo, not on one laptop.
2. data/calibration/{nano,qwen,flash,super}/bvd.json — the only
ground-truth-anchored measurement in the project, and it points the wrong
way. On false-claim-even-odd (provably false), the agent returned CORRECT:
depth (1x12 iters) 11/18 (61%)
breadth (6x2 iters, best by verdict) 15/18 (83%)
nemotron-super is the cleanest case: 20% -> 100%. When the premise is
false, every run that "succeeds" is a false positive, so ranking by
verdict-then-confidence selects for the most convincing wrong answer.
Bounds on that claim, stated so nobody over-reads it later: 4 non-Claude
OpenRouter models, one anchor, N=18, and the breadth arm is
scripts/breadth_vs_depth.py's own restart-and-rank (best_of_n=1 in its
config), not literally Alethic's best-of-N. Same argmax mechanism, not the
same code path. It is a hypothesis with teeth, not a verdict — and the
false_claim_accept_rate metric added in 5e0e78e is what tests it properly.
docs/results/ holds the generated reports over the same data, including the
e-vs-f-report.md whose own conclusion is "Indecisive".
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: A. Friedrich <alex@f2media.de>
The repo had no CI of any kind — no .github/, no pre-commit — while carrying four open PRs totalling ~10,400 unreviewed added lines. Every merge to date has been gated only by someone running the suite locally. Gates on pytest and mypy. Ruff runs advisory (continue-on-error) because main carries 111 pre-existing findings, 93 of them in tests/ and mostly unused imports and import ordering; gating on that today would block every merge on unrelated debt. Clean those in a dedicated pass, then drop continue-on-error. No ANTHROPIC_API_KEY is provided, deliberately: the suite is fully mocked and must stay that way, so a test that starts needing a live key will fail here. Landing this via PR #12 rather than a separate PR so it takes effect after PR #11 brings mypy to 0, which means it gates the two merges that actually carry risk (#10 at 8467 lines, #9 with three conflict hunks). Assisted-by: Claude Code:claude-opus-5 Signed-off-by: A. Friedrich <alex@f2media.de>
hyperion-git
added a commit
that referenced
this pull request
Jul 29, 2026
Brings in PR #11 (mypy 18->0), PR #12 (RQGM analysis, eval metric split, tracked evidence, CI workflow). One conflict, in the run_benchmark() return dict — both sides added keys and both are kept. The merged report now carries all three axes needed to compare two runs: search_mode which code path ran (#10) anchor_sha256 which problem set ran (#12) gate_epoch how outcomes were scored (#12) Also un-ignores data/calibration/ and docs/results/. They were ignored as "generated outputs", but they hold the project's only measurement record and that record sat untracked for months. New runs now surface as untracked so they get a keep/discard decision instead of being dropped silently. Verified: 1653 passed, 2 skipped, 3 xfailed. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: A. Friedrich <alex@f2media.de>
hyperion-git
added a commit
that referenced
this pull request
Jul 29, 2026
Brings in PR #11 (mypy), PR #12 (metric split, evidence, CI), PR #10 (v3.8 tree search). Three conflicts, all keep-both: models.py EventType REVISER_ALL_DECLINED (#9) + the 5 v3.8 search events -> 16 members (10 in v3.7, +5, +1) models.py AgentConfig enable_surveyor/enforce_checks_floor (#9) + search_mode/search (#10) test_new_types.py len(EventType) assertion 11 vs 15 -> 16 Also fixes a mypy regression this merge exposed: _parse_survey() bound `m` twice for two different types — Match[str] from enumerate() at line 115, then Match[str] | None at 133. Renamed the second to `sanity` rather than annotating it, since the reuse was the actual defect. Without this, merging #9 would have silently undone part of #11's mypy cleanup. Verified: 1707 passed, 2 skipped, 3 xfailed; mypy 0 errors across 41 files. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: A. Friedrich <alex@f2media.de>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Analysis of "The Red Queen Gödel Machine" (arXiv:2606.26294) for Alethic, plus a runnable
diagnostic implementing the #1 recommendation. Produced by a 26-agent adversarial workflow
(readers → 5 design lenses → 3-skeptic panel each → synthesis → completeness critic), then reduced
to what is faithful to the paper's demonstrated results — not its framing.
Headline finding: 3 of 4 substantive RQGM-inspired proposals failed their faithfulness skeptic
— they rest on classic ensemble/decorrelation logic, not on anything RQGM actually demonstrated. The
honest output is therefore mostly "measure first," not "adopt the framework."
The spine
Alethic's Verifier is the stationary criterion RQGM critiques. Generator≈Verifier (both Opus), so
decoupled verification hides the generator's traces but not its correlated blind spots. And there
is no labeled
(problem, solution, true_verdict)set anywhere — every accuracy signal is anchoredto the verifier's own output. So the one failure RQGM targets — a verifier accepting a wrong proof —
is currently unmeasurable.
What's in this PR
docs/plans/2026-06-27-rqgm-verifier-bias.md— ranked adoptables (adopt / defer / reject), thegrader-vs-reviewer (
verifyvscheck) asymmetry the completeness critic flagged as a HIGH miss,and the link to the live v4.0 benchmark-gate decision.
scripts/self_preference_probe.py— the Claude/configurable agent settings w iybi #1 move, measurement-only, no orchestrator change.Generates proof attempts of the
expected_solvable=falseanchors from anopusauthor vs anOpenRouter author, runs the real Opus verifier (
subagents.verify, stockVERIFIER_SYSTEM),and reports false-positive rate + Fisher exact 2×2 + Wilson 95% CI. Optional
--k5(consensus,the variance-vs-bias test) and
--check-arm(reference-lessCheckerAgent).Why a null result is a win
The anchors were designed to be caught, so FPR may be 0 → the ratio is
0/0. That cheaply falsifiesthe spine's worry and means: do not build a multi-model verifier on this evidence. The diagnostic
gates the downstream roster work in either direction.
Validation
Probe imports + argparse clean; both anchors load from benchmark JSON; lazy imports
(OpenRouter / VerifierAgent / CheckerAgent / scipy) resolve; Wilson + Fisher helpers correct. No API
calls made in CI — running it requires
ANTHROPIC_API_KEY(+OPENROUTER_API_KEYfor the nonopus arm).This is an analysis + experiment-scaffold PR; it changes no library behavior.
Assisted-by: Claude Code:claude-opus-4-8