fix(summarize): outside-in HDI tower + mass-aware tip — resolve minority-duplicate collapse (C-44)#100
Merged
Conversation
…ity-duplicate collapse (C-44) The v1.1 tower was built inside-out from the degenerate ~2-sample 5% floor, so any minority duplicated draw (a couple of exact zeros, a lone pair) was the unbeatably "shortest" interval and hijacked the foundation — silently collapsing tower_point AND the nested hdi_tower bands. Confirmed on real faoapi cells. Rebuild the tower OUTSIDE-IN (widest floor first, each narrower floor the shortest interval contained in its wider parent): robust by construction — outliers are shed by the wide floors and containment forbids a narrower floor from re-selecting them. The tip now reads the configurable tip_mass floor (default 0.5, the shorth), not the degenerate 5% floor. A k<=0 floor collapses to a real sample (not an averaged median) so containment stays well-defined. All tower-family tunables move to a fail-loud config.py (TOWER_CONFIG + REQUIRED_KEYS + validate_config/get) — no silent defaults: a missing key raises ValueError naming it (ADR-008/009). The tower-family public functions drop their tunable kwargs (read from config); masses stays per-call. Frozen estimators (ADR-018) untouched; CONFORMANCE_FLOOR stays 1.0.0. - engine: reversed _dense_tower; new _shortest_seed/_shortest_contained_in/ _median_in/_mid_sample_in/_tip_floor_index; deleted _select_window + old helpers - conformance: tip law restated to tip-in-tip_mass-floor - tests: +44 (truth table A-L, real faoapi cells, dup-count sweep, NaN/inf locality, multimodality, config fail-loud); 275 pass at 100% line+branch - governance: ADR-019 amended (inside-out->outside-in, tip_mass, config); Summarize CIC updated (+ the nesting-tradeoff / robust-mode-vs-MAP caveats); register C-44 resolved (Tier 1), C-32/C-34 amended; version 1.1.1 -> 1.2.0; CHANGELOG [1.2.0] Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Outside-in HDI tower + mass-aware tip + fail-loud config — resolve C-44 (Tier 1)
Fixes a silent output-correctness bug in the v1.1 tower estimators (register C-44):
a minority duplicated draw (a couple of exact zeros, a lone pair, any repeated value)
could hijack the degenerate ~2-sample 5% floor and collapse both
tower_pointand thenested
hdi_towerbands. Confirmed on real faoapi forecast cells (2–3 exact zeros + aclear positive body →
tower_point = 0.0,hdi 50% = [0, 1.49]).The fix
narrower floor is the shortest interval contained in its wider parent. Robust by
construction: outliers are shed by the well-determined wide floors and the containment
constraint forbids a narrower floor from re-selecting them. Keeps the whole tower; nesting
tower_pointreads the median of the configurabletip_massfloor (default
0.5, the "shorth"), not the degenerate 5% floor. Ak<=0floor collapsesto a real sample (not an averaged median) so containment stays well-defined.
views_frames_summarize.config) — every tower-family tunable in onedict, no silent defaults: a missing key raises
ValueErrornaming it (ADR-008/009).The tower-family functions drop their tunable kwargs (read from config);
massesstaysper-call. Frozen estimators (ADR-018) untouched;
CONFORMANCE_FLOORstays1.0.0.Verification
locality, multimodality, config fail-loud) at 100% line+branch coverage.
validate_docs.sh· 1.2.0 wheel builds./review-diffCLEAN;/falsifySURVIVED (12 probes, no hard/soft falsifications).Truth table (was wrong → now)
A2×0+30×2 → 2.0 ·E3×0+29×3 → 3.0 ·F30×2+2×5 → 2.0 ·Ldistinct body+2×3 → body (not 3.0) · majority 25×0+7×5 → 0.0 ·real faoapi cells → robust body (no collapse).
Governance
ADR-019 amended (inside-out→outside-in,
tip_mass, config); Summarize CIC updated (+ thenesting-tradeoff and robust-mode-vs-MAP caveats); register C-44 Resolved (Tier 1),
C-32/C-34 amended; version 1.1.1 → 1.2.0; CHANGELOG
[1.2.0].🤖 Generated with Claude Code