Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion reports/technical_risk_register.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<sha>` 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<sha>` 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.
Expand Down
Loading