From 64086a48667e8ee034ff3ce8540b5f0239f3c910 Mon Sep 17 00:00:00 2001 From: Polichinl Date: Sat, 19 Sep 2026 04:48:10 +0200 Subject: [PATCH] =?UTF-8?q?docs(register):=200.3.4=20published=20=E2=80=94?= =?UTF-8?q?=20Cluster=20H's=20recorded=20trigger=20discharged?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01N7YBtiS2kSVj27spMKDYfh --- reports/technical_risk_register.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reports/technical_risk_register.md b/reports/technical_risk_register.md index eec6cbf..f6a1972 100644 --- a/reports/technical_risk_register.md +++ b/reports/technical_risk_register.md @@ -30,7 +30,7 @@ Root causes shared by multiple concerns. Resolving the root tends to dissolve or | **E — Legacy transform machinery** | RESOLVED (2026-06-20, #119) — `DatasetTransformationModule` removed + direct `polars` declaration dropped (polars stays transitive via pipeline-core) | C-25 ✓ (+ resolved C-10, C-04, C-02) | ✓ Resolved | | **F — Value-correctness & contract assurance** | The load → compute → render → reconcile chain is tested for shape / does-not-crash, not for value equality, contract conformance, or input completeness | C-29 ✓ (render fidelity), C-35 ✓ (MAP/HDI correctness — render path + PosteriorDistributionAnalyzer both on the views-frames tower + law tests; RESOLVED, ADR-019 / #157), C-185 (`*_map` is a tower tip, not a MAP — naming debt), C-39 ✓ (metadata accessors untested — resolved, `tests/test_metadata_accessors.py`), C-41 ✓ (canonical-token contract test), C-116 ✓ (multi-match → silent wrong value — RESOLVED: fail-loud default + visible "ambiguous" cell + collision contract test), C-111 ✓ (input completeness — RESOLVED 2026-07-31, S4 #266), C-113 (actuals provenance), C-112 (bundled-data staleness — forward, pairs with C-22), C-186 ✓ (views-frames version → forecast-output drift), C-208 ✓ (gapped-lattice cell stretch/misplacement — rendering-geometry faithfulness, RESOLVED 2026-07-16), C-192 ✓ (cross-repo eval contract untested — RESOLVED 2026-07-31, executable seam test), C-227 ✓ (CM choropleth silently drew the dead country on duplicate ISO codes — RESOLVED 2026-09-17, loud guard at the merge chokepoint; latent, never observed) (+ resolved C-01, C-11) | Open — highest latent severity; mostly "write the missing correctness/contract test" (an assurance sprint). Phase 1 (correctness/contract core) landed 2026-06-28: C-29 ✓ (render==source fidelity test), C-41 ✓ (canonical-metric contract test), C-111 values-half guarded. C-186 ✓ (tower behavioural-regime tests, Phase 2, 2026-06-28). Remaining: C-112 (guards live — watch the regen cadence), C-113 / C-185 (non-test); C-111 ✓ resolved (coverage checks, S4 #266); C-192 ✓ resolved (seam test landed, S2 #264); C-39 ✓ resolved (accessor tests landed, 2026-07). | | **G — Partner-deliverable readiness** | Reports are built for internal preview, not yet hardened as a standalone, traceable, decision-appropriate *partner artifact* | C-28 ✓ (offline / self-contained — RESOLVED, vendored Tailwind, #132), C-34 ✓ (provenance / auditability — RESOLVED, footer stamp, #131), C-187 ✓ (vendored-CSS class coverage — RESOLVED, #132), C-188 ✓ (machine-readable provenance — RESOLVED, #132), C-109 (decision-appropriate uncertainty), C-214 ✓ (plotly-injection heuristics — RESOLVED 2026-07-31, S3 #265) | Open — C-109 (decision-appropriate uncertainty, partially delivered 2026-07: the #230 P(any) exceedance map layer) is the live remainder; C-214 ✓ resolved (S3 #265); offline + provenance now shipped | -| **H — Published-state qualification gap (dev-tandem ↔ PyPI seam)** | Contracts, pins, and names are qualified against dev branches moving in tandem, never against **published** artifacts — the coordinated publish (#179) is the single event where every deferred qualification fires at once | C-213 ✓ (root — vpc pin outran PyPI; import surface canonicalized + guarded 2026-07-31 S1 #263; ordering half resolved 2026-08-03 when vpc 3.0.0 published pre-qualified), C-192 ✓ (cross-repo seam untested — resolved S2 #264), C-36 (upstream transitive pins — re-probed at vpc's 2026-08-03 publish: envelope matches ours, ingester3==2.1.1 unchanged so the levenshtein wall persists), C-185 (rename waits on a coordinated cross-repo change), C-186 ✓ residual (b) (exact-pin views-frames for release), C-211 (partial — cross-repo decision, not publish-gated) | Open (added review-rr 2026-07-31) — mitigation is the #179 release-gate runbook (largely written); C-192's executable contract test landed (S2 #264); C-36 stays upstream-blocked regardless. **SECOND CONFIRMED FIRING (2026-08-02, v0.3.3):** 0.3.2's published `requires_dist` pin `views-evaluation>=0.4.0,<1.0.0` — qualified only against the dev-tandem git source — excluded views-evaluation **1.0.0** the day it hit PyPI, breaking platform co-resolution at the coordinated publish (caught by a sibling-repo agent). Fixed same-day: pin `>=1.0.0,<2.0.0`, interim git-source retired (its documented trigger fired), suite green against the RELEASED 1.0.0. The root cause has now bitten in production twice (vpc pin C-213(a) + this); every remaining dev-tandem git source (vpc, until their 3.0.0 publishes) carries the same latent defect until re-qualified at its publish. **CYCLE CLOSED (2026-08-03, #279):** vpc 3.0.0 published to PyPI carrying the pre-qualified pins (the vpc#313 warning worked — no third firing); the last dev-tandem git source retired, `views-reporting==0.3.3` co-resolves from PyPI alone, suite green against the released 3.0.0. **No dev-tandem git sources remain anywhere in pyproject/uv.lock** — the cluster's generating condition is discharged for this release cycle; it re-arises only if a future unreleased-dependency tandem is reintroduced. **THIRD EXPOSURE — of the published-metadata facet only, caught as a prediction (2026-09-17, #289):** no dev-tandem was reintroduced and the `<2.0.0` ceiling WAS correctly qualified against the released 1.0.0; what is Cluster-H-shaped is the second half below. views-evaluation's pandas-free 2.0.0 (their #66/#72) and vpc's coming `^2.0.0` pin (vpc#515) would make our `<2.0.0` ceiling unsatisfiable in the shared env. Source widened to a SPAN pin `>=1.0.0,<3.0.0` — deliberately NOT the requested `>=2.0.0`, because 2.0.0 was unpublished at fix time (PyPI latest 1.0.0) and a floor naming an unpublished version is exactly C-213(a)'s mistake. Safety evidence: everything we import lives in `evaluation.metric_frame` (+ `metric_catalog` in one test), and no 2.0.0 story changes the MetricFrame format or the names we import (S8's gate: "MetricFrame format unchanged"; `[frames]` survives; the only merged changes to that module since 1.0.0 are to the provenance stamp's value — the `+g` suffix and S1's bounding of it — which we treat as opaque text). **Not yet pre-empted at the seam that matters:** the shared env resolves from PyPI, where 0.3.3's immutable metadata still says `<2.0.0` — vpc#515's "after views-reporting has widened" precondition is met only by a **0.3.4 publish**, which collides with the publish-last rule and is therefore a decision, not a mechanical step. Re-qualification trigger: views-evaluation 2.0.0 on PyPI → re-lock, suite, then the `>=2.0.0` floor + 0.3.4. **TRIGGER FIRED 2026-09-18 — re-qualified, floor deliberately NOT raised:** 2.0.0 published (21:29). Our suite is green on it (442) in isolation and a 2.0.0-emitted frame round-trips through `MetricFrameFileSource` + `mean_metric_value` exactly. But `uv lock --upgrade-package views-evaluation` resolves only 1.1.0: **views-pipeline-core 3.2.0 pins `views-evaluation<2.0.0`**, and its evaluation stage still calls `report.to_dataframe()` (stage.py:375-377) — their ceiling is protecting a live call, not stale. A `>=2.0.0` floor here today would make views-reporting + vpc mutually unsatisfiable (the C-115-shape shared-env trap). Sequencing is therefore fixed: vpc#515 lands (removing their `to_dataframe` egress, vpc#512) → our floor `>=2.0.0` → our 0.3.4 publish. The lock stays on 1.0.0 until then; the span admits 2.0.0 the moment vpc's ceiling lifts. **LANDED 2026-09-19:** vpc 3.3.0 requires `views-evaluation>=2.0.0` (their #515/#512 shipped); floor raised to `>=2.0.0,<3.0.0` in the same PR as the 3.3.0 bump; lock resolves 2.0.0 (129→126 packages: views-evaluation dropped its scikit-learn dep, but sklearn stays via viewser→pyod; the three that left are stepshift, xarray and views-transformation-library — vpc 3.3.0 dropped the latter). The 0.3.4 publish remains the open decision. **NEXT TRIGGER, already visible (2026-09-19): views-frames 2.0.0 is on PyPI** and cannot reach a reporting env until TWO ceilings move — ours (`views-frames<2.0.0`, deliberate: C-186's characterization pins must re-qualify a major of the leaf data contract) and views-evaluation's `[frames]` extra (`<2`, theirs — views-evaluation#91). Not a rider on the 3.3.0 bump; a separate qualification PR when views-evaluation lifts theirs. | +| **H — Published-state qualification gap (dev-tandem ↔ PyPI seam)** | Contracts, pins, and names are qualified against dev branches moving in tandem, never against **published** artifacts — the coordinated publish (#179) is the single event where every deferred qualification fires at once | C-213 ✓ (root — vpc pin outran PyPI; import surface canonicalized + guarded 2026-07-31 S1 #263; ordering half resolved 2026-08-03 when vpc 3.0.0 published pre-qualified), C-192 ✓ (cross-repo seam untested — resolved S2 #264), C-36 (upstream transitive pins — re-probed at vpc's 2026-08-03 publish: envelope matches ours, ingester3==2.1.1 unchanged so the levenshtein wall persists), C-185 (rename waits on a coordinated cross-repo change), C-186 ✓ residual (b) (exact-pin views-frames for release), C-211 (partial — cross-repo decision, not publish-gated) | Open (added review-rr 2026-07-31) — mitigation is the #179 release-gate runbook (largely written); C-192's executable contract test landed (S2 #264); C-36 stays upstream-blocked regardless. **SECOND CONFIRMED FIRING (2026-08-02, v0.3.3):** 0.3.2's published `requires_dist` pin `views-evaluation>=0.4.0,<1.0.0` — qualified only against the dev-tandem git source — excluded views-evaluation **1.0.0** the day it hit PyPI, breaking platform co-resolution at the coordinated publish (caught by a sibling-repo agent). Fixed same-day: pin `>=1.0.0,<2.0.0`, interim git-source retired (its documented trigger fired), suite green against the RELEASED 1.0.0. The root cause has now bitten in production twice (vpc pin C-213(a) + this); every remaining dev-tandem git source (vpc, until their 3.0.0 publishes) carries the same latent defect until re-qualified at its publish. **CYCLE CLOSED (2026-08-03, #279):** vpc 3.0.0 published to PyPI carrying the pre-qualified pins (the vpc#313 warning worked — no third firing); the last dev-tandem git source retired, `views-reporting==0.3.3` co-resolves from PyPI alone, suite green against the released 3.0.0. **No dev-tandem git sources remain anywhere in pyproject/uv.lock** — the cluster's generating condition is discharged for this release cycle; it re-arises only if a future unreleased-dependency tandem is reintroduced. **THIRD EXPOSURE — of the published-metadata facet only, caught as a prediction (2026-09-17, #289):** no dev-tandem was reintroduced and the `<2.0.0` ceiling WAS correctly qualified against the released 1.0.0; what is Cluster-H-shaped is the second half below. views-evaluation's pandas-free 2.0.0 (their #66/#72) and vpc's coming `^2.0.0` pin (vpc#515) would make our `<2.0.0` ceiling unsatisfiable in the shared env. Source widened to a SPAN pin `>=1.0.0,<3.0.0` — deliberately NOT the requested `>=2.0.0`, because 2.0.0 was unpublished at fix time (PyPI latest 1.0.0) and a floor naming an unpublished version is exactly C-213(a)'s mistake. Safety evidence: everything we import lives in `evaluation.metric_frame` (+ `metric_catalog` in one test), and no 2.0.0 story changes the MetricFrame format or the names we import (S8's gate: "MetricFrame format unchanged"; `[frames]` survives; the only merged changes to that module since 1.0.0 are to the provenance stamp's value — the `+g` suffix and S1's bounding of it — which we treat as opaque text). **Not yet pre-empted at the seam that matters:** the shared env resolves from PyPI, where 0.3.3's immutable metadata still says `<2.0.0` — vpc#515's "after views-reporting has widened" precondition is met only by a **0.3.4 publish**, which collides with the publish-last rule and is therefore a decision, not a mechanical step. Re-qualification trigger: views-evaluation 2.0.0 on PyPI → re-lock, suite, then the `>=2.0.0` floor + 0.3.4. **TRIGGER FIRED 2026-09-18 — re-qualified, floor deliberately NOT raised:** 2.0.0 published (21:29). Our suite is green on it (442) in isolation and a 2.0.0-emitted frame round-trips through `MetricFrameFileSource` + `mean_metric_value` exactly. But `uv lock --upgrade-package views-evaluation` resolves only 1.1.0: **views-pipeline-core 3.2.0 pins `views-evaluation<2.0.0`**, and its evaluation stage still calls `report.to_dataframe()` (stage.py:375-377) — their ceiling is protecting a live call, not stale. A `>=2.0.0` floor here today would make views-reporting + vpc mutually unsatisfiable (the C-115-shape shared-env trap). Sequencing is therefore fixed: vpc#515 lands (removing their `to_dataframe` egress, vpc#512) → our floor `>=2.0.0` → our 0.3.4 publish. The lock stays on 1.0.0 until then; the span admits 2.0.0 the moment vpc's ceiling lifts. **LANDED 2026-09-19:** vpc 3.3.0 requires `views-evaluation>=2.0.0` (their #515/#512 shipped); floor raised to `>=2.0.0,<3.0.0` in the same PR as the 3.3.0 bump; lock resolves 2.0.0 (129→126 packages: views-evaluation dropped its scikit-learn dep, but sklearn stays via viewser→pyod; the three that left are stepshift, xarray and views-transformation-library — vpc 3.3.0 dropped the latter). **0.3.4 PUBLISHED 2026-09-19 02:45 (Simon-approved that day, the recorded trigger having fired):** PyPI metadata `vpc>=3.3.0`, `views-evaluation>=2.0.0`; cold-cache resolution proves a plain install now selects 0.3.4 + vpc 3.3.0 + eval 2.0.0 (it had silently backtracked to 0.3.3 + vpc 3.2.0 — the row-blanking stage — until this publish). Watcher lesson re-confirmed: a warm resolver cache served the pre-publish index for ~1 min; verify with a cold cache. **NEXT TRIGGER, already visible (2026-09-19): views-frames 2.0.0 is on PyPI** and cannot reach a reporting env until TWO ceilings move — ours (`views-frames<2.0.0`, deliberate: C-186's characterization pins must re-qualify a major of the leaf data contract) and views-evaluation's `[frames]` extra (`<2`, theirs — views-evaluation#91). Not a rider on the 3.3.0 bump; a separate qualification PR when views-evaluation lifts theirs. | | **I — Post-B2 eval-report comparison seam (the baselines-vanishing braid)** | The B2 inversion shipped with its production wiring unverified end-to-end: consumer and producer disagree on frame location, declarations/targets/pins/envs each independently blank comparison rows, and every failure mode is silenced or mislabeled — so the deliverable degraded for months with green CI | C-215 ✓ (root, Tier 1 — subject-rooted source + seam test pinning it; RESOLVED 2026-09-19), C-216 (target drift + stranded fixes), C-217 (pins/envs make the seam unreachable), C-218 (Tier 1 — zero-report silence), C-219 (declaration/announce layer), C-220 (post-fix detonation), C-221 (corruption path), C-222 (vintage semantics dropped), C-223 (cache short-circuit / no baseline orchestrator), C-224 (3.0.0 classification drop), C-225/C-226 (ride-alongs) | Open — ROOT RESOLVED 2026-09-19 (C-215 ✓: vpc 3.3.0 per-model source + our seam-test correction, in step). Remaining members: C-216/C-217 (views-models configs/pins), C-218 (silence), C-219 (announce), C-220 (post-fix detonation — NOW ARMED: rows CAN resolve, so once C-223's one-time baseline evaluation writes a cm-baseline frame, a pgm subject declaring it hits the level guard and aborts the whole report; the cross-level scrub is C-220's own remediation on views-models, not #405's vocabulary fix), C-221, C-222, C-223 (baselines still need a one-time evaluation run), C-225. End-to-end proof (a real ensemble report with baseline rows) still owed. Sequencing note, updated: the original constraint (C-220/C-225 land WITH the C-215 fix) was NOT honoured — upstream shipped the root fix alone in 3.3.0 and we corrected the seam test in step; C-220's scrub and C-225's AP-sort are now owed BEFORE C-223's baseline evaluation run, which is the step that would actually arm them. C-192's seam contract correction: done. Cross-repo: vpc stage + views-models configs/branches own most mechanisms; this repo owns the template/source/announce layers and the seam test. | C-34 (provenance) and C-28 (offline) now anchor **Cluster G** (partner-deliverable readiness) rather than standing alone; the C-108 inversion does not fix C-28 (the exported HTML's view-time CDN dependency), which is why C-28 moved out of Cluster A.