Skip to content

refactor(validator): unify per-repo config override machinery#1333

Open
plind-junior wants to merge 1 commit into
entrius:testfrom
plind-junior:refactor/per-repo-config-resolver
Open

refactor(validator): unify per-repo config override machinery#1333
plind-junior wants to merge 1 commit into
entrius:testfrom
plind-junior:refactor/per-repo-config-resolver

Conversation

@plind-junior
Copy link
Copy Markdown
Contributor

What

Collapses the three parallel per-repo config families in load_weights.py
(eligibility, scoring, time-decay) into one spec-driven mechanism. Each family
was added in a separate PR (#1293, #1300) by copy-pasting the same
resolve → coerce → parse → validate scaffolding, leaving the file at 666 lines
with three identical pick closures, two identical coerce functions, three
near-identical parse functions, six field-name tuples, and two hand-written
range validators.

Pure refactor — no behavioral change to scoring, eligibility, or config
loading. The public API (resolve_eligibility, resolve_scoring,
resolve_time_decay, all Repo*Config / Resolved* dataclasses) is unchanged,
so no downstream caller is touched.

Changes

  • _FieldSpec: one declaration per overridable field — caster, default
    constant, range bounds (inclusive/exclusive), and an optional note (e.g.
    "used as a divisor"). Three tables drive everything: _ELIGIBILITY_SPECS,
    _TIME_DECAY_SPECS, _SCORING_SPECS.
  • Generic helpers replace the duplicated machinery:
    • _resolve_overrides ← three pick-closure resolvers
    • _coerce_override_coerce_eligibility_value + _coerce_scoring_value
    • _parse_overrides ← three parse functions + six field-name tuples
    • _bound_desc / _validate_ranges ← two validators with ~15 inline checks
  • resolve_*, _parse_*, and _validate_*_configs are now thin wrappers over
    the generic helpers.
  • Net: −207 / +73 in load_weights.py. Adding a 4th override family is now
    a ~6-line spec-table entry instead of ~80 lines of boilerplate.

Tests

  • 4 new cases in test_load_weights.py locking the centralized paths: the
    eligibility divisor case (exclusive-min + "used as a divisor" note), nested
    scoring.time_decay range rejection, and inclusive-vs-exclusive bracket
    rendering in error messages ([0, 1] vs (0, 1]).
  • Full suite: 841 passing. ruff check, ruff format --check clean;
    pyright shows no new errors.

Collapse the three parallel per-repo config families (eligibility,
scoring, time-decay) into one spec-driven mechanism. Each family was
added separately (entrius#1293, entrius#1300) by copy-pasting the same resolve ->
coerce -> parse -> validate scaffolding.

- _FieldSpec declares each overridable field: caster, default constant,
  range bounds, and an optional note. Three spec tables drive everything.
- Generic helpers replace the duplication: _resolve_overrides (was 3
  pick-closure resolvers), _coerce_override (was 2), _parse_overrides
  (was 3 + 6 field-name tuples), _bound_desc/_validate_ranges (was 2
  validators with ~15 inline checks).
- resolve_*, _parse_*, _validate_*_configs become thin wrappers. Public
  API and dataclasses unchanged; no downstream caller touched.
- Net -134 lines in load_weights.py; a 4th override family is now a
  ~6-line spec entry instead of ~80 lines of boilerplate.

Pure refactor - no behavioral change. Adds 4 tests locking the
centralized paths (divisor note, nested time_decay range rejection,
inclusive-vs-exclusive bracket rendering). Full suite: 841 passing.
@xiao-xiao-mao xiao-xiao-mao Bot added the refactor Code restructuring without behavior change label May 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Code restructuring without behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant