Skip to content

[P1] Production scoring hardwired to credit; non-credit asset class raises, 7/8 weight TOMLs inert #693

Description

@stranske

Why

Production scoring is hardwired to a single asset class. Both production callers pass
weights_by_asset_class=weights_by_asset_class_for("credit"):
src/inv_man_intake/v1_smoke.py:303-306 (also asset_class="credit") and
app/streamlit_app.py:197-200. But weights_by_asset_class_for (scoring/weights.py:111-117) returns a
single-key dict {that_one_class: weights}. So compute_score's weight_sets[canonical_asset_class]
(engine.py:116) only has credit_long_short. Verified by execution: a submission with
asset_class="macro" and the credit weights dict raises
ValueError: missing weight set for canonical asset class 'macro'.

Consequence: the #592 fix wired only credit. The other 7 launch asset-class TOMLs
(config/scoring_weights/{activist,macro,quant,multi_strat,trend_following,credit_relative_value,equity_market_neutral}.toml)
— which load_weight_registry validates must all exist (weights.py:91-93) — are never used in any
production scoring path and would crash if used
. This is a current break for any non-credit manager.

Scope

Make the production scoring path use the weight set for the submission's actual asset class, so all 8
launch TOMLs are live. Either (a) have callers pass the full registry shaped for compute_score, or
(b) add a weights_for_registry() helper returning all classes and use it in v1_smoke.py + streamlit_app.py,
and stop hardcoding asset_class="credit" where a real asset class is available.

Non-Goals

  • Do NOT change the weight VALUES in the TOMLs or default_weights_by_asset_class().
  • Do NOT change compute_score's selection logic (it already picks by canonical asset class).
  • Scaffold-only completion does NOT count: wiring that still only loads credit, or that leaves a non-credit
    submission raising, is a failure. The multi-class test below must pass.

Tasks

  • Add scoring/weights.py::weights_for_registry(config_dir=None) -> dict[str, dict[str, float]] returning
    every launch class from load_weight_registry in compute_score shape.
  • In v1_smoke.py:300-306, pass the manager's real asset class (not the literal "credit") and the
    full-registry weights (or weights_by_asset_class_for(<real_class>)).
  • In app/streamlit_app.py:194-200 (and _browser_safe_demo_fixture), do the same.
  • Add tests/scoring/test_weights_config.py::test_compute_score_works_for_all_launch_classes scoring one
    submission per launch class through the registry weights.

Acceptance Criteria

  • Named test test_compute_score_works_for_all_launch_classes passes: each of the 8 launch asset classes
    scores without raising, using its own TOML weights.
  • Deliberate-break gate: edit one non-credit TOML (e.g. config/scoring_weights/macro.toml) to change a
    weight (keeping sum=1.0); the macro case in the named test must observe the changed score (assert the
    contribution reflects the edit). Revert; assertion returns to baseline. Capture both. (Proves operator edits
    to non-credit TOMLs now affect scores.)
  • pytest tests/scoring/ tests/baseline/ -q green.

Implementation Notes

  • Confirmed: compute_score(ScoreSubmission(asset_class="macro", components=[...]), weights_by_asset_class=weights_by_asset_class_for("credit"))ValueError.
  • load_weight_registry() (weights.py:75-94) already loads + validates all 8; the only gap is the single-key
    reshaping in weights_by_asset_class_for and the hardcoded "credit" at the call sites.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions