feat(quickadapter): add label weight support policy (#85)
Per-row sample-weight composition decoupled from the final per-split
compose. Causal-guard filtering operates on raw base/label weights.
Configurable support thresholds gate the train-weight compose.
- `SampleWeightInputs` dataclass carries `(base, label,
label_weighting_config)` from `_build_sample_weight_inputs`;
`compose_sample_weights(base, label)` runs AFTER
`train_test_split`/`TimeSeriesSplit` AND AFTER causal guards.
`__post_init__` validates 1-D shape, base/label shape parity,
required `label_weighting_config` keys, and `support_policy` enum
membership.
- Thresholds in `freqai.label_weighting`:
`min_pivot_equivalent_count` (default 3),
`min_positive_label_weight_fraction` (default 0.01),
`min_effective_sample_size` (default 3.0; Kish ESS).
- `support_policy: enum {fallback, raise}` (default `fallback`)
drives the failure mode when any threshold trips. Eval (test/val)
weights bypass this policy by design.
- `compose_sample_weights` takes `on_collapse: Literal["raise",
"fallback"]` (default `"raise"`); the train path lets collapse raise
through `LabelWeightSupportError` so `support_policy` catches it,
the eval path passes `"fallback"` to preserve the label-derived
drop mask.
- `_apply_support_policy` (typed `policy: LabelWeightSupportPolicy`)
dispatches `fallback` and `raise` branches via `match`/`case` with
`assert_never` exhaustiveness; `compose_sample_weights` applies the
same pattern on `on_collapse`.
- `_shuffle_split_rows` 4-tuple shuffler covers label weights.
- `_filter_train_by_mask` accepts optional `train_label_weights` for
uniform causal-guard filtering across base+label weight arrays.
- `LabelWeightSupportSummary`, `_effective_sample_size` (Kish ESS),
and `summarize_label_weight_support` documented as operational spec.
README documents the four `label_weighting` rows;
`config-template.json` records the `fallback` default.