# Fluidity Replication: a prospective test of two Check 3 findings

**Draft 1, for Colson's approval. October 14, 2026.** Nothing has run, and no fresh start has been touched. Once
approved, this plan is fingerprinted in a lock record before any fresh start runs, and it doesn't change after that.

Colson asked for a prospective replication of two findings from Check 3 of the pilot review. It uses only the existing
oscillator model, the existing intervention methods and the existing observables.

Ground rules:

- **The records stand.** The Cause Test's FAIL stands as registered. The pilot's results and Check 3 stay exactly as
  recorded. Nothing here edits them.
- **Nothing new in the model.** No memory kernel, new scalar, adaptive coupling, biological mechanism or RGMC backlog
  concept is added. The model code is used unchanged.
- **A toy model.** It shows structure inside the model, not evidence about cells. Histories, not memory: differences
  between routes are between intervention histories and the states they leave.
- **A fair test.** The aim is to test the fluidity observations fairly, not to engineer a positive outcome. Every choice
  below is fixed before any fresh start runs.

## The two hypotheses

In Colson's words:

> **Primary hypothesis 1 — Coherence distribution.** A temporary coupling-medium intervention concentrates a larger
> share of its additional coherence among the slower, frequency-compatible oscillators than a coherence-matched direct
> phase push.
>
> **Primary hypothesis 2 — Persistence.** The slower oscillator population's contribution to naturally arising
> coherence persists more strongly over the next 100 time units than the faster population's contribution.

Check 3 found both, after the fact, on the pilot's starts 103 to 114:

- **Hypothesis 1.** The medium put 0.994 of its extra coherence in the slower half, the matched push 0.714. The
  difference was +0.279 ± 0.022.
- **Hypothesis 2.** Over the next 100 units, the slower half's coefficient was +0.380 and the faster half's +0.056.
  The difference was +0.324 ± 0.039.

Because these came from looking at the pilot's data, they can suggest but not confirm. This replication asks whether
they hold on starts that played no part in finding them.

## First check: do the existing code and saved outputs suffice?

**The code: yes, for everything that touches the model.** Nothing in the model needs to change.

| Piece | Where it is | How it's used |
| --- | --- | --- |
| The model and its step | nudge_test.py | unchanged, imported |
| Base runs with the carried gap; the medium arms; the matched push and its sham; the descriptions at R | medium_test.py | unchanged, imported |
| Check 3's measures: exact contributions, within-start slopes and coefficients, shares, error bars | check3_fluidity.py | the same measures |

**The saved outputs: no, by design.** The pilot's 12 starts are where both hypotheses came from, so they can't test
them. They are used only to check that the new code reproduces the pilot to the last digit.

**Three gaps, none of them in the model:**

1. **Fresh runs are needed.**
2. **A small new runner is needed.** medium_test.py refuses any start outside 103 to 114 (a safeguard from the pilot's
   freeze), and it must not be edited. The runner calls the same functions with the new starts and writes to its own
   folders.
3. **One recording is added.**
   - The pilot saved each arm's state at R only as summaries, including each half's own coherence. That covers
     hypothesis 1's primary statistic, which uses the same summary as Check 3.
   - The robustness check for hypothesis 1 and the exploratory composition analysis also need each arm's exact
     contributions (the slower half's, the faster half's and the free turners'), at R and every time unit after.
   - The runner records them from the same states. Recording only reads the state; it changes nothing. A check below
     confirms that every number the pilot recorded comes out identical.

Hypothesis 2 needs nothing new: the untouched base runs and their saved states at T and R, as in Check 3.

## Fresh starts

- **Starts 115 to 134 (seeds 114 to 133): 20 starts, ten moments each, 200 moments.**
  - None has been run in any test. The starts used so far are 1 to 18, 19 to 60 (the Cause Test) and 103 to 114 (the
    pilot).
  - Starts 61 to 102 stay reserved for the paused hold-vs-pulse design.
- **Moment times follow the pilot's rule and are fixed by each start's seed.**
  - T = 2,000 + 5 × (an offset from 0 to 65, drawn once per start) + 330 m, for m = 0 to 9.
  - R = T + 200.
  - They are worked out and written into the lock before anything runs.
- **Draws, all by the pilot's rules:**
  - the moment offset from (20261014, 1, seed);
  - the sham signs from (20261014, 3, seed, moment, direction);
  - the gap's direction from (20261011, seed).
- **The pilot's numbers are never pooled with these.** They set only the expected directions, the smallest effect of
  interest and the sample size.

## What stays exactly as in the pilot

| | |
| --- | --- |
| The model | Two groups of 4,000 oscillators. Natural rates spread as a Lorentzian of half-width 1, at evenly spaced quantiles. Pull within a group K = 1.9, faint link ε = 0.1, right at the threshold. No noise. The 128 oscillators per group faster than 20 turn freely. |
| The slower and faster halves | Of the 3,872 pulled oscillators in each group: the 1,936 whose natural rates are closest to the group's (within about 0.95 of the centre), and the other 1,936. |
| Numerics | Steps of 0.025: half a step of free turning, the pull by Runge-Kutta, half a step of free turning. Settle 300 units; runs of 6,000 units. The carried gap is 10⁻⁷, measured and put back every 5 units. |
| The medium | K raised or lowered by 0.5% (the pilot's frozen size, read from medium_freeze.json) for 200 units from T. Set back to exactly 1.9 at R and followed 500 more units. |
| The matched push and its sham | The pilot's procedure and tolerances (next section). |
| Moments | 10 per start, 330 units apart. Every branch ends before t = 6,000. |
| Error bars | Starts are the units. The larger of the resampled bar (400 resamples, seed 20261016) and SD/√n. Ratios take the resampled bar. |

## Coherence matching and its tolerances (unchanged)

At each moment's R, starting from the untouched state:

- **The push.**
  - Each group is taken to the medium arm's coherence at R.
  - Every pulled oscillator moves by the same amplitude times sin(group's rhythm − its phase). It moves toward the
    rhythm if the target is above the current coherence, and away if below.
  - The amplitude is the smallest one, up to a quarter turn (π/2), that reaches the target. It is found by scanning
    in 256 steps, then halving between two values until they are less than 10⁻¹² apart.
  - The push must land within a relative 10⁻⁶ of the target.
- **The sham.**
  - The same oscillators are moved by the same sizes. Their signs are paired between neighbours ranked by
    sin²(rhythm − phase), as in the Cause Test's sham, and drawn as above.
  - Each group's coherence must stay within 0.95 to 1.05 of where it was.
- **Both.** The sizes must be identical (sums of squares within 10⁻⁹), and the carried gap must be unchanged (within a
  relative 10⁻⁶).
- **Unsuccessful matches.** A push and its sham are built only if every condition holds for both groups.
  - The reasons one can fail: no move up to a quarter turn reaches the target; a solver failure; a sham out of its
    band; sizes that differ; or a moved gap.
  - If one fails, nothing is forced, clipped or replaced. The moment keeps its medium arms but drops out of every
    medium-vs-push comparison, and the reason is recorded.
  - No moment is added to make up for it.
- **Like for like.** Medium-vs-push comparisons use only the moments where both pushes (raised and lowered) and both
  shams were built. In the pilot that was 119 of 120.

## Primary statistic 1: the share gap (hypothesis 1)

This is exactly Check 3's route comparison, on the fresh starts.

1. At R of each like-for-like moment, take each half's own coherence in the four arms: medium raised, medium lowered,
   push raised and push lowered. A half's own coherence is the size of the average of e^(iθ) over its 1,936
   oscillators.
2. For each route, a half's extra is half of (raised minus lowered), averaged over the two groups. Average it over the
   start's like-for-like moments, then over the starts.
3. The slower half's share of a route's extra is slower extra ÷ (slower extra + faster extra), as a ratio of averages
   over the starts.
4. **The share gap is the medium's share minus the push's.** Its error bar is the resampled one, using the same draws
   for both routes.

- **Expected direction: positive.** Check 3 found +0.279 ± 0.022.
- **A robustness check, fixed now: the same gap from the exact contributions.**
  - Each half's exact contribution is its part of the group's coherence along the group's own rhythm. The three parts
    add up exactly to the group's coherence.
  - Check 3 noted that a half's own coherence responds only weakly to small amounts of order near the random-phase
    floor. The exact contributions don't have that limit.
  - If the exact version is clearly opposite in sign, hypothesis 1 is inconclusive. Its value is reported either way.

## Primary statistic 2: the persistence gap (hypothesis 2)

This is exactly Check 3's question 3, on the fresh starts.

1. **Natural states.** These are the untouched base run's saved states at T and at R of every moment (first copy): 20
   per start, with each group read separately, so 40 group states per start.
2. **Contributions.** At each natural state (time t), a group's coherence splits exactly into three contributions
   along its own rhythm: the slower half's, the faster half's and the free turners'.
3. **Later coherence.** This is the group's coherence |z| in the same untouched run, averaged over the 100 time units
   after t (t + 1 to t + 100, one reading per unit).
4. **The fit.** For each start, later coherence is fitted on the three contributions together by least squares. Each
   group's own average is removed first, and the two groups are pooled. The slower half's coefficient is how much of
   its contribution at t is still in the group's coherence over the next 100 units, and likewise for the faster half.
5. **The persistence gap is the slower half's coefficient minus the faster half's.** It is worked out per start and
   averaged over the starts.

- **Expected direction: positive.** Check 3 found +0.324 ± 0.039.

## How natural rises are sampled

- **Every saved natural state is used:** two per moment, at T and at R.
  - None is picked or dropped for its coherence, so nothing selects on rises or peaks.
  - A natural rise is read from how the contributions vary with coherence across these states within a start, as in
    Check 3.
- **The states' times are fixed in advance.** The seed-drawn moment schedule sets them before any run, independently
  of what the runs do.
- **They come only from untouched base runs**, which no intervention ever touches. The arms branch off copies.

## The persistence window, and overlapping observations

- **Primary window: (t, t + 100].** Later blocks, out to t + 500, are reported as descriptions only.
- **No two primary windows overlap.**
  - Within a start, natural states are 200 units apart (T to R) and then 130 apart (R to the next T). Both gaps are
    longer than 100.
  - So no natural state falls inside another state's primary window either.
- **Some other windows do overlap, as in the pilot.**
  - The later blocks overlap other states' windows.
  - The arms' 500-unit follow-ups overlap the next moment's, since moments are 330 apart.
- **Treatment.** Nothing within a start is treated as independent. Each start yields one value of every statistic,
  and all uncertainty comes from the variation between starts.

## Uncertainty, at the level of independent starts

- **Starts are independent; moments within a start aren't.** Each start is a separate run from its own random phases.
  Moments and states within a start share one trajectory.
- **Within a start**, the values are averaged over its like-for-like moments (hypothesis 1), or come from one fit over
  its 40 group states (hypothesis 2).
- **Across starts**, this is exactly the pilot's and Check 3's rule:
  - averages get the larger of the resampled bar (starts drawn with replacement 400 times, seed 20261016) and SD/√20;
  - ratios and shares get the resampled bar, with the same draws for both routes.
- **Each primary hypothesis is read on its own.** At a 3-bar line, the chance that either would pass by luck alone, if
  nothing were there, is well under 1 in 100. So no further correction is applied.

## PASS, FAIL and INCONCLUSIVE

**The smallest effect of interest is 0.10, for both gaps.**

- That is about a third of each pilot value.
- It is big enough to matter: Check 3 read a difference of 0.066 between natural rises and the medium as not clearly
  different.
- It is small enough that a real effect at half the pilot's size would pass nearly always (see Sample size).

For each gap, with its error bar:

| Verdict | Rule |
| --- | --- |
| **PASS** | The gap is in the expected direction, clear (more than 3 bars from zero) and at least 0.10. |
| **FAIL** | The gap plus 2 bars is below 0.10: there's no effect as large as 0.10 in the expected direction. This includes zero and reversed gaps. The report says which applies: reversed (clearly negative), absent, or real but smaller than 0.10. |
| **INCONCLUSIVE** | Neither of the above, or one of the conditions below fails. |

**Conditions that make a hypothesis inconclusive (never negative):**

- **Hypothesis 1:**
  - more than 1 moment in 10 (more than 20 of 200) lacks a built push-and-sham pair, as in the pilot;
  - a start has no like-for-like moment;
  - a route's extra (slower plus faster) isn't above zero, so its share isn't defined;
  - the exact-contribution version is clearly opposite in sign.
- **Either hypothesis:** a failed check (below), a file that doesn't match its recorded fingerprint, or a lock that
  doesn't match.

**No early looks.**

- While the run goes, only progress is shown: tasks finished, the time taken, and any failure with its reason.
- No number from a fresh start is printed or read until all 220 tasks are done. Then the report runs once.
- There's no stopping early and no adding starts.

## Sample size: how likely each verdict is

These estimates are rough. They use the spread between starts in the pilot (each gap's error bar times √12).

| Starts | Share gap: chance of PASS if the true gap is half the pilot's / chance of FAIL if it's zero | Persistence gap: the same | Computing |
| --- | --- | --- | --- |
| 12 | 96% / 99% | 88% / 71% | about 31 min |
| **20 (proposed)** | 99% / nearly 100% | 98% / 91% | about 52 min |
| 24 | 99% / nearly 100% | 99% / 95% | about 62 min |

- **At the pilot's full size, both gaps pass** with any of these sample sizes.
- **The persistence gap sets the size, because it's the noisier one.**
  - With 20 starts, each possibility has at least a 9-in-10 chance of a definite answer (PASS for an effect at half
    the pilot's size, FAIL for none).
  - With 12, a null would be left inconclusive about 3 times in 10.

## Secondary: delayed perturbation growth

Everything the pilot's report read about later growth is computed the same way, using the readings in the pilot's
plan.md and the benchmark of 0.1602:

- **The medium against untouched:** S, P, D_raised, D_lowered, the shape, and whether S is ruled out at half the
  benchmark.
- **The pushes** against their shams and against untouched, and the shams against untouched.
- **The medium against its matched push, like for like:**
  - the S and P differences;
  - the persistence of the raised-minus-lowered difference over (R + 200, R + 500];
  - the lasting switch.

**How they're described.** Each is set beside the pilot's value and described as one of: same sign and clear; same
sign, not clear; opposite sign, not clear; or opposite sign and clear. None of these is a PASS or a FAIL.

**The pilot's values, for reference:**

- the medium's S: +0.00303 (8.4 bars; "same direction");
- the medium-vs-push difference in S: +0.00181 (3.6 bars; "differs");
- the persistence difference: +0.052 (1.6 bars; not clear).

## Exploratory: does slower-half concentration explain the route difference in persistence?

**Can this be tested prospectively without changing the design? Only partly, so it's labelled exploratory.**

- It can be written down now, before anything runs, without changing the model, the arms or the sampling. It uses only
  the added recording.
- But it isn't a controlled comparison. "Why it stays exploratory" below explains.

**First, the difference itself.**

- In the pilot, the difference wasn't clear over the registered window, R + 200 to R + 500: medium 0.350, push 0.298,
  1.6 bars.
- Over the first 100 units it looked larger (0.877 against 0.676), but no test was fixed for it.
- So the replication first reports the medium-minus-push persistence difference in each 100-unit block after R, and
  over (R + 200, R + 500], with error bars.
- The composition question is read only in blocks where that difference is clear. Elsewhere the answer is "nothing
  clear to explain".

**Then, the analysis.** For each route, the extra (half of raised minus lowered) is split exactly into the three parts'
contributions, at every time unit after R. There are two readings:

1. **The slower half, like for like.** Does the push's slower-half extra fade as the medium's does?
   - Each part's retention in a block is its extra over the block ÷ its extra at R (a ratio of averages over the
     starts).
2. **The push, re-weighted to the medium's composition.**
   - The push's persistence is recomputed as if its extra had been divided between the parts as the medium's was:
     the medium's shares at R, times the push's own retention of each part.
   - The report gives the share of the medium-minus-push difference that this closes, with resampled error bars.

**How the readings are described:**

- **Consistent with composition** if, in a block where the route difference is clear:
  - the push's slower-half retention isn't clearly below the medium's; and
  - the re-weighting closes more than half of the difference.
- **Composition alone doesn't account for it** if the push's slower-half retention is clearly below the medium's.
- **Not clear** otherwise.

**Why it stays exploratory.**

- **Reading 2 rests on an assumption the design can't check.** It assumes each half's extra fades the same way
  whatever the other half holds.
  - In this model the halves pull on each other through the shared rhythm.
  - No arm changes the composition while holding everything else fixed.
- **The medium and the push also differ in other ways at R.**
  - The A–B timing differed: 0.37 against 0.78 radians in the pilot, raised.
  - So did how phases were arranged within each half: the phases were 0.73 radians apart, raised.
- **A controlled test would need a new arm,** such as a push confined to one half and matched in coherence. That would
  change the design, so it's left out. It could be proposed separately afterwards.
- **Hypothesis 2's natural-rise coefficients aren't used to predict the routes' persistence.** The pilot showed that
  natural rises fade much faster than either route's extra: about 0.32 against 0.68 to 0.88 over the first 100 units.
  So they can't stand in for the routes.

## Also reported (descriptions, not readings)

- **Where natural order sits** (Check 3's question 1): each part's share of the extra natural coherence, and the slower
  half against an even spread (0.484).
- **The natural share** of the extra beside the medium's and the push's (Check 3's question 2), including from the
  states at R alone and at T alone.
- **Blocks:** hypothesis 2's coefficients in all five blocks out to t + 500, and each route's persistence block by
  block.
- **Arms separately:** the raised and lowered arms against untouched, and the medium over all 200 moments.
- **The states at R**, described as in the pilot: coherence, each half, |z₂| to |z₄|, the A–B timing, and the
  medium-push phase distance.

## Numerical reproducibility checks

**Before the lock (no fresh start is touched):**

1. **The new code reproduces the pilot to the last digit, on pilot start 103.**
   - Its base run is re-run unbroken and must match the saved file exactly.
   - Moment 1 is run by both the pilot's own code and the new runner. Every number the pilot saved must be identical
     across all three versions: the two runs now and the saved file.
   - If the two codes agree with each other but not with the saved file, the machine or a library is the likely
     cause. That would be recorded and brought to Colson before going on.
2. **The added recording adds up.** In every arm and at every recorded time, the three contributions add up to the
   group's coherence within 10⁻¹². That coherence matches the saved coherence record within 10⁻¹².
3. **The mechanics, on old start 1, as in the pilot's checks:**
   - a zero change reproduces the untouched run exactly;
   - the pull is back at exactly 1.9 after R;
   - a built push lands on target, and its sham stays in band with the gap kept.
4. **The report code reproduces Check 3.** Pointed at the pilot's saved files, it must give check3_fluidity.json's
   numbers exactly. These numbers only check the code; they enter no reading.
5. **The report runs on made-up numbers** (written only to /tmp). This exercises every verdict: PASS, each kind of
   FAIL and each inconclusive condition.

**During the run:**

- Every piece first checks the lock: the plan, the code, the model files, and the pilot's freeze record and protected
  files.
- Each finished task's fingerprint is logged.
- The pull must be exactly 1.9 after R in every medium arm, and every number must be finite.
- A task that fails is re-run unchanged in the next piece; the same seed gives the same numbers. If it fails twice, the
  run stops and comes to Colson without any numbers read.
- The machine is recorded with every piece.

**At the report:** all 220 files must be present and match their logged fingerprints, and running the report twice must
give identical numbers.

## The lock

Before the first fresh start runs, one command writes replication_lock.json. It holds:

- the date and time, and the machine;
- SHA-256 fingerprints of this approved plan, the runner and report code, the model files, medium_test.py,
  check3_fluidity.py and the pilot's freeze record;
- the settings, the starts, and every moment's T and R;
- the smallest effect of interest and the verdict rules, as numbers;
- the results of the checks above;
- confirmation that no replication output exists yet.

**Rules for the lock:**

- It is refused if any replication output exists or any check failed.
- Nothing in it changes afterwards. If something had to change, it would come to Colson first. A new, dated lock would
  be labelled as a change, the old one kept, and the change reported with the results.

## Computational budget

**Measured in the pilot,** on the same machine type with 7 workers:

- a base run took about 173 s of one worker's time;
- a moment took 63 to 100 s (91 s on average);
- the pilot's 132 tasks took 32.1 minutes, in 11 pieces.

| Stage | Tasks | Worker time | Foreground time (7 at once) |
| --- | --- | --- | --- |
| Checks before the lock | 3 runs plus short checks | about 8 min | about 5 min, in 2 pieces |
| The run, 20 starts | 20 base runs plus 200 moments | about 6 hours | about 52 min, in about 18 pieces |
| The report | reads about 170 MB | | about 1 min |

**In total, about an hour of computing (allow 50 to 80 minutes).**

- **All in the foreground.** It runs in pieces of under 5 minutes, each with a hard time limit. Nothing runs in the
  background, and nothing is left running between pieces.
- **The added recording** costs about 1% more.
- **Working files** take about 170 MB in generated-artifacts/medium-test/fluidity-replication/, which is kept out of
  the project's history and the published site.
- **Other sample sizes:** 12 starts would take about 31 minutes, and 24 about 62.
- **Most of the effort** is writing and checking the code before the lock.

## What a PASS or FAIL would and wouldn't mean

- **The scope.** Each verdict is about this toy model, at this pull, size and window, with this one push method. It
  isn't evidence about cells. Differences between routes are between histories and the states they leave, not evidence
  of memory.
- **Context from established theory.** This is added for honesty, and it plays no part in the readings.
  - Both expected directions are what the standard theory of this kind of model leads one to expect.
  - Near the synchronization threshold, the slowly changing collective rhythm is carried mostly by oscillators whose
    natural rates are close to the group's (Strogatz and Mirollo, 1991).
  - Contributions from faster oscillators wash out quickly as they drift apart in phase. This is the effect called
    generalized Landau damping (Strogatz, Mirollo and Matthews, 1992).
  - A change of pull acts through that collective rhythm, while a uniform push moves every oscillator.
- **So:**
  - **A PASS** would show the pilot's fluidity observations are robust in this model and consistent with that theory.
    It wouldn't show a new mechanism.
  - **A FAIL** would be at odds with that expectation. It would be reported as a FAIL; any look at why would come
    afterwards, labelled as after the fact.
  - **Inconclusive** is never negative.

## What's left out

- **The model stays as it is.** No memory kernel, new scalar, adaptive coupling, biological mechanism or RGMC backlog
  concept is added.
- **No new interventions.** The push confined to one half stays a possible later proposal.
- **Other designs stay as they are.** Tests 2 and 3 stay separate and unapproved, and the hold-vs-pulse design stays
  paused.
- **Nothing existing changes.** That covers the Cause Test's FAIL, the pilot's results, Check 3, the pilot's files and
  freeze, cancer-research.md, map.md, the website and the Spiral Staircase pages.

## How it would run

1. Colson reviews this draft, and it's revised as needed. If it changes, draft 1 is kept word for word.
2. **First go.** Write the runner and report, run the checks, write the lock, and report back. No fresh start runs.
3. **Second go.** Run starts 115 to 134 in foreground pieces, saving each task as it finishes. No numbers are looked at.
4. **Report, once.** Every reading is reported exactly as fixed here. Anything added after seeing the results is
   labelled as after the fact.

**Where things go.**

- This plan, the code, the lock and the report stay in this folder.
- Working files (saved states and parts) go to generated-artifacts/medium-test/fluidity-replication/.
- The model's files and the pilot's files are only read.
- This folder sits inside medium-test/, so the pilot's freeze verification is unaffected.
