arco 0.6.0

Automated Research into Computational Ontologies — a platform for discovering the conditions under which computation emerges
Documentation
# Changelog

All notable changes to this project are documented in this file.

The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and version numbers follow [Semantic Versioning](https://semver.org/)
(pre-1.0: a minor version bump may include breaking changes).

## Yanked versions

**All versions prior to 0.5.0 have been yanked from crates.io.** They
exposed non-default MI estimators (`--estimator mm`, `--estimator nsb`)
with correctness bugs described under 0.5.0 below. If you depended on
one of these versions:

- If you only used the default estimator (plugin with shuffle
  correction — i.e. you never passed `--estimator mm` or
  `--estimator nsb`, and never constructed a `MetricConfig` with a
  non-default `estimator` field), your results are **not** affected
  by either bug.
- If you used `mm` or `nsb`, treat those results as unreliable and
  re-run under 0.5.0 or later.

## [0.5.0] - 2026-08-03

### Added

- `Estimator` enum (`Plugin`, `MillerMadow`, `QE`) and `MetricConfig`,
  threaded consistently through `calibrate_thresholds` and the main
  scoring loop in `run_cycle`, so calibration and observed-universe
  scoring always use the same estimator.
- `--estimator <plugin|mm|qe>` CLI flag. Default remains `plugin`.
- Miller-Madow bias-corrected entropy/MI estimator (`src/metrics/mm.rs`).
- Quadratic extrapolation (QE) bias-corrected MI estimator
  (`src/metrics/qe.rs`), following Strong, Koberle, de Ruyter van
  Steveninck, Bialek (1998).
- `src/metrics/` split into focused submodules: `entropy`, `mm`, `qe`,
  `persistence`, `separation`, `shuffle`, `storage`.

### Fixed

- **Miller-Madow formula.** The MI correction term used
  `(m_x - 1)(m_y - 1) / (2N ln 2)`, where `m_x`, `m_y` are the number
  of *observed* distinct values — the degrees-of-freedom term for a
  fully dense contingency table. The standard correction for mutual
  information is `(K_xy - K_x - K_y + 1) / (2N ln 2)`, where `K_xy` is
  the number of *observed* joint pairs. The two are only equal when
  every possible (x, y) combination has been observed. In the
  undersampled, large-alphabet regime this crate operates in, the old
  formula massively over-corrected — on the graph substrate
  (4096-symbol alphabet) it drove hypothesis survival to 0/10 across
  all seeds. Fixed to use the standard formula; graph-substrate MM
  survival is now 10/10, in line with plugin and QE.
- **QE subsampling independence.** The subsampling RNG seed was
  derived from the caller-supplied `seed` alone. `storage()` passes
  `config.seed + delta`, identical for every universe scored at a
  given timescale — so every distinct dataset sharing a sequence
  length received the *same* "random" subsample rather than an
  independent draw, undermining the extrapolation's statistical
  basis. Now derives the subsampling seed from a hash of the actual
  `(x_seq, y_seq)` content combined with the caller's seed, so
  distinct datasets get independent draws regardless of what seed the
  caller passes; identical inputs remain fully reproducible. Also now
  averages `N_RESAMPLES = 3` independent subsamples at each fraction
  below 1.0, rather than a single arbitrary draw. Graph-substrate
  survival under this estimator went from 9/10 to 10/10; cross-
  estimator agreement (plugin / MM / QE) tightened from within 3
  points to within 2 points across both substrates and all 10 seeds.

### Changed

- **`Estimator::Nsb` renamed to `Estimator::QE`** (`--estimator nsb`
  is now `--estimator qe`). The implementation is Quadratic
  Extrapolation (Strong et al., 1998), not the Nemenman-Shafee-Bialek
  estimator (Nemenman, Shafee, Bialek, 2002) it was previously
  labeled as and cited against. This crate does not implement NSB.
  Do not cite results computed with this estimator as NSB.

## Prior to 0.5.0

Not individually documented — see "Yanked versions" above.