Skip to content

fix(g3-budget): align sweep→eval resolver + re-key resolver on expensive geometric axes + document/retry residual#36

Merged
KE7 merged 1 commit into
mainfrom
fix/g3-budget-resolver
Jun 23, 2026
Merged

fix(g3-budget): align sweep→eval resolver + re-key resolver on expensive geometric axes + document/retry residual#36
KE7 merged 1 commit into
mainfrom
fix/g3-budget-resolver

Conversation

@KE7

@KE7 KE7 commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the run3 g3 publication finding (g3 = 96.85%, 2,092 RejectionException fails). The budget triage (rca/g3_budget_triage.md) diagnosed these as three populations — and showed "just align the sweep to the eval budget" is insufficient:

Class Count % Remediation
sweep-cap artifact ~1,304 62.3% R1 align sweep budget → eval resolver
resolver-gap ~748 35.8% R2 fix resolver preset-containment logic
genuine-hard ~40 1.9% R3 document §6 + bounded resample retry

R1 — align the sweep budget to the eval resolver

The sweep sampled every condition at a flat --max-iter 2000tighter than the eval/gym path's resolve_iteration_budget() — producing false g3 failures for conditions the real pipeline samples fine. --max-iter now defaults to omitted → the sweep resolves the budget per (task, axis-subset) through the same resolver the eval path uses, so sweep and eval agree by construction. An explicit --max-iter N still overrides (back-compat / debugging). Routed through the resolver — no hardcoded flat bump.

R2 — fix resolver under-provisioning (the principled core fix)

resolve_iteration_budget gated the combined/full budget on full preset-superset containment — including the geometrically-free appearance axes (object/camera/lighting/background, ~1 iteration each). A subset carrying all the expensive geometric axes (position+robot+distractor) but omitting one cheap axis was starved at the 5000 floor despite being geometrically as hard as combined.

Re-keyed on EXPENSIVE_GEOMETRIC_AXES = {position, robot, distractor, articulation} — a preset's budget applies iff (preset_axes & EXPENSIVE) ⊆ request. Still monotone in axis-set inclusion. position,robot,distractor now resolves to 55000 (was 5000); cheap subsets stay at 5000 (no balloon). Logic fix, not a constant bump.

R3 — document + retry the residual

  • (a) The robustly-over-constrained full-perturbation cells on the 5 worst multi-object tasks fail even at the 55000 eval ceiling across seeds — documented as §6 criterion-6 known-hard in data/known_hard_cells.json + docs/scenic_iteration_budget.md. Not masked with a larger budget.
  • (b) Added a bounded resample-on-RejectionException retry (G3_RESAMPLE_RETRIES=2) to the sweep's G3 stage for the heavy-tailed high-variance tail (e.g. bowl_on_stove: FAIL seed 0, PASS 4,441 iters seed 1). Mirrors the eval reset() settle-loop resample policy — bounded, never unbounded, never a budget bump.

Before/after evidence (live, multi-seed)

Per the triage's own single-draw classification (one seeded draw at the 55000 ceiling classifies a cell against every budget threshold at once). Pass rates over seeds:

(task, subset)                                          new_budget   OLD@2000   OLDeval   ->  NEW    n_iters
-- resolver-gap (R2): OLD eval@5000 fails, NEW@55000 passes --
put_the_bowl_on_the_plate × position,robot,distractor      55000      0/5       0/5      ->  5/5   19629,50510,5108,11343,10892
put_the_bowl_on_the_plate × position,object,robot,distr.   55000      1/5       1/5      ->  5/5   37336,5111,15411,46158,758
open_the_top_drawer × position,robot,distractor            55000      1/5       1/5      ->  5/5   107,27985,36535,8303,6083
-- sweep-cap-artifact (R1): eval already sampled these; sweep@2000 was just capped too low --
put_the_bowl_on_the_plate × combined                       55000      0/5       5/5      ->  5/5   11157,12967,8130,6082,5281
KITCHEN_SCENE2_..._on_the_plate × combined                 55000      4/5       5/5      ->  5/5   2809,267,263,68,142
open_the_top_drawer × combined                             55000      1/5       4/5      ->  4/5   1500,12943,11463,8038,FAIL*
-- genuine-hard (R3a): still FAIL at the ceiling, documented as §6 known-hard --
KITCHEN_SCENE7_open_the_microwave × full                   55000      0/3       0/3      ->  0/3   FAIL,FAIL,FAIL
bowl_on_wooden_cabinet × full                              55000      0/3       0/3      ->  0/3   FAIL,FAIL,FAIL
-- cheap controls: budget stays 5000, still pass fast (no balloon) --
put_the_bowl_on_the_plate × object,camera,lighting          5000      2/2       2/2      ->  2/2   1,1
alphabet_soup × position                                    5000      2/2       2/2      ->  2/2   2,1

* the single open_the_top_drawer × combined FAIL@55k is the high-variance straddler the R3b bounded resample retry targets.

Expected post-fix g3 publication rate: ~99.94% (R1+R2 resolve ~98.1% outright) + the documented ~40-cell §6 residual reported honestly rather than as silent failures.

Tests / CI

  • R2 regression (test_scenic.py): resolver-gap subset inherits combined budget; cheap subsets don't balloon; expensive keying stays monotone.
  • R1 + R3b regression (test_sweep_g3_budget.py, added to CI Tier-1): G3 budget routes through the resolver; explicit --max-iter overrides; cheap subset no balloon; bounded resample-then-pass and resample-is-bounded(→honest fail).
  • Tier-1 (219 passed) + exact CI validation-smoke (6/6 G0–G3) green locally; ruff check, ruff format --check, black --check all clean.

🤖 Generated with Claude Code

… on expensive geometric axes + document/retry residual

Fixes the run3 g3 publication finding (96.85%, 2,092 RejectionException fails),
which the budget triage (rca/g3_budget_triage.md) diagnosed as three populations:
62.3% sweep-cap artifact, 35.8% eval-resolver under-provisioning, ≤1.9% genuine-hard.

R1 — align the sweep budget to the eval resolver. The sweep sampled every
condition at a flat --max-iter 2000, *tighter* than the eval/gym path's
resolve_iteration_budget(), producing false g3 failures for conditions the real
pipeline samples fine. --max-iter now defaults to omitted → the sweep resolves
the budget per (task, axis-subset) through the SAME resolver the eval path uses,
so sweep and eval agree by construction. An explicit --max-iter still overrides.

R2 — fix resolver under-provisioning. resolve_iteration_budget gated the
combined/full budget on full preset-superset containment — including the
geometrically-free appearance axes (object/camera/lighting/background, ~1 iter
each). A subset carrying all the EXPENSIVE geometric axes (position+robot+
distractor) but omitting one cheap axis was starved at the 5000 floor despite
being geometrically as hard as combined. Re-keyed the budget on
EXPENSIVE_GEOMETRIC_AXES = {position, robot, distractor, articulation}: a preset's
budget applies iff (preset_axes & EXPENSIVE) ⊆ request. Still monotone in
axis-set inclusion. position,robot,distractor now resolves to 55000 (was 5000).

R3 — document + retry the residual. (a) The robustly-over-constrained
full-perturbation cells on the 5 worst multi-object tasks (bowl_on_wooden_cabinet,
KITCHEN_SCENE7_open_the_microwave, …) fail even at the 55000 eval ceiling across
seeds — documented as §6 criterion-6 known-hard in data/known_hard_cells.json +
docs, NOT masked with a larger budget. (b) Added a bounded
resample-on-RejectionException retry (G3_RESAMPLE_RETRIES=2) to the sweep's G3
stage for the heavy-tailed high-variance tail (e.g. bowl_on_stove: FAIL seed 0,
PASS 4,441 iters seed 1) — mirrors the eval reset() settle-loop resample policy;
bounded, never an unbounded loop, never a budget bump.

Live before/after (multi-seed, per the triage's own single-draw classification):
- resolver-gap (position,robot,distractor on moderate tasks): OLD eval@5000 0–1/5
  → NEW@55000 5/5 (n_iters 5108–50510, all >5000 ≤55000)
- sweep-cap-artifact (combined): OLD sweep@2000 0–4/5 → NEW 5/5
- genuine-hard (full on microwave + wooden_cabinet): 0/3, still FAIL (documented)
- cheap controls: budget stays 5000, 2/2 pass (no wall-clock balloon)

Expected post-fix g3 publication rate: ~99.94% + documented ~40-cell §6 residual.

Tests: R2 resolver-gap/no-balloon/monotone regression in test_scenic.py; R1+R3b
budget-routing + bounded-resample regression in test_sweep_g3_budget.py (added to
CI Tier-1). Tier-1 + validation-smoke green; ruff + black clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@KE7
KE7 merged commit e5bb03d into main Jun 23, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant