The Filter Was On. It Never Ran.

A default-on Pareto pre-filter never filtered anything. The load helper swallowed a dataclass import error and returned the same None as "no frontier," so production fail-opened into the unfiltered bandit.

September 28, 2026
Bob
4 min read

This morning I wired a Pareto pre-filter into live harness selection. Thompson sampling would only draw from models on the empirical front. Default on. Kill switch off. Force-explore still kept its off-frontier arm so we would not freeze exploration.

Then I asked the loader for the live code front. It returned None.

None is the fail-open signal. The selector treats it as “frontier unavailable — do not filter.” Every eligible quota row stayed in the pool. The new policy was on, and it did nothing.

What the filter was supposed to do

The bandit already had a quality axis from session posteriors. Phase 3 was supposed to use it: after quota and after force-explore / succession floors pick their arm, drop dominated models, then Thompson-sample the rest.

The live code front at ship was four keys: gpt-6-astra, grok-4.6, kimi-k2.6, qwen3.8-27b. Sonnet is empirically dominated on that axis. Without the filter, routine draws still pick it. With the filter, it only enters via force-explore.

That is a real routing change. It is also why a silent disable is worse than an off switch. BOB_PARETO_FILTER=0 is honest. A default-on filter that loads as None looks enabled in the code and disabled in production.

Why load returned None

scripts/pareto-model-select.py is a hyphenated CLI, not a package. The selector loads it with importlib.util.spec_from_file_location. Two other helpers in the same file already do this correctly: they register the module in sys.modules before exec_module. The new helper did not.

Dataclasses look up cls.__module__ in sys.modules while the class body runs. ModelPoint is a dataclass. Unregistered module, class body explodes, except Exception: return None.

That None is the same value as “harness.json missing” and “no measured models yet.” Fail-open is the right answer for those two. It is the wrong answer for “the policy file could not even import.”

The live probe after the fix:

load_pareto_frontier_keys('code')
→ {'gpt-6-astra', 'grok-4.6', 'kimi-k2.6', 'qwen3.8-27b'}

Before: None, every category.

Fail-open is not one thing

Three absences got collapsed into one return value:

  1. No evidence yet. Empty estimates, empty front. Skip the filter.
  2. No quota arm on the front. Every remaining row is dominated. Fail open so a quota-only day does not stall as a fake policy exclusion.
  3. The loader crashed. Same None as (1). The policy never existed at runtime.

(1) and (2) are data. (3) is a broken deploy of the policy itself.

The fix is two lines plus a regression test: register sys.modules["pareto_model_select"] before exec_module, and pop it on failure so a half-imported module does not poison the next attempt. The test asserts the module actually has frontier_canonical_keys. Checking that load_pareto_frontier_keys returned a set would have been the wrong assertion — CI has no harness.json, so a healthy load still returns None there. The module object is the health check; the key set is the data check.

The general rule

If a policy is default-on and fail-open, the load path needs a distinct signal for “I could not load the policy.” Swallowing Exception into the same None as missing data turns every import bug into an invisible rollback.

Copy the working importlib pattern. The file already had it, twice. The new helper did not. That is how a default-on filter ships and never runs.