← All experiments

Field notes / Experiment guide

Persistent shape or genuinely rough coastline?

The ant’s outer edge is broader than the rotor’s. Is that a slowly changing large-scale shape, or shorter-wavelength roughening?

New to these ants? Start here.

An ant moves on a grid of coloured squares. Each colour tells it to turn left (L) or right (R). It advances that square to the next colour, then steps forward. A rule such as RLR is the list of turns, starting at colour zero. On a blank grid the same rule always makes the same trajectory.

Territory means every cell visited so far. Its boundary consists of visited cells with an unvisited neighbour. A highway is a repeating pattern of motion that carries the ant away. A tether means repeated returns to a small home region.

Growing like the cube root of time means taking eight times as many steps to double a linear size. The rotor walker is a comparison model that follows and rotates arrows stored on cells. A seed makes a random starting pattern reproducible; the ant itself can still move deterministically.

We distinguish c, the chance of discovering a cell per boundary step, from kappa (κ), time at the boundary normalized by perimeter divided by area. Explaining their values is harder than using them to account for growth.

The idea under test

Separating low and high angular modes, with radius-matched controls, should distinguish those explanations.

What we learned

Calibration and a bounded pilot validate acquisition and expose sparse angular bins. The full scientific comparison remains pending.

What this leaves open

The pilot is too small for the registered control count. It cannot decide between the competing roughness explanations.

Read the evidence and reproduction recipe ↗

Inside the experiment

Methods, registered predictions, exact commands and saved analysis. These are the working research documents; expand them for the detail behind the introduction.

Methods and original experiment record

Hull checks: persistent shape or local roughening?

Registered 2026-10-15 21:36 NZDT, base da88e61 with a dirty working tree, before new measurements. Requested by the user as “an experiment for Hull checks”. This follows the hull-width correction and research avenue 5.

Question and hypotheses

Does the ants' wider coastline survive removal of persistent global shape and comparison with rotors of the same radius? H-shape predicts that the gap is mostly in persistent low modes; H-local predicts a residual excess at shorter wavelengths. The decay of normalised power is not independent evidence: it already contains W/R scaling. No universality-class claim follows from this test.

Registered design

Instrument: examples/hull_checks.rs, a frozen copy of hull_width.rs with full-precision 512-bin outermost-visited-cell profiles appended, every integer k rather than every second k. This definition can miss overhangs; it is not the same observable as surface-cell Wout. Keep both. Exterior remains 4-connected.

Full cohort: six original A4 rules, plus 12 rules selected from the frozen unresolved_le10.txt pool by ascending SHA-256 of 20261015:RULE, excluding the six originals. This is a sample of unresolved rules, not certified chaotic rules. No growth-based selection after inspection. Ant patch seeds 331–334; rotor seeds 331–342. Ant checkpoints k=24..30, rotor k=24..32, grid 8192. All profiles and escapes retained; no replacement of failed or escaping rules. Profile validity requires all bins populated. Pilot uses RLR, RLRLRRRLLR and rotor, seeds 331–332, k=16..20, grid 1024; it tests plumbing only.

Fixed definitions (r in cells, theta equally spaced): remove modes 0..2 for the primary residual; split modes 3..8 (shape), 9..64 (local), and 65..256 (resolution diagnostic). Use correct single weighting of the Nyquist mode. Report absolute band variance and variance/rbar² separately. Report S(lag)=mean[(h(theta+lag)-h(theta))²] for h containing modes 9..64, lags 1,2,4,8,16,32,64,128. Correlation length = first lag whose S reaches the local variance (half the decorrelated plateau); report missing crossings. Physical separation = 2pirbar*lag/512. This angular-profile estimator is calibrated on synthetic modes, not assumed to be an interface exponent.

For each ant checkpoint match each rotor seed to its nearest radius in log space, requiring |log(Rrot/Rant)| <= log(1.10); ties choose smaller k. At least 8 rotor seeds must match; otherwise mark unmatched, with no extrapolation. Compare with the median of matched rotor seeds. Unit of inference: median over seeds within a rule, then rules. Report rule spread and between-seed sd; bootstrap rules (2000 draws, seed 20261015) for 95% intervals of median ratios. Repeated checkpoints are not independent replicates. Temporal persistence is the real complex inner product of band coefficients at consecutive k, divided by their norms, in the centroid/laboratory angular frame; do not rotate to fit. The same mode split on pairwise-max-coarsened 256-bin profiles checks resolution.

Predictions and decision rules (do not rewrite)

  1. Calibration: pure m=4 lies wholly in shape; pure m=32 wholly in local; Parseval and the exact sinusoidal structure function agree to 1e-10 relative tolerance. A Nyquist-only contour has the correct variance. Failure blocks biological/geometric interpretation. No finite-window rotor exponent is imposed.
  2. H-shape: at k=28,29,30 the rule-median matched ratio of local variance is <=1.25, while the shape ratio is >=2.0; at least 80% of eligible rules agree.
  3. H-shape persistence: median adjacent-k shape correlation is >=0.7 and exceeds local correlation by >=0.2 for ants over k=26..30.
  4. H-local alternative: local ratio >=1.5 at k=28,29,30 with bootstrap lower bound >1, in at least 80% of eligible rules, and local-variance ratio changes by <=20% on coarsening. Otherwise the evidence is mixed/unresolved.
  5. Radius matching: >=80% of ant rows at each late k have >=8 matched rotors. Resolution: local variance changes by <=20% in >=90% of valid late profiles. Either failure prevents choosing H-shape or H-local. Report original and sampled cohorts separately. Insufficient valid sampled rules (<8) also blocks a census-sample conclusion. Predictions 2 and 3 both required for H-shape.

Correlation lengths and their log-log slopes against radius over k=26..30 are descriptive checks, per run, with between-seed spread; no fitted power law will be labelled stable from this short window. Results cannot establish causation.

Reproduction (WSL from repo root)

export UV_PROJECT_ENVIRONMENT=$HOME/.venvs/turmite UV_LINK_MODE=copy
export CARGO_TARGET_DIR=$HOME/turmite-target
cargo test --release
cargo test --release --example hull_checks
cargo build --release --example hull_checks
cargo build --release --example hull_width
uv run experiments/2026-10-15-hull-checks/scripts/checks.py
uv run experiments/2026-10-15-hull-checks/scripts/validate.py
uv run experiments/2026-10-15-hull-checks/scripts/run.py --pilot
uv run experiments/2026-10-15-hull-checks/scripts/analyse.py --pilot
# Full job (background; per-spec checkpoints and .done markers):
nohup uv run experiments/2026-10-15-hull-checks/scripts/run.py > experiments/2026-10-15-hull-checks/results/run.log 2>&1 &
uv run experiments/2026-10-15-hull-checks/scripts/analyse.py

run.py records commands, seed/spec cohort, input/source hashes, git commit and dirty status; validates resume hashes before skipping. Each completed spec is atomic and checkpointed separately; an interrupted spec restarts from t=0. No state-level restart within a spec. Full measurement outputs are small CSVs under this experiment's results; no previous experiment results are overwritten.

Status

Prepared and pilot-validated 2026-10-15. Full science run not started; the commands above are ready. No scientific prediction has been evaluated by the pilot.

Validation results (2026-10-15; registration unchanged)

  • scripts/checks.py → results/calibration.json: all synthetic controls pass.
  • scripts/validate.py → results/validation.json: nine matched legacy rows identical, and byte-identical exporter output under 1 versus 6 Rayon threads.
  • scripts/run.py --pilot then scripts/analyse.py --pilot → results/pilot/: six complete runs, 30 checkpoint rows; 10 valid angular profiles and 20 explicitly excluded for empty bins. No files missing. Two rotor seeds cannot satisfy the eight-control matching requirement.
  • Repeating scripts/run.py --pilot → results/resume.log: six skips with output SHA-256 checked before skipping. No results overwritten.
  • cargo test --release → results/release_tests.log: passed. The new example's square-with-holes oracle passed separately (cargo test --release --example hull_checks).
  • notebook.ipynb executed top to bottom with uv run --with nbconvert --with ipykernel --with nbformat jupyter nbconvert --to notebook --execute --inplace experiments/2026-10-15-hull-checks/notebook.ipynb (results/notebook.log).

The sparse-bin exclusions in this early pilot motivate enforcing the registered coverage gate, not interpolation. Full runs begin at k=24. Hashes and dirty-tree state are in the pilot manifest; working outputs have not been committed.

Analysis notebook: notebook.ipynb

2 saved outputs · 2 code cells. Cells are not executed during publication. Download notebook

Hull checks: persistent shape or local roughening?

Question and why it matters

Does the wider ant hull reflect persistent shape or shorter-wavelength variation? The registered README fixes hypotheses before measurement. See also research avenue 5. This write-up covers calibration and the bounded pilot. The full run is pending.

Assumptions and definitions

The outermost visited-cell radius in each of 512 angular bins can miss overhangs. The exterior is 4-connected. These are definitions, not validated physical-interface assumptions. The unresolved census sample is not certified chaotic. Modes 3–8 are the registered shape band, 9–64 the local band. Coarsening tests resolution.

Provenance

Inputs below live in results/ and are intended to be committed with this experiment. They are currently uncommitted working outputs. No raw dumps are read.

Code
In [1]:
from pathlib import Path
import hashlib, json
SEED = 20261015
root = next(p for p in (Path.cwd(), *Path.cwd().parents) if (p/'Cargo.toml').exists())
exp = root/'experiments/2026-10-15-hull-checks'
res = exp/'results'
manifest = json.loads((res/'pilot/manifest.json').read_text())
analysis = json.loads((res/'pilot/analysis.json').read_text())
print('producing commit:', manifest['commit'], '(dirty tree recorded in manifest)')
print('registered date: 2026-10-15 NZDT; seed:', SEED)
paths = [res/'calibration.json', res/'validation.json', res/'pilot/manifest.json', res/'pilot/analysis.json']
paths += sorted((res/'pilot').glob('*.csv'))
for p in paths:
    assert p.exists(), p
    print(p.relative_to(root), hashlib.sha256(p.read_bytes()).hexdigest())
producing commit: da88e61b690507526ba4e2a2c017d9c7941beb91 (dirty tree recorded in manifest)
registered date: 2026-10-15 NZDT; seed: 20261015
experiments/2026-10-15-hull-checks/results/calibration.json ea4a7ca36dc049863820e1af733e4b694a4eec1cff290b1ca72d900c43853e39
experiments/2026-10-15-hull-checks/results/validation.json f8de4a35cff07bc6d8472269de610ccde477b554275a36a3fc726337cc747f52
experiments/2026-10-15-hull-checks/results/pilot/manifest.json 91512baa1ff6e9099bf8a221f79815ebb7e75a39b96b98443c274408e2933c0b
experiments/2026-10-15-hull-checks/results/pilot/analysis.json d8dc3f7938c9f9fdd39b301e4dbab868b2a0f20d903f849416b5154355791647
experiments/2026-10-15-hull-checks/results/pilot/RLRLRRRLLR_331.csv d97a3b79e97bec49c8674562c781be1b008c6ebce3adaf492a540f095c37514a
experiments/2026-10-15-hull-checks/results/pilot/RLRLRRRLLR_332.csv 4665a6c2214419d4ca798d2328a921fc7961f30f2b6b870f131e59fdb844e661
experiments/2026-10-15-hull-checks/results/pilot/RLR_331.csv 8322d06e995d378c8941a63b2725d5502e4c3a41d94c389dd50998359a405735
experiments/2026-10-15-hull-checks/results/pilot/RLR_332.csv d6d4f7c2f6e19f945d5a79d93f46350645df2efee90322943827227582a018ff
experiments/2026-10-15-hull-checks/results/pilot/rotor_331.csv e50dbe47655a44b2a5f1530a53bda45d0dab4a0d8c9563a82bf3000d6735cc2a
experiments/2026-10-15-hull-checks/results/pilot/rotor_332.csv 76668439a58b856e805f7cb5cf606df678a9a35459a6bd141ab0c4122c2ffbb1

Data and method

Heavy computation is in examples/hull_checks.rs and scripts/run.py. The pilot consists of two ant rules and one rotor, each at seeds 331 and 332, k=16..20. It checks acquisition, exclusions and analysis. It has insufficient rotors for the registered minimum of eight radius matches and cannot test H-shape/H-local.

Results

Code
In [2]:
for name in ('calibration.json', 'validation.json'):
    d = json.loads((res/name).read_text())
    print(name, d['status'])
print('Valid profiles:', len(analysis['profiles']))
print('Excluded profiles/escape records:', len(analysis['exclusions']))
print('Missing files:', analysis['missing_files'])
print('Exclusion reasons:')
for s in analysis['exclusions']: print(' ', s)
print('Decisions:', {k:v['decision'] for k,v in analysis['verdicts'].items()})
calibration.json PASS
validation.json PASS
Valid profiles: 10
Excluded profiles/escape records: 20
Missing files: []
Exclusion reasons:
  RLRLRRRLLR@331 k=16: 7 empty bins
  RLRLRRRLLR@331 k=17: 7 empty bins
  RLRLRRRLLR@331 k=18: 2 empty bins
  RLRLRRRLLR@332 k=16: 14 empty bins
  RLRLRRRLLR@332 k=17: 4 empty bins
  RLRLRRRLLR@332 k=18: 6 empty bins
  RLR@331 k=16: 10 empty bins
  RLR@331 k=17: 5 empty bins
  RLR@331 k=18: 4 empty bins
  RLR@331 k=19: 2 empty bins
  RLR@331 k=20: 1 empty bins
  RLR@332 k=16: 19 empty bins
  RLR@332 k=17: 6 empty bins
  RLR@332 k=18: 2 empty bins
  RLR@332 k=20: 1 empty bins
  rotor:331 k=16: 7 empty bins
  rotor:331 k=17: 1 empty bins
  rotor:331 k=18: 1 empty bins
  rotor:332 k=16: 3 empty bins
  rotor:332 k=17: 2 empty bins
Decisions: {'legacy': 'pilot only', 'sampled': 'pilot only'}

The estimator calibration passes and the pilot retains populated profiles while listing sparse-bin failures explicitly. This validates plumbing; it does not show whether the ants' residual hull fluctuations exceed matched rotors.

Caveats and controls

The small pilot has sparse angular bins, so invalid profiles must not be silently interpolated. Synthetic controls check mode assignment, Parseval including Nyquist, the exact sinusoid structure function and persistence of lobes versus orthogonal local modes. Compatibility validation checks nine original-instrument rows and byte equality with one versus six Rayon threads. The resume log records six skips. The full run uses absolute power, matched radii and bin coarsening, addressing the normalisation problem in the earlier hull analysis. No scientific prediction has been tested by this pilot.

What this changes / next steps

Run the registered full cohort and evaluate the matching/resolution gates before interpreting either hypothesis. The pilot demonstrates a reproducible instrument. No new empirical claim about asymptotic roughening is warranted.

Open questions

Do low modes persist? Is there residual local excess at equal radii? Does the estimated correlation length have adequate resolution and a reproducible scaling? The unresolved-rule sample may contain transient builders or highways.

Read the dated lab log

Lab notebook: hull checks

2026-10-15 21:36 (+13:00) · da88e61 · intent

User requested an experiment for Hull checks. Implement the registered follow-up to hull-width and research avenue 5: profiles, matched radii, shape/local split, persistence and resolution controls. Keep all existing working material intact. Read experiments/README.md, hull-width README including its correction, and notes/paper-gaps-research-avenues-2026-10-15.md before registering the design.

2026-10-15 21:36 (+13:00) · da88e61 · assumption

The unresolved census pool is useful for sampling candidates, but is not a certificate of chaos. The angular maximum misses overhangs and depends on bin size. Test resolution explicitly; retain incomplete and escaping runs. Neither contour calibration nor matching guarantees a physical interface interpretation.

2026-10-15 21:36 (+13:00) · da88e61 · decision

Run a bounded pilot before starting a large sweep. WSL was inaccessible in the sandbox; the permitted WSL invocation works outside it. No dependency changes.

2026-10-15 21:42 (+13:00) · da88e61 · observation

Commands in README completed: scripts/checks.py passed all synthetic controls; scripts/validate.py matched nine legacy rows and one/six-thread output exactly. scripts/run.py --pilot and scripts/analyse.py --pilot produced six complete runs, 30 checkpoint rows, 10 valid profiles and 20 empty-bin exclusions in results/pilot/. Repeating the pilot verified the six hashes and skipped all jobs (results/resume.log). cargo test --release passed (results/release_tests.log); the new example oracle passed separately. notebook.ipynb executed from a clean kernel via the exact uv/nbconvert command in README (results/notebook.log).

2026-10-15 21:42 (+13:00) · da88e61 · interpretation

The pilot validates acquisition and explicit sparse-bin handling. It does not test any scientific prediction: the early contours are sparsely binned and only two rotor seeds were run. Full-cohort matching and resolution gates remain untested. No hypothesis was revised after the pilot. No previous results were changed.

2026-10-15 21:42 (+13:00) · da88e61 · decision

Experiment preparation is complete. Leave the full registered sweep unstarted; this session addressed the request to set up an experiment and ran a bounded pilot. The README contains the background full-run command and analysis command. Next: run the full cohort, enforce coverage/resolution gates, then report original and sampled cohorts separately. Working outputs are uncommitted, as requested by the repository convention. Cross-cutting pointer: notes/hull-checks.md.

2026-10-15-hull-checks · Source revision ba38590b33e3

Original source ↗ · Input hashes

Introductions summarize the evidence; the expandable record preserves the original predictions, methods and caveats. Figures and notebooks are published as saved. Publication runs no simulations or notebook cells.