Skip to content

feat(unfao): Hop-A legacy transition guard — pin type=ensemble in selection (ADR-013 §11.4)#99

Merged
Polichinel merged 1 commit into
developmentfrom
feat/hop-a-legacy-type-guard
Jul 15, 2026
Merged

feat(unfao): Hop-A legacy transition guard — pin type=ensemble in selection (ADR-013 §11.4)#99
Polichinel merged 1 commit into
developmentfrom
feat/hop-a-legacy-type-guard

Conversation

@Polichinel

Copy link
Copy Markdown
Collaborator

Build leg 1a of the adopted wire contract — the guard ADR-013 §11.4 sequences before pipeline-core#269's first live upload.

The legacy forecast selection (unfao.py) now pins {category="forecast", type="ensemble"} via a module constant LEGACY_FORECAST_FILTERS, instead of category alone. Legacy ensemble forecasts carry type="ensemble" (pipeline-core EnsemblePathManager._target, verified); the contract's sampled_forecast_* types are disjoint by design — so #269's shard/manifest uploads can never be selected by this deployed reader (previously they'd be grabbed as "the newest forecast" and fail loud at the identity gate — an outage, reconciliation finding R1).

Declare-don't-guess: the type is a pinned constant with golden-string tests (the §3.3 pattern) asserting the exact dict, that selection routes through it, and disjointness from the contract vocabulary. CIC §6 updated. ruff clean; 145 passed (3 new).

Refs: ADR-013 §11.4 + §3.3, views-models#149 (adoption), pipeline-core#269 (the upload this guards against).

…ecast selection (ADR-013 §11.4)

The one-line guard the contract sequences BEFORE pipeline-core#269's first live
upload: the legacy reader's selection now pins {category=forecast, type=ensemble}
(LEGACY_FORECAST_FILTERS) instead of category alone. Legacy ensemble forecasts
carry type="ensemble" (pipeline-core EnsemblePathManager._target, verified);
the contract's sampled_forecast_* vocabulary is disjoint by design — so contract
shard/manifest uploads can never be selected by this deployed reader (which
would previously have grabbed the newest one and failed loud at the identity
gate: an outage, per reconciliation finding R1).

Declared, not inferred: the type is a pinned module constant with golden-string
tests (ADR-013 §3.3 spirit) asserting the exact filter dict, that selection goes
through it, and that no contract type is pinned. CIC §6 updated to match.

ruff clean; 145 passed (3 new), 43 xfailed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Polichinel Polichinel merged commit 75dada9 into development Jul 15, 2026
4 checks passed
@Polichinel Polichinel deleted the feat/hop-a-legacy-type-guard branch July 15, 2026 14:54
Polichinel added a commit that referenced this pull request Jul 15, 2026
… both legacy guards merged

faoapi's Hop-B guard work (their PR #200) ground-truthed the live bucket: six
orange_ensemble-named forecast docs stranded by the name filter — ADR-013
§4.1a's "latent" inconsistency has been firing all along (forecast serving
empty). F1 claim 2 upgraded corroborated -> confirmed (addendum in faoapi's
ratification). §11.2(b) run-0 duty substantially pre-executed. Also records:
both §11.4 legacy guards merged (vpp #99, faoapi #200); standing constraint
faoapi C-161 — the Hop-B guard must reach production before vpp's first
contract upload. No ADR clause altered; dated factual record only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant