Repository navigation
docs: R&D dossier for summary-event allocation (#533) - #535
Merged
Polichinel merged 2 commits intoNov 4, 2026
Merged
Conversation
Scaffolds the research program for how UCDP aggregate events are allocated in space and time, following the catalog in reports/investigation_summary_event_concentration/. Ten documents: the README spine, an 840-paper library survey with a 19-item acquisition list, the option space, the harness audit, a gated roadmap, a deliberately-empty analysis plan, a glossary, an append-only experiment log, and a study of the legacy views3 GedLoader. The harness audit found ~85% of the standing harness already in place: an OCP strategy registry so a new allocation strategy is registered rather than patched in, profiles as the default-off flag mechanism, the byte-identical fixture gates, a synthetic known-answer path for cheap readout, and sixteen post-mortems. The one real gap is that nothing in this repo evaluates allocation QUALITY — no locked baseline, no metric protocol, no ground truth — because allocation was never treated as a choice. That is the build, and it is constructible: 343,865 events are well-located and well-dated, carrying 68.6% of all mass, so a coarsen-and-recover test has a known answer and needs no new data. Three divergences found, all governance rather than research, and all routed to P0 rather than resolved here: ADR-049 was accepted 2026-06-28 and is not live. It decided spatial distribution "on by default", named cell 148759 and event 463131, and set a golden test that cell 148759 should drop from 273,076. The profile uses passthrough and the cell now holds 274,358 — it grew. Nothing is red because no test asserts it, which is C-365's lesson recurring. ADR-049's own worked example misdescribes the code. It states event 463131 "is spread across 12 months by temporal distribution (correct)". It produces exactly one row; the annual->date_end_only override catches it. So the spatial half is decided but dormant, and the temporal half is undecided and was believed decided. production_parity does not reproduce the legacy country-month path. The legacy loader filtered where_prec 4/6 out of priogrid-month but read the unfiltered table for country-month, so those deaths were present at country level. Our country-month derives from the grid, after the viewpoint filter, so they are in neither — approximately 48,124 events and 864,869 fatalities, 19.16% of all mass. Structural, not configurable, and an argument for making ADR-049 live, since distributed events would reach country-month on their own. The legacy notebook also corrects something I had filed as a bug. ceil_split's 0.91% inflation is faithful parity: the legacy code applies np.ceil to best, high and low alike. Fixing it is a parity break, not a bug fix, and belongs behind the same profile switch as everything else. The legacy loader also computed an is_summary flag and dropped it at the aggregation boundary, and named every column _nokgi — "no Known Geographical Imprecision" — so views-hydranet's request for a precision flag is a restoration of a legacy concept, not a new demand. The parity freeze is not the obstacle it looked like. ADR-049 section 6 already established that parity is achievable via configuration, so production_parity can stay frozen and byte-identical while a separate recommended profile carries the changes. The question becomes which profile the pipeline invokes. No code, configuration or data changed. Weighted scoring rules and intensity-measure targets are recorded as comparators and explicitly out of scope, per the boundary ADR-049's Deferred section already drew. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EfeuULbPTqrx4qtNki5dy9
Simon added all seven Tier 1 acquisitions plus Croicu2026, which was not on my list and is the most important of the eight. Library is now 848 papers. Four of them changed the design, so this records what did not survive the reading. Croicu2026 is our problem by its own name, from inside UCDP/ViEWS. Multiple Spatial Imputation fits actor-dyad-monthly Gaussian Processes over the cloud of precisely located events in a 24-month window, then samples m locations per KGI event inside its administrative polygon, emitting m complete datasets. Measured: RMSLE down 34.92% against list deletion and 36.30% against centroid imputation, winning 100% of 2,400 simulations, with mean point error 519km to 275km. Even m=1 beats centroid everywhere, and gains plateau past m=20. Actor-dyad decomposition is both essential to the method and what makes the GP tractable, about 27,000x cheaper than one global model. That contradicts two of ADR-049's deferrals. It deferred actor-informed distribution partly as premature; Croicu makes it load-bearing. It placed sampling treatments downstream; Croicu treats MSI as data preparation consuming this layer's own input. Added as option O7 with the boundary question raised as decision D5 rather than answered here, since it reaches beyond this repo. Heitjan1991 changes the argument against the status quo from degree to kind. Under coarsening at random the mechanism may be ignored; when data are not CAR, ignoring it "leads to severely biased inference". Croicu measures that KGI is non-random, correlating with remoteness, reporting quality and common predictors of violence. So passthrough and date_end_only ignore a mechanism that provably cannot be ignored, and O0 is a specification error rather than a conservative default. What stays open is which remedy, not whether one is needed. Denton1971 rejects our intended O2 by name. The identity-matrix penalty distributes each year's discrepancy equally among sub-annual periods, which is even_split, and Denton calls that specification "inadequate for practical use" because it introduces spurious year-boundary discontinuities. O2 is now the first-difference penalty, with Chow-Lin as the covariate-informed variant where an indicator series exists. ChowLin1971 also notes that temporal additivity emerges from best linear unbiasedness rather than being imposed, so a conserving allocation need not be a constrained one. Weidmann2015 both validates and bounds the exercise. Spatial error is of the order of an administrative district; 80% of matched events fall within 50km, 63.4% in the correct district. The paper recommends not operating below 50x50km cells, and our cells are 0.5 degrees. So the grid choice is vindicated and allocation precision is capped at about one cell. It also reverses a premise: counts are substantially more accurate than locations, and remoteness degrades location without degrading casualty accuracy. With Vesco2026 that gives a second and more direct argument against dropping, since dropping discards the reliable number because the coordinate is unreliable. Gotway2002 supplies the map. Ecological inference, MAUP, block kriging, pycnophylactic interpolation and spatial misalignment are all special cases of the change of support problem, so ours is not sui generis. ADR-049's proportional weighting is the bottom rung of a known overlay ladder, with Tobler1979's mass-preserving surface as the next rung, added as O1b. Tobler's Dirichlet boundary condition at water maps onto our existing land mask, and his non-negativity clipping is the same problem any fatality allocation faces. Gotway also states the mandate for our harness directly: the assumptions made when combining incompatible spatial data often surreptitiously determine cross-scale relationships, and diagnostic tools to assess them are needed. Two numbers now disagree and neither should be cited until they do not. Croicu reports KGI at 31.1% of 293,634 GED observations; we measure where_prec >= 4 at 15.5% of 440,461. Different denominators and possibly different definitions. Registered as decision D6 in P0. Also recorded: Croicu's effect sizes are not our expected gain, because his comparators are centroid imputation and list deletion, not ADR-049's proportional weighting. Quoting 34.92% as ours would be the borrowed-number error this dossier exists to avoid. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EfeuULbPTqrx4qtNki5dy9
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.
Scaffolds the research program for how UCDP aggregate events are allocated in space and time.
Follows the catalog in
reports/investigation_summary_event_concentration/(#534) and responds to#533 / #484.
No code, configuration or data changed. This is a staging area; on
promoteits designgraduates to a proposed ADR.
What's here
Ten documents in
reports/2026-11-04_summary_event_allocation_dossier/: the README spine, an840-paper library survey with a 19-item acquisition list, the option space, the harness audit, a
gated roadmap, a deliberately-empty analysis plan, a glossary, an append-only experiment log, and a
study of the legacy
views3GedLoader.The harness audit: ~85% already exists
Found, not built: an OCP strategy registry (
datafactory_provenance.registry.Registry) so a newallocation strategy is registered rather than patched into the builder · profiles as the
default-off flag mechanism · the ADR-050 byte-identical fixture gates · a synthetic known-answer
path for cheap readout · sixteen post-mortems, so negatives have a home.
The one real gap: nothing in this repo evaluates allocation quality — no locked baseline, no
metric protocol, no ground truth — because allocation was never treated as a choice. That is the
build, and it is constructible: 343,865 events are well-located and well-dated, carrying
68.6% of all mass, so a coarsen-and-recover test has a known answer and needs no new data.
All routed to roadmap P0 rather than resolved here.
1. ADR-049 is accepted and dormant. Dated 2026-06-28, it decided spatial distribution "on by
default", named cell 148759 and event 463131, and set a golden test that cell 148759 should drop
from 273,076 to its proportional share. The profile uses
passthrough:Nothing is red because no test asserts it. That is C-365's lesson recurring, and
03 §C4makeswriting that test a pre-flight blocker — expected red until the decision lands.
2. ADR-049's worked example misdescribes the code. It states event 463131 "is spread across 12
months by temporal distribution (correct)". It produces exactly one row; the
annual → date_end_onlyoverride catches it. So the spatial half is decided but dormant and thetemporal half is undecided and was believed decided.
3.
production_paritydoes not reproduce the legacy country-month path. The legacy loader readsdifferent tables for its two aggregations —
self.pg_ged(filtered) for priogrid-month,self.ged(unfiltered) for country-month — sowhere_prec4/6 deaths were present at countrylevel. Our
grid_to_country_month()takes the grid as input, after the viewpoint filter, sothey are in neither: ~48,124 events, ~864,869 fatalities, 19.16% of all mass. Structural
rather than configurable, and an argument for making ADR-049 live, since distributed events would
reach country-month on their own. (Approximate — deduplicated by event
idrather than replayingfull survivorship; the order is right, the number is provisional.)
A correction the legacy notebook forced
I had filed
ceil_split's 0.91% inflation as an ADR-040 Invariant 1 violation to fix. It isfaithful parity: the legacy code applies
np.ceiltobest,highandlowalike. Fixing itis a parity break, not a bug fix, and belongs behind the same profile switch as everything else.
The legacy loader also truncates summary events spreading past the ingestion month — a second
inherited leak, pulling the other way.
Two more legacy findings that strengthen the design:
is_summaryflag already existed and was dropped at the aggregation boundary — the sameseam where ours dies. So Summary/aggregate events are concentrated by measurement, not by reality — and one of them is ~63% of our primary evaluation score #533's ask for a precision flag is a restoration of a legacy concept,
not a new consumer demand.
_nokgi— "no Known Geographical Imprecision". The old schemadeclared the exclusion in its column names and implied a
_kgicounterpart nobody built. Ourlr_sb_bestsays nothing. The legacy schema was more self-documenting on exactly this point.The parity freeze is not the obstacle it looked like
ADR-049 §6 already established that parity is "achievable via configuration". So
production_paritystays frozen and byte-identical while a separate recommended profile carries thechanges, and the question becomes which profile the pipeline invokes — one line, reversible,
auditable — rather than whether to mutate a frozen contract.
Library: survey and acquisition list
840 papers, 3,807 claims. Strong on evaluation under domination by a few observations (31
scoring-rule papers incl.
Lerch2017on the forecaster's dilemma,Gneiting2011's thresholddecomposition,
Bolin2023SCRPS), point processes (22, incl.Brehmer2023on scoring a pointprocess's intensity measure), and UCDP measurement error (
Vesco2026: underreporting is non-linearin event size, so the large aggregates are the most accurately-counted values we hold — which is
why option O4, dropping, should be rejected).
Verified absent, checked against all 840 titles rather than inferred from a failed search:
change-of-support/MAUP (0), temporal disaggregation/benchmarking (0), areal interpolation
(~0), coarsened-at-random/partial identification (3, all Tobit — a different problem).
09_library_acquisitions.mdlists 19 items in 3 tiers with verified citations; three of the sevenTier 1 items are open access. Notable: Tobler (1979) on pycnophylactic (mass-preserving)
interpolation is ADR-040 Invariant 1 as an existing method, and the R packages
pycnoandTSdisaggregationcan serve as oracles for the evaluation harness.Caveats carried in the documents
against the deployed build before citing as current.
Weidmann (2015)— that UCDP-GED locational accuracy degrades sharply below district scale,so our "ground truth" carries its own error at ~55 km cells and the oracle is not a true ceiling.
Verification
Full suite: 2,433 passed · 16 skipped · 17 xfailed · 0 failed · 0 errors.
🤖 Generated with Claude Code
https://claude.ai/code/session_01EfeuULbPTqrx4qtNki5dy9