Epic #242 S3+S4: HydraNet roster reconfig + roster-conformance + D×K sample-count contract - #367
Epic #242 S3+S4: HydraNet roster reconfig + roster-conformance + D×K sample-count contract#367Polichinel wants to merge 6 commits into
Conversation
…the occurrence/gate channel; every HydraNet ensemble AP understated Discovered in Epic #242 S6 (views-hydranet ensemble dossier EXP-03). The pool loops ctx.targets = config.targets|regression_targets; HydraNet ensembles declare only lr_* (no by_* classification), so concat never pools the gate. AP crippled (sb-h1 0.316 vs members 0.38-0.47); recovered to near-best (0.456) by pooling by_* — no retrain, no code change. Fix direction: pool the occurrence channel by default for gated ensembles + a test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ter + wire rusty_bucket S3 (#246). The fleet moves from the pre-epic tobit configs to the v2 gated_NB roster (pre-registration 05, LOCKED 2026-08-08): gated_NB (nb, soft_gate) violet 42 / bright_starship 43 / bold_comet 44 th_gated_NB (nb, threshold_gate 0.5) blazing_meteor 45 / heavy_freighter 46 mixture_NB (mixture_nb, soft_gate) pink_pirate 42 / blue_stranger 43 / purple_alien 44 All eight share the v2 foundation (mse · softplus · body_supervision=all · weighted_bce pos_weight 2 · rollout_feedback=sample · bn_recalibrate · D×K=4×4 · lr_*/by_* targets) and all read views-datafactory / africa_me_legacy (S2 migrated the three viewser models; heavy_freighter scoped global→africa for the local run, its global template banked in the hydranet dossier). rusty_bucket now points at all eight (concat, 8×16=128 pooled) and declares `classification_targets: [by_*]` so the pool carries the occurrence gate (C-132) — the durable form of the transient `targets` gate-hack, which the #380-fixed manager now refuses. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…r parity with roster-conformance S3 (#246). The viewser↔datafactory trio-mirror parity programme (C-47) is resolved: S2 migrated all three viewser models to datafactory, so "two loss-identical trios compared via golden_hour vs stellar_horizon" no longer describes reality — the roster reorganised every model by family across both trios and moved them all off tobit. - Retire the two 3-member parity ensembles golden_hour + stellar_horizon (superseded by the single 8-member rusty_bucket; the comparison they existed for is moot). - Replace test_datafactory_parity.py (trio-mirror, tobit) with test_roster_conformance.py: pins each model to its roster (family / composition / gate / seed), the shared v2 foundation, identical grid + targets, datafactory source, and the rusty_bucket 8-member ensemble incl. the C-132 classification_targets gate-pooling + no stale `targets` key. EXPERIMENT_IN_PROGRESS is now unused (the roster is pinned, not skipped). - Downstream consequence fixes: repoint the stale-loss docstring guard to the new file; delivery-map shadow count 117→115; env-sharing pin views_ensemble 13→11. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… sampler (ADR-015 §6) S4. An ADR-067 HydraNet family head draws K = n_head_samples from the distribution per D = n_posterior_samples MC-dropout pass, so the EMITTED posterior width per cell is D×K, not D. The roster runs D=4 × K=4 = 16 (rusty_bucket pools 8×16 = 128) — but the sample-count contract still equated "samples per model" with n_posterior_samples (4) alone, so every family model's on-disk y_pred width (16) and rusty_bucket's expected_samples_per_model (16) tripped the contract (9 red tests). - conftest: add get_produced_sample_count = n_posterior_samples × n_head_samples (K defaults to 1 for every non-family model, so pre-#242 behaviour is byte-identical). - Route the ensemble expected_samples_per_model contract, the PF output-width checks (test_pfe_production_readiness), and the non-blocking drift report through the produced count. - ADR-015 §6 records the reconciliation: the two knobs stay distinct (D = MC-dropout depth, K = family draws per pass); the produced width is their product; the 128 standard is a target on the produced count. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ion note - C-132: record the durable fix (incomplete #380 migration; both _build_context sites now route through combined_targets, pipeline-core branch chore/c132-pool-gate) and the durable config form (classification_targets, pinned by test_roster_conformance). Kept Open pending merge of both PRs. - C-71: the roster LANDED (S3) — the trio-mirror parity premise this Cluster-E entry guards is retired (parity test replaced, golden_hour/stellar_horizon retired, violet pinned not skipped). Flag Cluster E (C-47/C-71/C-72/C-74/C-87) for a /review-rr pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t declare the gate A falsification pass (2026-08-10) showed the C-132 fix is config-gated, not automatic: a prediction_frame / hydranet_ucdp concat ensemble that omits classification_targets still silently drops the by_* occurrence gate, and only rusty_bucket was pinned. test_every_hydranet_pf_ensemble_declares_the_occurrence_gate generalises the check across all ensembles — green today (rusty_bucket declares it), fails loud the moment a gate-less HydraNet ensemble is added, so C-132 cannot silently recur (e.g. on the global ensemble). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
docs(ADR-015): §6 — the count that matters is the count a model produces (S4, split from #367)
|
Superseded in part. Two pieces of this are now on
Three deliberate departures, each with a reason:
Two findings from reviewing this that are not in #368:
Still to come from this branch: the two ensembles are being retired to README-only reusable slots rather than deleted outright (maintainer's call — they become slots for future HydraNet ensembles), with the preanalysis plan archived first. The C-132 work waits on views-pipeline-core#422 merging and a release being pinned here. Closing this in favour of the split is reasonable once the remaining pieces land; leaving it open as the reference is also fine. Your call. |
|
Finding from the views-pipeline-core side, on the deferred The Run against the real sniffer, three variants:
Suggested fix, entirely your call: add a classification metric key alongside the targets — e.g. Why I am flagging it now rather than after #422 merges: the discussion on this PR and on pipeline-core#427 both characterise the pipeline-core change as the blocker and this config as inert until it lands. That is half right. The pipeline-core change is needed for the gate to actually be pooled — but the config as written does not get that far, because it does not load. Merging #422 first would not reveal it; the config would still be refused. One correction to something I said on pipeline-core#427, for the record: I claimed the failure mode here would be a silent wrong answer — the gate quietly dropped. It is not silent. The sniffer refuses loudly, which is the better outcome and means this is a smaller problem than I described. Separately: the gate-pooling effect itself is real and measured — views-hydranet's EXP-03 log records h1 AP moving 0.316 → 0.456 (sb), 0.177 → 0.355 (ns), 0.135 → 0.225 (os) once the gate is pooled. I had earlier suggested #422 could not deliver the improvement it claimed; that was wrong, and the measurement is what changed my mind. Verified 2026-08-10 by running |
Epic #242 story S3 (#246), with the S4 sample-count contract reconciliation folded in (it's the only path to a green suite — the roster's D×K sampler trips the old contract).
S3 — roster + tidy-up
gated_NB (nb, soft_gate: violet 42 / bright_starship 43 / bold_comet 44),
th_gated_NB (nb, threshold_gate 0.5: blazing_meteor 45 / heavy_freighter 46),
mixture_NB (mixture_nb, soft_gate: pink_pirate 42 / blue_stranger 43 / purple_alien 44).
All share the v2 foundation (mse · softplus · body_supervision=all · weighted_bce pw2 ·
rollout_feedback=sample · bn_recalibrate · D×K=4×4 · lr_/by_ targets), all datafactory /
africa_me_legacy.
rusty_bucketpoints at all 8 (concat, 8×16=128) and declaresclassification_targetsfor the C-132 gate pooling.by the 8-member rusty_bucket (the viewser↔datafactory comparison they existed for is moot; S2
migrated all three viewser models to datafactory).
test_datafactory_parity.py(trio-mirror, tobit) withtest_roster_conformance.py:pins each model to its roster family + the shared v2 foundation + grid/targets + datafactory,
and the rusty_bucket ensemble incl. the C-132 gate channel + no stale
targetskey.EXPERIMENT_IN_PROGRESSis now unused (violet is pinned, not skipped).count 117→115; env-sharing pin views_ensemble 13→11.
S4 — sample-count contract (ADR-015 §6)
An ADR-067 family head emits D×K = n_posterior_samples × n_head_samples = 16 draws per cell,
not D=4. The contract equated "samples per model" with
n_posterior_samplesalone, so everyfamily model's on-disk width (16) and rusty_bucket's
expected_samples_per_model(16) tripped it(9 red tests). Fix: a shared
conftest.get_produced_sample_count(D×K; K defaults to 1 fornon-family models — pre-#242 behaviour byte-identical), routed through the ensemble contract, the
PF output-width checks, and the drift report. ADR-015 §6 records the reconciliation.
Register
C-132 updated with the durable fix (see cross-repo PR below); C-71 noted the roster landed and
flags Cluster E (C-47/C-71/C-72/C-74/C-87) for a
/review-rrpass.Verification
Full suite: 7574 passed, 0 failed; ruff clean. No prediction artifacts or the transient
gate-hack committed.
The
classification_targetsdeclaration only actually pools the gate once the framework fix lands:views-platform/views-pipeline-core#422 (C-132). Merge these two together.
🤖 Generated with Claude Code