Field notes / Experiment guide
Matching size without reusing the same trajectory
Could the excursion-cutoff association be an artefact of estimating area and both compared quantities from the same ant runs?
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.
A closer look

The idea under test
Splitting seeds into independent roles should preserve the association if shared-trajectory noise is not its whole explanation.
What we learned
The registered concordance and interval criteria hold at both tested windows after separating the seed roles.
What this leaves open
This reuses selected rules, rather than validating on new ones. Noisy area matching, escape exclusions and the earlier reliability failure remain limitations.
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
Independent-area test of the excursion-cutoff association
Registered 2026-10-15 21:12 +13:00, base da88e61 (dirty tree), before analysis.
Question: does higher kappa still predict shorter extreme excursions when the
area used to match rules comes from independent trajectories?
Input: committed ../2026-10-14-t1-excursion-tomography/results/t1b_cutoff_seeds.csv.
Reuse k=22,25, exclude escaped windows. Partition seeds by seed modulo 3;
require >=2 surviving seeds in each group for each rule/window. Use all six
permutations assigning groups to area, kappa, and ln(L999/R). Match rule pairs
with |difference in mean ln A| <=0.05, sensitivity 0.10. Each permutation has
equal weight; statistic is mean fraction of pairs with opposite signed kappa
and cutoff differences. Report all six fractions and counts. No z selection.
Bootstrap rules (2000, seed 20261015), keeping roles and windows together;
pair weights are products of rule multiplicities. Overlapping pairs are not
independent observations. Report between-rule-bootstrap uncertainty.
Prediction: at tolerance 0.05, mean concordance >=0.65 and bootstrap lower 95% bound >0.5 at BOTH windows. If not, independent-area replication fails; do not proceed to a transplant on this evidence. Fewer than 20 rules or any role with <20 pairs makes that window inconclusive. Passing supports an association, not a mechanism or causality. Matching noisy area does not hold true area fixed; disjoint seeds remove shared-trajectory selection only.
Instrument calibration: this is a new association estimator, not a growth fit. Before ant analysis run synthetic rule-level null and negative-association controls (44 rules, 3 groups, 200 independent datasets, seed 20261015): null mean within 0.05 of 0.5, negative-association mean >0.8. Synthetic area independent of predictors; this checks signs and role handling, not biological confounding. No new rotor/random-walk growth estimates are made.
Command (WSL, repository root):
export UV_PROJECT_ENVIRONMENT=$HOME/.venvs/turmite UV_LINK_MODE=copy; uv run experiments/2026-10-15-independent-area/scripts/analyse.py
Outputs: results/analysis.json (full hashes, commit, controls, per-role results).
No new simulations. No existing results overwritten.
Results — 2026-10-15 21:18 +13:00
Registered prediction held at both windows, 44 rules retained at each.
At tolerance 0.05, concordance is 0.730 (rule-bootstrap 95% 0.605–0.842)
at k=22 and 0.757 (0.617–0.881) at k=25. At tolerance 0.10 it is
0.694 (0.573–0.799) and 0.728 (0.603–0.845). All six role assignments
meet the 20-pair requirement. Null synthetic mean 0.497; negative-association
control 0.957, both passing the registered calibration gates.
Numbers, individual assignments and hashes: results/analysis.json, command above.
This rejects shared-trajectory area selection as a sufficient explanation of the observed concordance. It does not establish that cutoff determines kappa: matching uses noisy area, the rules were previously selected, escapes are excluded, and k=22 and k=25 are repeated windows of the same trajectories. Confidence intervals are marginal per window, not independent replications or a joint CI. Implementation clarification: rule resampling is joint over all six role assignments within each window; bootstrap draws differ between windows. No cross-window statistic or confidence interval is estimated.
What changes: retain the cutoff as a credible rule-level lead despite the failed earlier noise-floor gate; that gate is not retroactively passed, and no transplant is justified by this analysis alone. Next discriminating test: new matched-area trajectories with direct tail measurements and a powered intervention designed around the residual kappa effect, rather than more pairwise correlations. These results reuse old simulations and are not fresh rule validation.
Verification
cargo test --release passed; log results/cargo-test.log (base commit above).
The analysis reran byte-identically: output SHA-256
737ad21e7495302cfc70176a60b7adb4d6a86c3136db8bc521962fcaaeebf610.
The shareable notebook executed from a clean kernel:
uv run experiments/2026-10-15-independent-area/scripts/make_notebook.py
uv run --with nbconvert --with ipykernel --with nbformat jupyter nbconvert --to notebook --execute --inplace experiments/2026-10-15-independent-area/notebook.ipynb
Run in WSL with the environment exports above. No dependency declarations changed. Results are uncommitted pending user request, as repository policy requires.
Analysis notebook: notebook.ipynb
2 saved outputs · 2 code cells. Cells are not executed during publication. Download notebook
Independent-area replication
Question and why it matters
Does the excursion-cutoff association survive area matching from separate seeds? See registration and scientific context.
Assumptions and definitions
Seed modulo 3 defines three disjoint trajectory groups. At least two surviving seeds per group are required. Independence between seeds is assumed, not tested. Matching noisy area does not fix true area; escaping trajectories are excluded.
Provenance
Inputs are small results files; no dumps are read.
Code
import hashlib, json, subprocess, datetime
from pathlib import Path
SEED = 20261015
ROOT = next(p for p in [Path.cwd(), *Path.cwd().parents] if (p / 'Cargo.toml').exists())
EXP = ROOT / 'experiments/2026-10-15-independent-area'
INPUTS = [EXP / 'results/analysis.json', ROOT / 'experiments/2026-10-14-t1-excursion-tomography/results/t1b_cutoff_seeds.csv']
print('git', subprocess.check_output(['git','rev-parse','HEAD'], cwd=ROOT, text=True).strip())
print('UTC', datetime.datetime.now(datetime.timezone.utc).isoformat(), 'seed', SEED)
for p in INPUTS:
print(p.relative_to(ROOT), hashlib.sha256(p.read_bytes()).hexdigest())
d = json.loads(INPUTS[0].read_text())
assert hashlib.sha256(INPUTS[1].read_bytes()).hexdigest() == d['input_sha256']
print('Producing commit', d['commit'], 'command', d['command'])
Data and method
Reuse k=22 and 25, excluding escapes. All six permutations assign separate groups
to area matching, kappa and cutoff. Average the six concordance fractions equally.
Bootstrap rules 2000 times with seed 20261016; never bootstrap pairs independently.
Heavy analysis: scripts/analyse.py. The bootstrap seed is analysis seed + 1.
Results
Code
print('Synthetic controls:', d['controls'])
for r in d['windows']:
print('k', r['k'], 'tolerance', r['tolerance'], 'rules', r['n_rules'],
'concordance', round(r['concordance'], 3),
'CI', [round(x, 3) for x in r['bootstrap95']], r['verdict'])
print('Role pair counts:', [x['pairs'] for x in r['roles']])
The registered concordance threshold and interval criterion hold at both windows. This does not establish causality or constitute validation on new rules.
Caveats and controls
Synthetic null and negative-association controls pass. They calibrate signs and role handling, not scientific confounding. Area is noisy, rules are selected, and escape exclusion can select outcomes. Windows share trajectories; intervals are marginal. No rotor or random-walk growth estimator was changed.
What this changes / next steps
The shared-trajectory area-matching confound cannot suffice to explain this signal. The earlier seed-noise gate remains failed. Next obtain new trajectories matched in size and design an intervention with power for the small residual effect.
Open questions
Does the association persist at truly fixed area? Is the cutoff causal, or a second response to an unmeasured property of the field?
Read the dated lab log
Lab notebook
2026-10-15 21:12 (+13:00) · da88e61 · intent
User asked to move the science forward. Test the unclosed area-selection confound of the matched-area cutoff association with independent seed groups. Prediction and estimator registered in README before executing code.
2026-10-15 21:12 (+13:00) · da88e61 · assumption
Seeds are independent patched starts, and two surviving seeds per role provide a noisy but meaningful rule mean. Excluding escapes can select trajectories; the design cannot remove that bias. Six role assignments share rules and seeds, so bootstrap rules jointly, never treat assignments or pairs as replicates.
2026-10-15 21:18 (+13:00) · da88e61 · observation
Ran uv run experiments/2026-10-15-independent-area/scripts/analyse.py via WSL.
results/analysis.json: synthetic null 0.497, association control 0.957;
44 rules/window; registered concordance 0.730 [0.605,0.842] at k=22,
0.757 [0.617,0.881] at k=25. Both pass. Tolerance 0.10 also passes.
Initial sandboxed WSL invocation failed with access denied; elevated WSL succeeded.
2026-10-15 21:18 (+13:00) · da88e61 · deviation
Clarification of registration: bootstrap assignments are kept together within a window; independent draws are used for the two marginal window intervals. No joint-window inference is made. The retained rules are the same at both windows.
2026-10-15 21:18 (+13:00) · da88e61 · interpretation
Shared-trajectory matching does not suffice to explain the association. Noisy area, previous rule selection and escape conditioning remain possible confounds. Earlier failed noise-floor gate remains failed; this does not authorize a mechanistic claim. Need independent trajectories at matched size and a powered intervention; this analysis alone cannot say whether the cutoff causes growth.
2026-10-15 21:22 (+13:00) · da88e61 · decision
Analysis complete. cargo test --release passed (results/cargo-test.log).
Reran the registered analysis byte-identically, output SHA-256
737ad21e7495302cfc70176a60b7adb4d6a86c3136db8bc521962fcaaeebf610.
Generated the notebook with uv run experiments/2026-10-15-independent-area/scripts/make_notebook.py
and executed it with uv/nbconvert from a clean kernel (command in README).
Scientific notes updated; no commit made. Next step is prospective matched-size
data and intervention design, not another reformulation of these same pairs.