1# Review of UQO Working Paper 35, "The Social Compression Hypothesis" (v1.0, November 2026)23**Reviewer persona:** computational social scientist (agent-based modelling, information theory, ML validation, reproducibility).4**Examined:** `paper/main.pdf` (pp. 1–55, 66–73), `research/framework.md`, the simulation, econometrics and IRT sources, `tests/`, `Makefile`, `results/`. `.venv/bin/pytest -q` → **11 passed, 3 FutureWarnings, 1.0 s**.56## 1. Summary78The paper is unusually candid: it pre-registers a mismatch hypothesis, finds that the index adds nothing beyond its components, and says so. The pipeline is traceable (every table number I checked matches a file under `results/`), the theorems are correctly stated, and the EMPIRICAL/SIMULATED/CONJECTURE labelling is disciplined. My objections concern what the agent-based experiments are said to show. The simulation does not *test* Theorems 1–5; it hard-codes their premises (zero decoding error for records, a capacity parameter defined as a multiple of demand, bits that ignore relay hops, an acknowledgement round paid only by the flat regimes) and reports the consequences as findings. Several headline results are accounting artefacts or floor effects, and one theorem check in the text is wrong. On the econometric side there is a silent fold failure that contradicts the text, a one-third imputed regressor, and an "80% of folds" rule applied to two folds. None of this changes the negative verdict on H2; it changes what §8 and the abstract may claim.910## 2. Major issues1112**M1. "Institutions raise success" is baked into the error parameters.** `model.py` lines 192–197: records/central/federated have `err = 0` by fiat; norms use `eps_code = 0.02`; "none" uses `eps·|dialect_i − dialect_j|` with `eps = 0.25`. Decode-failure shares in the main design are exactly these constants (none 0.096, norms 0.041, records 0; recomputed), and the `eps` ablation (Table 24, p. 49) shows the ranking reverses at `eps = 0.05`. Table 20's "higher success in 99.3% / 100% of pairs" (p. 45) restates the parameter order. The paper half-admits this (p. 49) yet the abstract says the experiments "confirm" the theorems. Fixable: sweep `eps_code` against `eps` and report where the ranking flips.1314**M2. Message and bit accounting differs by regime, and the differences drive the contrasts.** (a) *Acknowledgements:* `msgs_per_recip = 1 if use_records else 2` (line 200); none/norms also load the initiator's queue with k−1 acks (line 206). At `bandwidth = 2` this saturates the flat regimes: success is 0.14 (none) / 0.15 (norms) vs 0.94 (records) in bandwidth-2 cells, against 0.90 / 0.96 / 1.00 at bandwidth 8 (recomputed). Half the 864 pairs in Table 20 compare a saturated queue with an unsaturated one; that is where "records raise success by 0.43" comes from. (b) *Relay bits:* line 236 computes bits identically for records, central and federated, while messages count 2·(depth − LCA level) hops per recipient (lines 212–218). Table 26 (p. 72) shows bits/task = 15.5 for central at every N while messages go 8 → 16. "Indistinguishable from records in success and bits" (p. 45) and "bits per success are flat in N" are artefacts of not charging bits per hop. (c) Only the LCA administrator is charged load (line 224); intermediate administrators on the path carry none.1516**M3. `admin_capacity_ratio` is circular; the "phase transition" is Theorem 5(i) by construction.** Line 146 sets `admin_bandwidth = ratio × 2λN(k−1)`: capacity is defined as a multiple of expected root load. Table 23 / Figure 8a is then the deterministic Lindley recursion; the kink sits at ratio ≈ 0.75, not 1, because N/4 producers are withdrawn (lines 155–156), so the x-axis label "ρ⁻¹" is off by that factor. Federated never saturates even at ratio 0.25 (Table 23) because *every* module administrator receives the system-wide bandwidth (lines 174–175, 229) while handling one-eighth of the load; "federated routing degrades gracefully" (p. 46) is a gift of the parameterization. P. 54 concedes "confirmed, not discovered", but §8.3 and Table 25 present it as a result.1718**M4. The network-shock result is a floor effect with the wrong mechanism attached.** Table 22 and p. 46 say link removal lowers success by ≈0.08 under hierarchies and records "and by almost nothing under flat regimes" because load concentrates on surviving neighbours. Disaggregating the DiD by bandwidth (from `runs_main.parquet`): at bandwidth 8 the effect is 0.000 for every regime except federated-0.5 (−0.02); at bandwidth 2 it is −0.14/−0.15 for records/central/federated and −0.01 for none/norms — which are already at 14% success and cannot fall. The shock (line 166) also leaves the tree built from `pos` (line 150) untouched, so hierarchies are never disrupted.1920**M5. The distribution shock is a no-op in half its cells, and Table 22 juxtaposes incommensurable columns.** With `zipf = 0` the plan distribution is uniform and every cyclic shift gives D_KL = 0 (recomputed: 0.000 for zipf 0, 1.030 for zipf 1; "0.52" on p. 44 is their mean; the target of 1.0 is hit nowhere). In shocked cells the post-window holds 10 stale and 10 re-learned periods (`adapt_delay = 10`), so Δbits/task ≈ 2 recipients × ½ × KL ≈ KL: the "0.523 vs 0.515" equality is a coincidence of k−1 = 2 and a half-stale window, not a check of Theorem 3. The ablation with `adapt_delay = 1000` (1.90 vs 1.98 per recipient) is the genuine comparison, and it evaluates the identity E_q[⌈−log₂p⌉] − E_q[⌈−log₂q⌉] ≈ D_KL rather than testing anything.2122**M6. The Theorem 1 check on p. 46 is wrong.** "The Shannon code is *longer* than the six raw bits (6.24), which is the exception the theorem allows." Theorem 1(ii)–(iii) concerns the *optimal* prefix code, and L*_p ≤ ⌈log₂ s⌉ always, since the fixed-length code is prefix-free. The simulation uses Shannon lengths (line 74); `huffman_lengths` exists but is unused (line 78). Running it: s = 64, zipf 0.5 gives H = 5.78, Shannon 6.24, **Huffman 5.81 < 6**. The theorem allows no exception; the simulation's code does. Either restate Theorem 1 for Shannon codes or use Huffman in "norms".2324**M7. Theorem 4(i) is a straw man the simulation contradicts.** A k-participant task never costs N−1 messages (p. 16); flat regimes use 2–4 messages per task, hierarchies 7–16 (Table 26), so the remark "a hierarchy cuts the message cost from linear to logarithmic in N" (p. 17) is false for the simulated task process. Theorem 1(i)'s "codeless baseline" also presupposes an agreed fixed-length enumeration — itself a shared code — so "none" is a 6-bit code with noisy decoding.2526**M8. Welfare is uninformative about communication.** With `cost_per_bit = 0.002` and value 1 per successful participant, bits are ≈1% of welfare (recomputed). "Raise welfare in every pair" (p. 45) restates "raise success"; Table 21 (norms: welfare-loss 0.06, bits-loss 1.00) leaves the two metrics unreconciled.2728**M9. One of three forward-chaining splits failed silently; the text reports three.** `h2_modern_cv_folds.csv` rows 0, 3, 6, 9, 12, 15: the `train≤1945, test 1946–1975` split errored for every model ("predict requires that you use a DataFrame…" — region 4 has no training rows before 1946, so the region FE cannot be evaluated; lines 124–125 swallow the exception). Table 16 shows "Folds 2"; its caption says "three temporal splits" and p. 39 says "in any of the three temporal splits". A win share of 0.50 over two folds is one fold; the 80% rule is meaningless at n = 2 and marginal at n = 6. The Seshat 10×5-fold run lost 14 of 420 model-folds to the same error, hence "48" in Table 11.2930**M10. `t_since` is imputed for one third of the sample.** `h2_modern.py` line 198 fills "no prior observed event" with the *full-panel maximum* (2.18 = 218 years); 33% of country-years take that value (event rate 0.095 vs 0.232 elsewhere; recomputed from `modern_h2_sample.parquet`). The code comment says "flagged in the paper"; grep of `paper/sections/*.tex` finds no flag. This is a regressor-creating imputation inside the primary cubic, and the fill value uses future data in forward chaining. Use time since panel entry plus a left-censoring indicator.3132**M11. Leakage and amendment bookkeeping.** Standardizations, the D-index PCA loadings (`build_indices.py` lines 32–36, 98–99) and `P_placebo_z` (line 202) are fitted on the full sample before folds are formed. Z-scoring is prediction-invariant for a logit with intercept, so this is minor for C1/B1/B2, but it affects the PC1 and placebo variants and the composite weighting of P; the fold-internal refit (A-001) covers Seshat LORO only. Appendix A (p. 70) says "no post-hoc amendments"; `decisions.md` records A-001 as made "after seeing the main CV results". One must change. Modern LORO folds do drop region FE correctly (line 273).3334**M12. IRT.** The "mild priors" (p. 25) are log-normal sd 0.5 on a and N(0, 2²) on b with hard clips a ∈ [0.05, 8] (`irt.py` line 49); five items still sit at a = 8 (p. 71), a boundary signature of local dependence among the jointly-coded writing items. No Q3 or residual-correlation diagnostic is reported; a testlet/bifactor structure is the standard remedy. The invariance check quotes r = 0.88 but omits the mean absolute difficulty shift of 1.16 in `measurement_diagnostics.json` (Figure 9): the fits are not linked. Missingness is called MAR "by design" (docstring line 3) although coded-item count is itself a complexity proxy (Figure 1).3536**M13. Reproducibility.** Seeds are fixed and the simulation is deterministic (tested). But `make all` needs network for `fetch` and `paper` (`build_bib.py` line 55 calls Crossref); `n_jobs = 12` is hard-coded; `pymc`/`arviz` are pinned but unused; `replication/` holds only a README; `scripts/` (named in `CLAUDE.md`) does not exist; the "three adversarial reviews … included in the package" (p. 54) were absent before this one; tests cover no econometric script on data, no hierarchical accounting, and no paper-vs-results consistency.3738**M14. Number consistency.** Matching: Tables 20–24, 26 vs `simulation_summary.json`, `ablation_admin_capacity.csv`, `regime_by_N.csv`; Tables 14–16, 18–19 vs `h2_modern_*.csv`, `h4_modern_summary.json`; Table 5 vs `measurement_diagnostics.json`. **Mismatch:** the abstract and p. 37 say "2,692 instability events"; the files give 1,676 raw events (176 + 599 + 1,041, overlaps removed); 2,692 is the number of country-years whose five-year window contains an event (Table 14 note). Also p. 44's single "0.52 bits" (see M5).3940## 3. Minor issues4142- `n_admin` is capped at N/4 (line 156) while the tree has 73 (N = 200) or 585 (N = 800) internal nodes.43- `root_load_mean` is an end-of-period backlog (stock), labelled "Root load" (flow) in Table 23.44- Forward chaining scores 1976–2005 with the 1970 decade level (line 267); fair across models, but the calibration slopes are partly luck.45- H4 modern: 3 × 5 country-blocked folds re-partition the same countries; the 15 folds are not independent.46- FutureWarnings in `seshat.py` lines 86–88 will become errors in pandas 3.4748## 4. Questions to the authors49501. Why do only the flat regimes pay an acknowledgement round, and what is the historical analogue of a record that removes both confirmation and decoding error?512. What are the success and bit rankings when bits are charged per hop and load per intermediate administrator?523. `h2_modern.py` line 259 calls the decade-FE substitution "pre-registered deviation A-001", but A-001 in `decisions.md` is the leakage check. Which is it, and where is the decade substitution logged?534. How many of the 2,692 event-windows are a single event counted up to five times, and does country clustering absorb this mechanical autocorrelation?5455## 5. Recommendation5657**Major revision.** The empirical negative result is sound and valuable; the simulation section overstates what it shows. Mandatory changes:58591. Rewrite §8 and the abstract so no simulation result is described as "confirming" or "testing" a theorem whose premise is a model parameter (M1, M3, M5); present the `eps`/`eps_code` and capacity-ratio sweeps as the actual content.602. Fix the accounting — bits per hop, load per intermediate administrator, acknowledgement round as a regime-independent switch — re-run the main design, and report success and bits by bandwidth cell so floor effects (M2, M4) are visible.613. Correct the Theorem 1 statement on p. 46 (M6): use Huffman lengths in "norms" or restate the theorem for Shannon codes.624. Repair the failed forward-chaining split, report the number of folds actually run, and replace the `t_since` max-fill with a left-censored spell plus indicator (M9, M10); re-report Tables 14–16.635. Reconcile Appendix A with `decisions.md`, correct "2,692 instability events" to event-windows, and add a test asserting that `paper/tables/*.tex` equal the `results/` files.64