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

**Revision 1, October 14, 2026.** Colson approved draft 1 in principle, with 20 fresh starts (115 to 134), and asked for
two clarifications before the plan is locked. Both are made here. Draft 1 is kept word for word in plan-draft-1.md.
Nothing has run on a fresh start. Once locked, this plan is fingerprinted in a lock record and doesn't change.

What revision 1 changes:

1. **Matching, frozen** (Colson's first clarification). The coherence-matching tolerances, how an unsuccessful match is
   handled, and which moments count in each denominator are written out in full and frozen. See "Coherence matching:
   tolerances, unsuccessful matches and denominators".
2. **The threshold and the uncertainty rule** (his second). The reason for the 0.10 threshold no longer leans on the
   pilot's values, and the exact rule behind PASS, FAIL and INCONCLUSIVE is written out with examples. A result that is
   merely not significant can't be a FAIL. See "The smallest effect of interest: 0.10, and why" and "The uncertainty rule
   behind each verdict".
3. **Details fixed with the code:**
   - the commands;
   - the secondary readings, computed by the pilot's own analysis function;
   - a conservative all-moments version of hypothesis 1, reported beside it;
   - a written record of Colson's go, without which the run won't start;
   - the checks as built.

Colson's conditions, in his words: "Keep both primary hypotheses separately evaluated, preserve the existing Trust Scalar
oscillator model and interventions, and retain all previous experimental records." And: "Do not run starts 115–134
automatically after checks pass. No changes to the website, no publication, and no incorporation of the separate research
backlog."

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 and the interventions are 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.
- **Nothing leaves this folder.** No change to the website, no publication, and nothing from the separate research
  backlog.

## 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. **Each hypothesis is judged on its own**, with its own verdict.

## 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; the pilot's analysis function | medium_test.py | unchanged, imported |
| Check 3's measures: exact contributions, within-start slopes and coefficients, shares, error bars | check3_fluidity.py | unchanged, imported; the replication's report repeats its calculations step for step, with the list of starts as a setting |

**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** (replication.py, in this folder). 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 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 and shares take the resampled bar. |

## Coherence matching: tolerances, unsuccessful matches and denominators (frozen)

These are the pilot's procedure and numbers, unchanged, now written out in full. The lock records each number, and the
runner checks that its settings match them before anything runs.

**The push,** at each moment's R, from the untouched state, for each group separately:

| | Frozen rule |
| --- | --- |
| Target | The medium arm's coherence at R, for that group and direction. |
| Move | Every pulled oscillator moves by a × sin(group's rhythm − its phase); the free turners don't move. The move is toward the rhythm if the target is at or above the current coherence, and away if below. |
| Already on target | If the current coherence is within a relative 10⁻⁶ of the target, a = 0. |
| Search | a on a grid of 256 values, π/512 up to π/2. The first grid value that reaches the target and the one before it are halved between until they are less than 10⁻¹² apart; the upper end is used. |
| Tolerance | The pushed coherence must satisfy \|R_pushed ÷ target − 1\| ≤ 10⁻⁶. |
| Infeasible | No grid value up to a quarter turn (π/2) reaches the target. |
| Solver failure | A number isn't finite, or the final value misses the target by more than a relative 10⁻⁶. |

**The sham,** worked out only when both groups' pushes are solved:

| | Frozen rule |
| --- | --- |
| Sizes | Each oscillator moves by exactly the push's size (absolute values identical), and the sums of squared moves agree within a relative 10⁻⁹. |
| Signs | Paired between neighbours ranked by sin²(rhythm − phase), the Cause Test's rule, drawn from (20261014, 3, seed, moment, direction). |
| Band | Each group's coherence after the sham is within 0.95 to 1.05 times its coherence before. |

**Both, push and sham:** the carried gap's relative rms change under the move is below 10⁻⁶.

**What counts as built.** A direction (raised or lowered) at a moment is built only if every condition above holds for
both groups, for the push and for its sham. A moment is **like for like** only if both directions are built. In the
pilot that was 119 of 120 moments.

**How unsuccessful matches are handled:**

- **Nothing is retried, loosened or replaced.** There's no amplitude beyond a quarter turn, no other push method, no
  re-drawn sham signs, no clipping and no substitute moment.
- **The unbuilt direction's push and sham aren't run.** The moment's medium arms and its natural states are still run
  and used wherever no push is involved.
- **Every unbuilt direction is listed** in the report with its start, moment, direction and reason, for example "group
  B: no move up to a quarter turn reaches 0.412 x R".
- **Any selection is made visible.** The report compares the medium's raised-minus-lowered coherence difference at R
  at the moments that aren't like for like with the moments that are.

**Which moments count in each denominator (frozen):**

| Quantity | Moments counted |
| --- | --- |
| The validity rule for hypothesis 1 | All 200 planned moments. If more than 20 aren't like for like (more than 1 in 10, the pilot's rule), hypothesis 1 is INCONCLUSIVE, and so are the medium-vs-push secondary readings. |
| Hypothesis 1's share gap (primary) | The like-for-like moments only. Each start's values are averaged over its like-for-like moments, and then every start counts equally. Nothing is imputed. If a start has no like-for-like moment, hypothesis 1 is INCONCLUSIVE. |
| Hypothesis 1, conservative version (reported beside it; it doesn't decide anything) | All 200 planned moments. At a moment that isn't like for like, the push is counted as dividing its extra exactly as the medium did there, which adds no difference at that moment. This shows how much the exclusions could matter. |
| Hypothesis 2 (primary) | All 200 planned moments, always: their natural states at T and R, 40 group states per start. Natural states don't depend on matching, so none is ever dropped. |
| Secondary readings | As in the pilot: the medium against untouched uses all 200 moments; anything involving a push or a sham uses the like-for-like moments. |

## 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.
- **Which moments:** the like-for-like moments, with every start counted equally (see the denominators above). The
  conservative all-moments version is reported beside it.
- **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 (its gap plus 3 of its bars is below zero), 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.

## The smallest effect of interest: 0.10, and why

**One threshold for both gaps, fixed before any fresh data.** Both gaps are differences between fractions on the same
0-to-1 scale, so a single value can serve both.

**What 0.10 means:**

- **Share gap:** the medium puts at least a tenth more of its extra coherence (10 percentage points) in the slower half
  than the matched push does.
- **Persistence gap:** over the next 100 units, the slower half keeps at least a tenth more of its contribution in the
  group's coherence than the faster half does (coefficients of 0.30 against 0.20, for example).

**Why a tenth of the scale:**

- **It's the smallest difference that would justify the hypotheses' wording.** "A larger share" and "persists more
  strongly" describe where order sits and what lasts. A difference under a tenth of the whole would mean the two halves
  are doing nearly the same thing.
- **For the share gap, it stays clear of the measure's known limit.** A half's own coherence responds only weakly to
  small amounts of order near the random-phase floor (Check 3's caveat), so differences of a few hundredths could come
  from the measure rather than from where order sits. A tenth is well above that.
- **It isn't taken from the pilot's results.** Draft 1 also described 0.10 as about a third of each pilot value. That's
  dropped as a reason: a threshold should say what size matters, not follow the result it tests. The pilot's values
  enter only the sample-size estimates.

**A check that the threshold is workable** (a feasibility check, not part of the reason):

- With 20 starts, the expected error bars are about 0.017 (share gap) and 0.030 (persistence gap), from the pilot's
  spread between starts.
- A FAIL needs the gap plus 2 bars to be below the threshold. With a threshold below about two bars (0.06 for the
  persistence gap), a FAIL would be out of reach even with no effect at all, and every null would be left
  INCONCLUSIVE. At 0.10 both verdicts are reachable (see Sample size).

**Other thresholds can be read off.** The report gives each gap with its bounds, so anyone can see where it stands
against another threshold. Only 0.10 decides the verdicts.

## The uncertainty rule behind each verdict

**For each gap, the report computes four numbers:**

1. **The gap** itself, as defined above.
2. **Its error bar,** the estimated standard error from the spread between starts:
   - share gap: the standard deviation of the gap over 400 resamples of the 20 starts, drawn with replacement (seed
     20261016), with both routes' shares recomputed from the same resampled starts;
   - persistence gap: the larger of that resampled standard deviation of the average and SD/√20.
3. **A lower bound:** the gap minus 3 bars.
4. **An upper bound:** the gap plus 2 bars.

**What the bounds mean in confidence-interval terms.** The lower bound is a one-sided bound at about 99.9% confidence on
a normal approximation (about 99.6% with a t-distribution on 19 degrees of freedom). The upper bound is a one-sided bound
at about 97.7% (about 97% on 19 degrees of freedom). These are the conventions the pilot and the Cause Test already
used: "clear" means more than 3 bars, and "ruled out" uses 2 bars.

| Verdict | Exact rule |
| --- | --- |
| **PASS** | The lower bound is above zero, and the gap is at least 0.10. |
| **FAIL** | The upper bound is below 0.10. |
| **INCONCLUSIVE** | Neither holds, or a validity condition fails (listed below). |

- **PASS and FAIL can't both hold.** PASS needs the gap at or above 0.10; FAIL needs it below 0.10 minus 2 bars.
- **A result that's merely not significant is never a FAIL.** When the gap isn't clearly above zero, FAIL still needs
  the upper bound below 0.10. Otherwise the verdict is INCONCLUSIVE.
- **Each FAIL says which kind it is:**
  - **reversed:** the gap is clearly negative (the gap plus 3 bars is below zero);
  - **absent:** the gap isn't clearly different from zero;
  - **real but smaller than 0.10:** the gap is clearly positive (the lower bound is above zero), yet the upper bound is
    below 0.10. It counts as a FAIL because 0.10 is the smallest size that matters; the label keeps the difference
    visible.
- **The two hypotheses are judged separately.** Each gets its own verdict. There's no combined verdict, and one result
  doesn't change the other.

**Examples,** with an error bar of 0.03 unless stated:

| Gap | Lower bound (gap − 3 bars) | Upper bound (gap + 2 bars) | Verdict |
| --- | --- | --- | --- |
| +0.25 | +0.16 | +0.31 | PASS |
| +0.12 | +0.03 | +0.18 | PASS |
| +0.08 | −0.01 | +0.14 | INCONCLUSIVE |
| +0.06 (not significant) | −0.03 | +0.12 | INCONCLUSIVE, not FAIL |
| +0.02 | −0.07 | +0.08 | FAIL (absent) |
| −0.15 | −0.24 | −0.09 | FAIL (reversed) |
| +0.06, error bar 0.01 | +0.03 | +0.08 | FAIL (real but smaller than 0.10) |

The runner tests its verdict code on exactly these cases before the lock.

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

- **Hypothesis 1:**
  - more than 20 of the 200 planned moments aren't like for like, 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 (approved)** | 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 by the pilot's own analysis function in
medium_test.py, imported unchanged and given the replication's 20 starts and the 1-in-10 cap for 200 moments (20). It
uses 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)

- **Beside hypothesis 1:** the exact-contribution version and the conservative all-moments version, each with its
  error bar; the list of unbuilt directions with reasons; and the medium's coherence difference at like-for-like and
  other moments.
- **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).** Two commands: checkruns does the model runs the checks need, in one
foreground piece; checks compares the results and writes checks.txt and checks.json.

0. **The runner's settings match this plan's numbers:** every tolerance, start, moment rule, seed and size above, and
   the verdict rule.
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 in every array.
   - Moment 1 is run by both the pilot's own code and the new runner, from the saved base run. Every array 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 is non-invasive, adds up and is correct.**
   - Non-invasive: the new runner's arrays are identical to the pilot code's (check 1). On old start 1, an arm with
     the recording matches the same arm without it to the last digit, for a zero change, a changed pull, a push and a
     sham.
   - Adds up: in every arm and at every recorded time, the three contributions add up to the group's coherence within
     10⁻¹².
   - Correct: at R, the recorded contributions match Check 3's own calculation from the states 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 exactly as scheduled, and back at exactly 1.9 after the change;
   - a built push lands on target, its sham stays in band, the sizes match and the gap is kept.
4. **The report code reproduces the pilot's records.** Pointed at the pilot's saved files, the replication's report
   code must give check3_fluidity.json's numbers exactly, and the pilot's analysis function, called the way the runner
   calls it, must give pilot_results.json's readings exactly. These numbers only check the code; they enter no reading.
5. **The verdict code gives the planned verdict** in every example above and for each validity condition.
6. **The whole report runs on made-up numbers,** written only to /tmp, with some moments not like for like.
7. **Nothing earlier has changed:**
   - the pilot's freeze record verifies;
   - every file of the pilot's records is unchanged, and the pilot's saved data match their recorded fingerprints;
   - the Cause Test's lock holds.
8. **No replication output exists.**

**During the run:**

- The run won't start without the lock and a written record of Colson's go (replication_go.json), in his words.
- Every piece first checks the lock: this plan, the code, the model files, the pilot's freeze record and protected
  files, and the pilot's records.
- The numerical environment must match the one the checks ran on.
- Each finished task's fingerprint is logged.
- The pull must be exactly 1.9 after R in every medium arm, every number must be finite, and the recording must add up.
- 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 the report is computed twice
and must give identical numbers.

## The lock

After the checks pass, one command writes replication_lock.json. It holds:

- the date and time, and the machine;
- SHA-256 fingerprints of this plan, draft 1, the runner and report code (replication.py), medium_test.py,
  check3_fluidity.py, the model and helper files (nudge_test.py, cause_test.py, prelock_common.py), the pilot's freeze
  record, and checks.txt and checks.json;
- the fingerprint of every file of the pilot's records in medium-test/;
- 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, any check failed, or the plan or code changed after the checks ran.
- 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 the stand-in on old start 1 | about 7 min | about 4 min, in 2 commands |
| 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 to 2 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, and nothing from the separate research backlog comes in.
- **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.
- **Nothing is published.**

## How it runs

1. **Approved in principle** (October 14), with 20 fresh starts and two clarifications, made in this revision.
2. **First go (given October 14).** Write the runner and report, run the checks, write the lock, and show Colson the
   fingerprints and the check results. No fresh start runs, and nothing starts automatically when the checks pass.
3. **Second go (a separate authorization).** Record Colson's go in replication_go.json, then 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.

**Commands.** Each runs in the foreground with a hard limit: timeout -k 10 285 python3 -B replication.py *command*.

| Command | What it does |
| --- | --- |
| checkruns | the model runs the checks need, in one piece: pilot start 103 (its base run, and moment 1 by both codes) and the stand-in on old start 1 |
| checks | compares them; tests the report code against Check 3 and the pilot's report, and the verdict code on the examples; runs the report on made-up numbers in /tmp; writes checks.txt and checks.json |
| lock | writes replication_lock.json; refused unless every check passed and no replication output exists |
| go | records Colson's go, in his words, in replication_go.json; used only when he gives it |
| run | one piece of the run on starts 115 to 134; refused without the lock and the go record |
| report | the readings, once all 220 tasks are done |

**Where things go.**

- This plan, the code, the checks, 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.
