Stage 2: Validate the contract
Sourced from whest-starterkit @
96e308c.
Stage 2: Validate the contract
Stage 1 confirms your estimator runs and converges. Stage 2 confirms it satisfies the harness contract: right shapes, right types, finite values, and optional lifecycle hooks that behave.
🚀 Run it
uv run whest validate --estimator estimator.pyA passing run renders a Rich panel with four green OK rows:
Validating estimator estimator.py
╭───────────────────────────────── Validation ─────────────────────────────────╮
│ Command: validate │
│ Status: success │
│ ╭───────────────────────────────── Checks ─────────────────────────────────╮ │
│ │ ┏━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ │ │
│ │ ┃ Status ┃ Check ┃ Detail ┃ │ │
│ │ ┡━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ │ │
│ │ │ OK │ class resolved │ Estimator │ │ │
│ │ │ OK │ setup(context) completed │ 0.00s (cap 5s) │ │ │
│ │ │ OK │ predict() returned shape │ (2, 4) │ │ │
│ │ │ OK │ values finite │ all finite │ │ │
│ │ └────────┴──────────────────────────┴────────────────┘ │ │
│ ╰──────────────────────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────╯
✓ Validation passed in 21ms
Next: `whest run --estimator estimator.py --split mini`(The panel is drawn to your terminal width, and the trailing timing figure moves run to run: ~20-30 ms here.)
What each check does
class resolved— the loader foundclass Estimator(BaseEstimator)in your file (override with--class CustomName).setup(context: SetupContext)— if you definedsetup()(it's optional), the validator calls it with a probeSetupContextand confirms it returns without raising. See SetupContext fields. The0.00s (cap 5s)detail is yoursetup()budget: it is the only limit whose breach fails the whole submission rather than one MLP. To rehearse against a tighter limit, runwhest run --setup-timeout SECONDS.predict() returned shape— invoked on a probe MLP (width=4, depth=2 by default) and asserts the returned array has shape(mlp.depth, mlp.width).values finite— no NaN or Inf in the returned array.
A failing run halts at the first failed check and prints a structured error pointing at the contract clause that broke. See estimator-contract.md for the full contract.
✅ Expected outcome
Validate is a sub-second sanity check against a probe MLP. It doesn't score your estimator; it only checks that it returns the right shape of the right type with finite values. Most participants pass on the first try.
If a check fails, the panel prints the broken clause inline. For shape
mismatches, the error includes expected_shape and got_shape so you
can fix the bug without reading source.
✅ When you're ready
Move on to Stage 3: run the harness locally.