Bundle review table

Test 04 — Nestedness Buffers Loss

Supplied working report; original verdicts not validated.

Review status: Needs review. This is an archival source note, not a passed proof.

README.md

# Test 04 — Nestedness Buffers Loss

**Preprint draft — not peer reviewed.** Designed and executed with AI assistance
(DeepSeek, via its coding agent).

## Result

The proposal is not supported. Across 175 plant–pollinator networks, robustness to
plant loss is associated mainly with connectance, with species richness second;
nestedness adds almost nothing once the other two are controlled.

In the pre-specified joint model the standardised coefficient is 1.095782 for log
connectance (`model.M1_joint.coefs.log_connectance.beta`) and 0.627288 for log
richness (`model.M1_joint.coefs.log_richness.beta`), both with p = 0.0
(`model.M1_joint.coefs.log_connectance.p`,
`model.M1_joint.coefs.log_richness.p`). The NODF coefficient is negative,
−0.158692, and not distinguishable from zero, p = 0.143435
(`model.M1_joint.coefs.nodf.beta`, `model.M1_joint.coefs.nodf.p`). The partial
correlation between robustness and NODF, controlling richness and connectance, is
therefore also negative: r = −0.1117, p = 0.143435
(`model.M1_joint.partial_nodf.r`, `model.M1_joint.partial_nodf.p_asymptotic`).

LMG relative importance assigns 58.38% of the explained variance to connectance,
20.84% to richness and 20.78% to NODF (`model.M1_joint.lmg.log_connectance.pct`,
`model.M1_joint.lmg.log_richness.pct`, `model.M1_joint.lmg.nodf.pct`). LMG gives
NODF credit for variance it shares with connectance; its unique contribution — the
drop in R² when the term is removed — is only 0.008445, or 2.55% of the model's R²
(`model.M1_joint.drop_r2.nodf`, `model.M1_joint.drop_r2_pct.nodf`). The
corresponding drops are 0.188434 (56.83%) for connectance and 0.119016 (35.89%)
for richness (`model.M1_joint.drop_r2.log_connectance`,
`model.M1_joint.drop_r2_pct.log_connectance`,
`model.M1_joint.drop_r2.log_richness`,
`model.M1_joint.drop_r2_pct.log_richness`). The full model explains R² = 0.3316
(`model.M1_joint.r2`).

The formal verdict is **PARTIAL** (`verdict.verdict`), but not partial support. All
three SUPPORT conditions fail: richness retains a partial association (|β| = 0.627288 against 0.10,
p = 0.0 against 0.05; `design.criteria.beta_small`, `design.criteria.p_weak`);
NODF is not associated at p < 0.01 (`design.criteria.p_strong`); the ratio model
explains 0.129943, below 0.25 (`model.M2_ratio.r2`, `design.criteria.r2_min`); and
the partial correlation is negative. REFUTE also fails, because the richness
coefficient is smaller than connectance's 1.095782. The data do not support the
proposal, but they do not reduce to "richness does everything" either.

## What was tested and how

The proposal claims that robustness is set by nestedness relative to connectance,
not by richness. It is a variance-partitioning claim: because all four quantities
are correlated, the test asks which predictor retains a partial association once
the other two are controlled, and how the explained variance partitions.

The data are the Web of Life plant–pollinator database (Zenodo record 6630184,
version 2). The file has 87,385 rows (`data.rows_read`); 153 exact duplicates were
removed after whitespace normalisation (`data.duplicate_rows_dropped`), leaving
87,232 unique records (`data.rows_unique`). Rows are grouped into 185 site-level
networks using `id_network_aggreg` (`data.networks_read`). Ten networks with fewer
than 10 plant or 10 pollinator species were excluded
(`data.networks_dropped_small`, `design.min_plants`,
`design.min_pollinators`); no network failed the 20-interaction rule
(`design.min_links`). The analysable set is 175 networks (`data.networks_kept`)
containing 8,473 plant and 21,783 pollinator network–species records
(`data.plant_species_total_kept`, `data.pollinator_species_total_kept`) and 78,720
links (`data.links_total_kept`). Mean richness is 172.891 species
(`data.mean_richness`), but the distribution is skewed: the median is 118
(`data.median_richness`). Of the retained interaction rows, 69.97% are identified
to species level (`data.pct_identified_ok`).

NODF was implemented directly from the definition of Almeida-Neto and colleagues
(2008), not approximated by a null-model z-score. It is unit-checked in `run.py`
against a hand-worked 3 × 4 matrix (expected 83.333333,
`checks.nodf.hand_matrix.computed`), a perfectly nested matrix (100, `checks.nodf.perfect_nested.computed`), a
brute-force reference implementation, row/column permutation invariance, and a
bitmask round-trip. Robustness is R50 from 1,000 random plant-removal orders
(`design.n_orders`): plants are removed one at a time, pollinators go extinct when
their last plant partner is removed, and R50 is the first plant-removal fraction at
which at least half the original pollinators are extinct. Mean R50 is 0.7225
(`data.mean_r50`); the mean area under the extinction curve is 0.3505
(`data.mean_auc`). The main model is an equal-weight OLS of R50 on log richness,
log connectance and NODF, all z-scored, with n = 175 (`model.M1_joint.n`). Each coefficient's p-value is
checked against a seeded 20,000-draw residual permutation
(`design.permutation_p_draws`; NODF: p = 0.13794,
`model.M1_joint.partial_nodf.p_permutation`).

## The variance partition

| Term | Standardised β | p | LMG share (%) | Drop in R² | Unique share (%) |
| --- | ---: | ---: | ---: | ---: | ---: |
| log richness | 0.627288 | 0.0 | 20.84 | 0.119016 | 35.89 |
| log connectance | 1.095782 | 0.0 | 58.38 | 0.188434 | 56.83 |
| NODF | −0.158692 | 0.143435 | 20.78 | 0.008445 | 2.55 |

β and p are in `model.M1_joint.coefs.<term>.beta` and `.p`; LMG shares in
`model.M1_joint.lmg.<term>.pct`; drops in `model.M1_joint.drop_r2.<term>` and
`model.M1_joint.drop_r2_pct.<term>`.

The predictors are strongly collinear: NODF correlates 0.7899 with log
connectance and −0.5246 with log richness; log richness correlates −0.8129 with
log connectance (`model.correlations.nodf_log_connectance`,
`model.correlations.nodf_log_richness`,
`model.correlations.log_richness_log_connectance`). The connectance VIF is 6.372
(`model.M1_joint.vif.log_connectance`). This is why NODF's bivariate correlation
with R50, 0.3778 (`model.correlations.r50_nodf`), disappears under control. The
proposal's own ratio has a negative coefficient, −0.462059 (p = 0.00002,
`model.M2_ratio.coefs.ratio_nodf_connectance.beta`,
`model.M2_ratio.coefs.ratio_nodf_connectance.p`), and its model explains
0.129943 (`model.M2_ratio.r2`); a log-ratio variant reaches 0.157345
(`model.M2_log_ratio.r2`). The ratio does less work than its components.

## Sensitivity

None of the pre-specified checks finds a positive, significant nestedness effect.
Standardised NODF against 500 fixed-margin null matrices (`design.n_null`) flips
the sign to +0.10717 but stays non-significant (p = 0.090902,
`sensitivity.znodf.coefs.nodf_z.beta`, `.p`). Restricting to networks above 20
species per side (`design.sensitivity_min_species_per_side`) gives −0.182585 (p = 0.094235, n = 134,
`sensitivity.above20.coefs.nodf.beta`, `sensitivity.above20.n`). Weighting by
species count makes it more negative, −0.383901 (p = 0.002827,
`sensitivity.weighted_by_species.coefs.nodf.beta`). Removing pollinators first
gives −0.377425 (p = 0.0, `sensitivity.pollinators_first.coefs.nodf.beta`), and
interleaved removal gives −0.305694 (p = 0.004514,
`sensitivity.interleaved.coefs.nodf.beta`). Using the 435 local `id_network` units
(`sensitivity.local_networks.n_networks_in_file`) instead of the 175
aggregated ones leaves NODF at 0.00657 (p = 0.921158, n = 341,
`sensitivity.local_networks.coefs.nodf.beta`,
`sensitivity.local_networks.n_networks_built`). Across every specification,
richness and connectance remain positive and large; NODF is never positive and
significant.

Observed NODF averages 36.474 against a fixed-margin null mean of 37.292
(`data.mean_nodf`, `data.mean_nodf_null`); only 59 of 175 networks are more nested
than their null expectation (`data.n_nodf_z_positive`), mean z = −0.562
(`data.mean_nodf_z`).

## What this means

The proposal is a claim about which quantity carries the variance. Here
nestedness carries almost none once connectance is in the model: its apparent
protective effect is shared variance, because nested networks tend to be more
connected and less species-rich, and connectance retains the association. The
ratio formulation does not rescue the claim; it fits worse than its components and
its coefficient is negative.

Richness is not eliminated either: it retains a substantial positive partial
association, contrary to the proposal's "not by species richness". The most
accurate summary is that robustness here is associated with connectance first and
richness second, with nestedness adding no detectable independent signal. These
are observational associations among network summaries; no causal effect is
identified.

## Limits

Three limits matter most. First, the database is a compilation of
published networks, not a random sample: taxonomic, geographic and sampling-effort biases
are inherited, many networks are restricted to particular pollinator groups, 30.03%
of retained rows (`data.pct_not_identified`) are not identified to species, and records are presence/absence
after aggregation. Networks with more sampling effort will appear more connected
and more nested, so the connectance–nestedness collinearity may partly reflect
sampling. Second, NODF is sensitive to matrix size and shape: larger networks tend
to have lower NODF, and fixed-margin null standardisation does not remove that
dependence. The standardised-NODF sensitivity changes the sign of the partial
coefficient, showing how fragile the nestedness term is; raw and standardised
results should be read together. Third, removal order is arbitrary. Random
plant-first removal is one of many possible sequences; removing pollinators first,
or interleaving removals, changes the coefficients, and none represents a real
extinction sequence. Real losses may be trait-biased, abundance-biased, or
correlated across species, and an R50 average over 1,000 random orders cannot
capture that. The model is also linear and equal-weight; the largest network has
high leverage, although the maximum Cook's distance is only 0.1062
(`model.M1_joint.diagnostics.max_cooks_d`).

## What would change the answer

A size-corrected nestedness measure that is not collinear with connectance, a
design that holds connectance fixed, or a trait-based removal model could give
NODF a fairer test. If nestedness retained a positive partial association under
those alternatives, the proposal would look better. The present data cannot
distinguish "nestedness does nothing" from "nestedness matters but cannot be
separated from connectance with 175 observational networks".

## Reproducing this test

`run.py` verifies the raw hashes, prints the NODF and R50 unit checks, computes
the metrics (cached in `data/cache/metrics.json`), writes `data.csv` and
`results.json`, and draws both figures with `lib/chartlib.py`: robustness against
NODF by richness tercile, and LMG relative-importance bars. URLs, hashes and the
exclusion waterfall are in `SOURCE.md`; the criteria are in `hypothesis.md`. A
clean run takes a few minutes.

hypothesis.md

# Hypothesis and pre-specified criteria — Test 04

## The proposal, verbatim

Source: *Original Theory Notebook*, Volume XVI, entry 64, "Nestedness Buffers Loss",
published at <https://incoprea.com/research-library/original-theories-vol16-20261030/nave.html>.

> The robustness of a pollination network to species loss is set by its nestedness
> relative to its connectance, not by species richness.

## What is being tested

The proposal is a variance-partitioning claim, not a claim that nestedness is
correlated with robustness. Nestedness, connectance, richness and robustness are all
correlated with one another. The falsifiable question is which of the three
predictors retains a partial association with robustness once the other two are
controlled, and how the explained variance partitions between them.

## Data unit and filters (fixed before analysis)

- Source: Zenodo record 6630184, `network interaction data.txt` (v2, 2022-06-10).
- One network = one `id_network_aggreg` value. The file also carries `id_network`
  (local networks that may be taxon-restricted subsets or sampling slices of the
  same site); the aggregated network is the whole site community and is the
  non-redundant unit. See SOURCE.md.
- An interaction is a unique (plant taxon, pollinator taxon) pair within a network.
  Taxon labels are `family|genus|species`, the finest label in the file.
- Keep networks with **at least 10 plant species, at least 10 pollinator species,
  and at least 20 unique interactions**. No other network-level exclusion.
- All 1,000 removal orders and 500 null matrices are seeded and fixed before the
  first number is computed.

## Metrics (definitions fixed before analysis)

- **Richness** `S = P + Q`, the number of plant plus pollinator species.
- **Connectance** `C = L / (P · Q)`, `L` = number of realised links.
- **NODF** (Almeida-Neto et al. 2008), computed from the binary matrix without
  approximation: for every pair of rows with unequal degree and smaller degree
  ≥ 2, the overlap divided by the smaller degree; likewise for columns; NODF is
  the sum of all pair scores divided by the number of valid pairs, × 100.
  Row/column order is irrelevant to the value (pairs are unordered).
- **Standardised NODF** `zNODF = (NODF_obs − mean(NODF_null)) / sd(NODF_null)`,
  from 500 null matrices per network generated by a checkerboard-swap Markov chain
  with both row and column totals fixed (burn-in and thinning scale with the number
  of links; sample sd, ddof = 1).
- **Robustness `R50`** (main): plants are removed in a random order, one at a time.
  A pollinator goes extinct when it has no remaining plant partner; a plant that
  loses all its pollinator partners also goes extinct (secondary extinction). `R50`
  is the smallest fraction of the original plant community removed at which at
  least half of the original pollinator species are extinct, averaged over 1,000
  random plant orders. **AUC** is the area under the pollinator-extinction curve
  over plant-removal fraction 0–1, averaged over the same 1,000 orders (trapezoid).
  This is the standard directional robustness measure; the brief's "plants first
  then pollinators" is read as plant removals driving pollinator extinctions.
  Alternative removal regimes (pollinators first; random interleaved order over all
  species, with total species loss) are sensitivity outcomes, not the headline.

## Main model (fixed before analysis)

`M1`: OLS of `R50` on `log(S)`, `log(C)` and `NODF`, all four variables z-scored,
networks weighted equally, n = number of kept networks. Report standardised
coefficients, two-sided t p-values (df = n − 4), R², adjusted R², variance
inflation factors, the partial correlation of `R50` with `NODF` controlling
`log(S)` and `log(C)` (with its p-value, which equals the NODF coefficient's
p-value in `M1`), and LMG relative importance (Shapley decomposition over the six
orderings of the three predictors), plus each predictor's drop in R² when removed.

`M2` (the proposal's ratio specification): OLS of `R50` on `log(S)` and the raw
ratio `NODF / C`, both predictors z-scored. Report R² and standardised
coefficients. A log-ratio variant, `R50` on `log(S)` and `log(NODF/C)`, is also
reported for comparison; the pre-specified criterion 2 refers to the raw-ratio
model.
`M3` (descriptive only): `R50` on `log(S)`, `log(C)` and the raw ratio `NODF/C`,
to show how the ratio behaves when connectance is also present.

## Pre-specified SUPPORT criteria (all three must hold)

1. In `M1`, richness has no partial association with robustness:
   `|β_richness| < 0.10` **and** `p_richness > 0.05`; **and** the nestedness term
   does: `p_NODF < 0.01`.
2. The proposal's ratio model `M2` explains at least 25% of the variance in `R50`
   (`R² ≥ 0.25`).
3. The partial correlation of `R50` with `NODF`, controlling `log(S)` and `log(C)`,
   is positive with `p < 0.01` (two-sided p, sign checked).

## Pre-specified REFUTE criterion

REFUTE if richness retains the dominant partial association in `M1`: its
standardised coefficient is larger in absolute value than **both** structure terms
(`|β_richness| > |β_NODF|` and `|β_richness| > |β_logC|`) and `p_richness < 0.01`.

## Decision rule

Evaluate SUPPORT first. If SUPPORT is not met, evaluate REFUTE. If neither, the
result is PARTIAL. In particular, PARTIAL is the expected verdict if `NODF` and
connectance each carry part of the signal, because that would mean the proposal's
ratio is doing less work than its two components.

These criteria are written before any NODF, robustness or model number has been
computed and will not be changed after seeing the results.

## Required sensitivity analyses (pre-specified)

1. Replace `NODF` with `zNODF` (500 null matrices) in `M1`.
2. Restrict to networks with more than 20 species on each side, refit `M1`.
3. Weight networks by total species count instead of equally (WLS), refit `M1`.
4. Robustness under pollinators-first removal (plants are the response) and under a
   random interleaved removal order (total species loss), refit `M1` with each.
5. Rebuild the networks from `id_network` (the 435 local networks, including
   taxon-restricted subsets) instead of `id_network_aggreg`, and refit `M1` on raw
   NODF; this tests whether the network-unit choice drives the partition.

Each sensitivity is reported, whatever direction it points.

Included code and results