A4-TOKENS: do layout-free tokens let the cartoon survive pass 2?
Work package A4-TOKENS of the SGH programme (operations/research/sgh-program-20260908/PLAN.md),
8-9 September 2026. One spot A100 (slot a), 110 generations, 0 failures. Slot d (F2 training)
was never touched; slots b and c were not used. Nothing was committed to git.
Engineering evidence only. Every instrument below measures shape, spacing, texture, colour or one pathology encoder. None of them diagnoses, grades or stages anything, no pathologist has seen any of it, and nothing here is "solved". Every "better" or "worse" names its instrument and its n.
One-sentence answer: the hypothesis is refuted. At start_index 3 not one of the five
layout-free arms beats the single-real-donor arm on cartoon lumen IoU — every arm sits at
0.041-0.051 against a single-donor 0.051 and a cartoon ceiling of 0.625 — and the three arms whose
tokens no longer depend on the cartoon collapse to producing one image five times (within-arm
pairwise SSIM 0.98 against 0.03-0.05 for real fields). The run also produced the control that
explains why: at si3 five different start images conditioned on the same tokens are 0.98-similar,
while one start image under five different token sets is 0.60-0.65 similar — the pass-2 canvas is
decided by the conditioning tokens, and the start image contributes almost nothing. Removing the
donor's spatial arrangement does not hand layout control back to the start image; it removes the
last thing that differed between cartoons.
0. What was built and run
| deliverable | path |
|---|---|
| generator, two new token sources | code/pixcell_generate.py (781 lines; was 667) |
| CPU tests, 11 of them | code/test_generate_cpu.py (768 lines; was 576) |
| manifest writer | code/make_a4_jobs.py |
| manifests, 10 + 100 jobs | jobs/a4-pass1.json, jobs/a4-pass2.json |
| fleet package | packages/a4/ (code/, jobs/, worker.sh, donors.json, STAGE_LIST, MANIFEST-ORDER.txt) |
| merged records, 110 | packages/a4/retrieved/records.jsonl + coverage.json |
| retrieved outputs, 110 PNGs, 1.63 GB | packages/a4/retrieved/out/a4/pass{1,2}/<category>/ |
| the exact VM cartoons + label maps the generator saw | packages/a4/retrieved/aux/cartoons-vm/a1/ (30 files) |
| merge + verification script | packages/a4/merge_records.py |
| A4 measurements | packages/a4/analyse_a4.py |
| harness output | packages/a4/eval/features.csv, scores.csv, screen-embed.csv, screen-ncc.csv, copy-margin.csv, stage-*.json |
| A4 tables | packages/a4/eval/a4-table.csv/.json, a4-paired-vs-a1.csv, a4-layout-iou.csv, a4-layout-iou-ceiling.json, a4-within-arm-ssim.json, a4-headline.json |
| contact sheets | packages/a4/eval/sheets/a4-{intestinal_metaplasia,hpylori_gastritis}.png and four a4-zoom-* |
Commands, in order, all from the programme root
(P=../../../research/sgh-synthetic-histopathology/.venv/bin/python):
$P code/test_generate_cpu.py # 11/11
python3 code/make_a4_jobs.py # 110 jobs, verified against a1
cd fleet && ./fleet.sh up a && ./fleet.sh stage a ../packages/a4
./fleet.sh ssh a "... ln -s <slot0>/{cartoons/a1,token-library,token-stats} ..."
./fleet.sh launch a ../packages/a4 a4-pass1 a4-pass2 && ./fleet.sh watch a
./fleet.sh retrieve a <abs>/packages/a4/retrieved && ./fleet.sh down a
cd .. && python3 packages/a4/merge_records.py
$P packages/sweep-v1/evaluate_sweep.py features --records packages/a4/retrieved/records.jsonl --out packages/a4/eval --jobs 12
$P packages/sweep-v1/evaluate_sweep.py screens --records packages/a4/retrieved/records.jsonl --out packages/a4/eval --jobs 12
$P packages/sweep-v1/evaluate_sweep.py sheets --records packages/a4/retrieved/records.jsonl --out packages/a4/eval --jobs 12
$P packages/a4/analyse_a4.py --records packages/a4/retrieved/records.jsonl --out packages/a4/eval --jobs 12
1. The code change
Two additions to code/pixcell_generate.py, both backward compatible. The 16 tokens of a window are
a 4x4 grid of 256-px UNI2-h patch embeddings, so their order is the donor's spatial arrangement;
both constructions keep real per-patch appearance and destroy that arrangement.
token_patchbag — a primary source (lines 538-596)
"token_patchbag": {"library": "token-library/", "category": "<cat>", "per_window": true}
From the same 2016-window library token_library reads, restricted to category (default: the
job's own), draw 16 (library window, patch) pairs uniformly at random and stack them into one
(1, 16, 1536) grid. Every token is a real patch embedding of real tissue; no two need come from
the same window, so the grid carries no coherent 4x4 layout. per_window: true draws a fresh bag
for every canvas window; per_window: false draws once (with window index 0) and broadcasts.
The draw is numpy.random.default_rng(seed * 1000 + window_index): rng.integers(0, n_candidates,
16) then rng.integers(0, 16, 16). Recorded: token_patchbag (the spec as resolved),
token_patchbag_candidates, token_patchbag_library_entries, token_patchbag_seed_base, and
token_patchbag_picks — one entry per window carrying all 16 draws as
{slot, library_entry, library_file, library_origin, library_category, patch_index}.
token_shuffle — a post-step over any source (lines 599-616)
"token_shuffle": true
After the primary source resolves a window's grid, permute its 16 tokens with the identical RNG,
numpy.random.default_rng(seed * 1000 + window_index).permutation(16). The multiset of tokens is
unchanged — same donor, same appearance statistics — only their positions in the 4x4 grid move. It
applies to every source. The record keeps the primary token_source and adds token_shuffle,
token_shuffle_seed_base and token_shuffle_permutations (one 16-int permutation per window).
When the flag is absent the keys are absent, so old records keep their exact shape.
Precedence (line 619)
token_file > token_patchbag > token_library > token_blend > token_reference >
reference, then token_shuffle as a post-step. The pre-existing precedence assertion is
unchanged and still passes. token_sha256 is still hashed from whatever grid was actually handed to
the denoiser, so it reflects the shuffle.
Two supporting edits so the fleet plumbing sees the new field: code/resolve_jobs.py resolves and
existence-checks token_patchbag.library the same way it does token_library, and code/worker.sh
counts a patch-bag library when deciding which libraries to build.
Tests — 11/11 pass
code/test_generate_cpu.py under research/sgh-synthetic-histopathology/.venv/bin/python, stub
encoder and stub pipeline, no weights.
PASS old-schema jobs are byte-for-byte unchanged against the canonical generator
4 old-schema jobs identical (bytes + record) to canonical pixcell_generate.py
PASS token_library picks the nearest composition per window
PASS token_blend weights and 'self' resolve to the weighted sum
PASS token_file broadcasts one grid to every window, both accepted shapes
PASS token_shuffle permutes the 16 tokens of every window, from the documented RNG
window perms [7, 10, 2, 11].../[9, 8, 6, 5]... from rng(seed*1000+w); applies to
token_reference and token_file; absent key when off
PASS token_patchbag assembles 16 real patches drawn from the library, per window or once
4 windows x 16 draws from 3 candidates, every (file, patch) verified; per_window=False
broadcasts window 0's bag; category restriction and precedence hold
PASS precedence is token_file > token_library > token_blend > token_reference > reference
PASS every record carries the provenance fields evaluation needs
PASS resume skips ids already in records.jsonl and adds nothing on a rerun
PASS resolve_jobs resolves PASS1 against out/ and drops jobs whose inputs are missing
PASS split_manifests keeps every pass-2 job on its pass-1 slot and places every job
11/11 passed
The two new tests are arithmetic, not aesthetic. The shuffle test computes the expected permutation
independently from numpy.random.default_rng(seed*1000+w), checks the record's claim against it
window by window, checks the tensors actually handed to the stub denoiser are the unshuffled ones
under exactly that permutation, checks the two windows get different permutations, checks a fixed
token_file grid shuffled two ways yields two distinct per-window hashes, and checks that with the
flag off the keys are absent. The patch-bag test builds a library where tokens[n, p, :] == n*100+p,
so the value of every slot names its own (library window, patch) — all 4 x 16 draws are verified
pair by pair against an independent re-draw, plus per_window: false broadcast, category
restriction, an empty category raising rather than falling back, both precedence directions, and
composition with the shuffle.
The strongest test is unchanged and still passes: the canonical repo generator and this one run the same four old-schema jobs under identical stubs and produce identical PNG bytes and identical records apart from the documented new keys.
2. The manifests and the run
code/make_a4_jobs.py copies the a1 pass-1 job of each cartoon verbatim and asserts, for all 10,
that mode, seed, start_index, reference, token_reference and category are unchanged;
only the id and the output path differ. Pass 2 is 10 cartoons x start_index {6, 3} x 5 arms = 100
jobs, all conditioned on the a4 pass-1 output.
| arm | tokens | shuffled? | where the layout goes |
|---|---|---|---|
donor-shuffle |
the a1 donor's own 16 per window | yes | donor appearance kept, donor arrangement destroyed |
bag-window |
16 random (library window, patch) draws, fresh per window | no | real patches, no arrangement, per-window variety |
bag-fixed |
one such bag, broadcast to all 21 windows | no | real patches, no arrangement, no variety |
library-shuffle |
a2's composition-matched library pick | yes | composition matching kept, arrangement destroyed |
nearmean-shuffle |
a3's <cat>_nearest_to_mean.pt fixed grid |
yes | one real window's tokens, arrangement destroyed |
Setup: 2 minutes instead of 45
fleet.sh up a returned a ready GPU in 64 s; staging 31 files took 44 s. Cartoons,
token-library/ (198 MB, 2016 windows) and token-stats/ were symlinked into the new run root
from the previous package root on slot a's own disk
([local]/slot0), so worker.sh
logged cartoons/a1 already rendered (60 cartoons), token-library already built,
token-stats already built and went straight to generation. Boot to first generation was 2 min 46
s, against 45 minutes for the sweep, saving roughly USD 1.50 of idle A100 and about 100 minutes.
Timeline (UTC, 8 September)
| what | time |
|---|---|
instances start issued / GPU ready |
18:18:17 / 18:18:50 |
| stage (31 files) | 18:19:22-18:20:06 |
| worker start | 18:20:59 |
| first generation | 18:21:01 |
a4-pass1 done (10 jobs) |
18:27:17 |
a4-pass2 done (100 jobs) |
19:37:37 |
WORKER_DONE, exit 0, {"ran":2,"skipped":0,"failed":0}, 110 PNGs |
19:37:37 |
retrieve 1.63 GB, SHA256SUMS OK (110 files) |
19:38:09-19:46:43 (514 s, 3.2 MB/s) |
down a -> TERMINATED |
19:46:56-19:48:34 |
No preemption. fleet.sh watch polled every 60 s (last logged poll 61) and exited on
WATCH WORKER_DONE 0 at 19:38:49.
Throughput and cost
| stage | n | median s |
|---|---|---|
pass 1, si12, token_reference |
10 | 32.03 |
pass 2, si6, token_reference + shuffle |
10 | 45.62 |
| pass 2, si6, all other arms | 40 | 37.15-37.34 |
| pass 2, si3, every arm | 50 | 43.95-44.14 |
Total generation 4469 s = 1.24 GPU-hours over 110 jobs, mean 40.6 s. The 8.4 s that
donor-shuffle si6 costs over the other si6 arms is the UNI2-h encode of the donor field — the
layout-free arms never touch the encoder, which is a small side benefit.
Powered 18:18:17 to 19:48:34 = 90.3 min = 1.505 h = USD 3.19 at USD 2.12/h, plus about USD 0.20 of egress for the 1.63 GB retrieved. GPU utilisation 1.24 / 1.505 = 82%, against the sweep's 56%.
Coverage and provenance: clean
packages/a4/merge_records.py: 110 records read, 110 written, 0 duplicates. Per manifest,
expected = records = PNGs (a4-pass1 10/10/10, a4-pass2 100/100/100), no missing ids. Every one
of the 110 PNGs was re-hashed on this Mac and all 110 match their record's output_sha256; no
zero-byte file (the fault that cost the sweep one image). All 110 token_source values equal their
extra.expected_token_source — token_reference 30, token_patchbag 40, token_library 20,
token_file 20 — and all 60 records that should carry token_shuffle: true do, while the other 50
have no token_shuffle key at all.
Pass 1 reproduces the sweep exactly
All 10 a4 pass-1 outputs are byte-identical to the corresponding sweep a1-pass1 outputs, and
each job's reference_sha256 also matches the sweep's, confirming the symlinked cartoons are the
exact bytes the sweep used. Example: a4_p1_intestinal_metaplasia_s11_across ->
dfe57d6f745b2bdeb0269b70211a1b84fbfd6c6d0ed911e75c998069d5289014, identical to
a1_p1_intestinal_metaplasia_s11_across. That is FLEET's cross-slot determinism extended to
cross-run determinism on the same slot five hours later, and it means every a4 pass-2 arm starts
from literally the same image as the a1 arm it is compared against.
Patch-bag provenance on real weights
token_patchbag_candidates = 504 (the library's per-category share of 2016 windows).
bag-window writes 21 picks x 16 draws = 336 recorded draws per canvas and touches a median of
24 distinct donor fields per canvas — every training field of the category. bag-fixed writes
one pick of 16 draws touching a median of 11 distinct fields. For contrast, a2-style
library-shuffle touches a median of 1.5 fields per canvas.
The label maps are the exact ones the generator saw
EVAL_RESULT.md section (c) had to caveat its IoU numbers because the VM cartoons were never retrieved. They were retrieved here (30 files, 125 MB). Comparing them with the local Mac render: the label maps are not pixel-equal (the stromal-nuclei scatter differs, as SWEEP_RESULT.md section 6 found), but the lumen label is identical on all 10 — VM-vs-Mac lumen IoU is exactly 1.000 for every cartoon. So EVAL_RESULT's argument that lumen IoU was safe is now measured rather than argued, and every IoU below is against the exact bytes the generator conditioned on.
3. The table
Per category x start_index x arm, n = 5 cartoons each; medians. IoU is cartoon lumen IoU
against the own (VM) label map; SSIM is mean pairwise SSIM within the cell (the repetition
check, 10 pairs); cos is phikon-v2 max cosine against 118 real reference fields (fail line 0.95);
srcfrac is the fraction of the canvas's phikon tiles whose nearest real field is one the tokens
actually came from; ncc is max pixel NCC (flag 0.92). Full file:
packages/a4/eval/a4-table.csv.
Cartoon lumen IoU ceiling (the cartoon PNG measured against its own label map): IM 0.407, gastritis 0.843, pooled median 0.625.
| cell | n | ring | env D | pct | in band | lap | IoU | SSIM | cos | srcfrac | ncc |
|---|---|---|---|---|---|---|---|---|---|---|---|
| intestinal_metaplasia | |||||||||||
| a1 pass1 (si12) | 5 | 0.545 | 7.65 | 100 | 0 | 12.3 | 0.350 | 0.285 | - | - | - |
| a1 si6 donor | 5 | 0.090 | 5.59 | 100 | 0 | 17.0 | 0.023 | 0.503 | 0.843 | 0.875 | 0.536 |
| a4 si6 donor-shuffle | 5 | 0.035 | 6.25 | 100 | 0 | 16.8 | 0.010 | 0.575 | 0.814 | 0.875 | 0.521 |
| a4 si6 bag-window | 5 | 0.090 | 4.78 | 100 | 0 | 15.7 | 0.047 | 0.886 | 0.772 | 0.250 | 0.520 |
| a4 si6 bag-fixed | 5 | 0.029 | 5.70 | 100 | 0 | 13.8 | 0.028 | 0.895 | 0.755 | 0.000 | 0.549 |
| a4 si6 library-shuffle | 5 | 0.318 | 6.22 | 100 | 0 | 13.7 | 0.075 | 0.799 | 0.789 | 0.875 | 0.546 |
| a4 si6 nearmean-shuffle | 5 | 0.629 | 4.07 | 83 | 5 | 17.3 | 0.104 | 0.882 | 0.838 | 1.000 | 0.461 |
| a1 si3 donor | 5 | 0.506 | 4.62 | 100 | 2 | 19.3 | 0.050 | 0.490 | 0.872 | 1.000 | 0.573 |
| a4 si3 donor-shuffle | 5 | 0.544 | 4.76 | 100 | 1 | 19.3 | 0.047 | 0.571 | 0.848 | 1.000 | 0.554 |
| a4 si3 bag-window | 5 | 0.489 | 2.84 | 67 | 5 | 17.7 | 0.047 | 0.981 | 0.789 | 0.125 | 0.620 |
| a4 si3 bag-fixed | 5 | 0.173 | 4.64 | 100 | 0 | 19.6 | 0.035 | 0.983 | 0.810 | 0.375 | 0.481 |
| a4 si3 library-shuffle | 5 | 0.496 | 5.17 | 100 | 0 | 14.9 | 0.046 | 0.875 | 0.798 | 0.750 | 0.599 |
| a4 si3 nearmean-shuffle | 5 | 0.532 | 4.99 | 100 | 0 | 20.7 | 0.034 | 0.982 | 0.873 | 0.875 | 0.518 |
| real held-out IM | 6 | 0.774 | 2.58 | 58 | 6 | 23.6 | - | 0.035 | - | - | - |
| hpylori_gastritis | |||||||||||
| a1 pass1 (si12) | 5 | 0.387 | 11.53 | 100 | 0 | 16.5 | 0.658 | 0.356 | - | - | - |
| a1 si6 donor | 5 | 0.000 | 7.83 | 83 | 3 | 18.1 | 0.006 | 0.539 | 0.860 | 0.750 | 0.538 |
| a4 si6 donor-shuffle | 5 | 0.022 | 8.26 | 100 | 2 | 18.0 | 0.012 | 0.614 | 0.831 | 0.750 | 0.501 |
| a4 si6 bag-window | 5 | 0.010 | 8.70 | 100 | 1 | 18.9 | 0.009 | 0.917 | 0.822 | 0.500 | 0.520 |
| a4 si6 bag-fixed | 5 | 0.017 | 8.97 | 100 | 0 | 20.0 | 0.006 | 0.934 | 0.812 | 0.375 | 0.552 |
| a4 si6 library-shuffle | 5 | 0.275 | 10.45 | 100 | 0 | 13.0 | 0.110 | 0.874 | 0.836 | 1.000 | 0.580 |
| a4 si6 nearmean-shuffle | 5 | 0.000 | 9.64 | 100 | 0 | 18.2 | 0.000 | 0.889 | 0.817 | 0.125 | 0.494 |
| a1 si3 donor | 5 | 0.294 | 5.77 | 83 | 5 | 19.0 | 0.053 | 0.521 | 0.866 | 1.000 | 0.520 |
| a4 si3 donor-shuffle | 5 | 0.328 | 6.13 | 83 | 5 | 19.0 | 0.048 | 0.603 | 0.856 | 1.000 | 0.472 |
| a4 si3 bag-window | 5 | 0.276 | 5.14 | 67 | 5 | 19.9 | 0.051 | 0.986 | 0.822 | 0.500 | 0.616 |
| a4 si3 bag-fixed | 5 | 0.430 | 4.99 | 67 | 5 | 16.6 | 0.061 | 0.976 | 0.838 | 0.875 | 0.613 |
| a4 si3 library-shuffle | 5 | 0.276 | 8.83 | 100 | 0 | 12.3 | 0.051 | 0.946 | 0.841 | 0.875 | 0.613 |
| a4 si3 nearmean-shuffle | 5 | 0.145 | 7.00 | 83 | 5 | 19.7 | 0.041 | 0.976 | 0.836 | 0.250 | 0.668 |
| real held-out gastritis | 6 | 0.806 | 4.19 | 58 | 6 | 20.4 | - | 0.047 | - | - | - |
Pooled over both categories (n = 10 per cell, packages/a4/eval/a4-headline.json):
| arm | si6 IoU | si6 D | si6 in band | si3 IoU | si3 D | si3 in band |
|---|---|---|---|---|---|---|
| a1 donor (single real donor) | 0.0145 | 6.79 | 3/10 | 0.0505 | 5.70 | 7/10 |
| donor-shuffle | 0.0117 | 7.30 | 2/10 | 0.0480 | 5.13 | 6/10 |
| bag-window | 0.0368 | 6.39 | 1/10 | 0.0492 | 3.96 | 10/10 |
| bag-fixed | 0.0154 | 7.32 | 0/10 | 0.0466 | 4.73 | 5/10 |
| library-shuffle | 0.0908 | 8.08 | 0/10 | 0.0483 | 7.05 | 0/10 |
| nearmean-shuffle | 0.0422 | 6.80 | 5/10 | 0.0407 | 5.77 | 5/10 |
| (a1 pass 1, si12, for scale) | 0.4989 | 9.37 | 0/10 | |||
| cartoon ceiling | 0.6248 |
Paired deltas, a4 arm minus the a1 single-donor arm on the same cartoon at the same depth
Medians of 10 per-cartoon deltas; n+ is how many of the 10 deltas were positive
(packages/a4/eval/a4-paired-vs-a1.csv). For IoU and ring, positive is better; for D, negative is
better; lap is the Laplacian detail statistic, higher is closer to real.
| si | arm | n | d IoU | n+ | d D | n+ | d ring | n+ | d lap | n+ |
|---|---|---|---|---|---|---|---|---|---|---|
| 6 | donor-shuffle | 10 | +0.0000 | 3 | +0.583 | 7 | +0.000 | 3 | -0.10 | 1 |
| 6 | bag-window | 10 | +0.0138 | 6 | -0.518 | 4 | +0.000 | 4 | -0.39 | 4 |
| 6 | bag-fixed | 10 | -0.0008 | 5 | +0.347 | 7 | -0.011 | 3 | -0.01 | 5 |
| 6 | library-shuffle | 10 | +0.0616 | 8 | +1.104 | 8 | +0.232 | 9 | -4.45 | 0 |
| 6 | nearmean-shuffle | 10 | +0.0012 | 5 | -0.324 | 5 | +0.000 | 4 | +0.42 | 6 |
| 3 | donor-shuffle | 10 | -0.0003 | 5 | -0.004 | 5 | +0.000 | 5 | -0.01 | 5 |
| 3 | bag-window | 10 | +0.0030 | 6 | -0.846 | 0 | -0.006 | 5 | -0.54 | 4 |
| 3 | bag-fixed | 10 | -0.0067 | 4 | -0.755 | 3 | -0.218 | 4 | -1.58 | 3 |
| 3 | library-shuffle | 10 | -0.0031 | 4 | +2.072 | 8 | -0.032 | 4 | -6.00 | 0 |
| 3 | nearmean-shuffle | 10 | -0.0129 | 2 | +1.221 | 7 | -0.080 | 3 | +1.12 | 7 |
4. Repetition, and the control that explains everything
Mean pairwise SSIM inside each cell — five outputs from five different cartoons
(packages/a4/eval/a4-within-arm-ssim.json):
| set | IM | gastritis |
|---|---|---|
| real held-out (n=6, 15 pairs) | 0.035 | 0.047 |
| a1 pass 1 si12 | 0.285 | 0.356 |
| a1 si6 donor / si3 donor | 0.503 / 0.491 | 0.539 / 0.521 |
| a4 donor-shuffle si6 / si3 | 0.575 / 0.572 | 0.614 / 0.604 |
| a4 library-shuffle si6 / si3 | 0.799 / 0.876 | 0.875 / 0.946 |
| a4 nearmean-shuffle si6 / si3 | 0.882 / 0.982 | 0.890 / 0.976 |
| a4 bag-window si6 / si3 | 0.886 / 0.981 | 0.917 / 0.986 |
| a4 bag-fixed si6 / si3 | 0.895 / 0.984 | 0.934 / 0.977 |
The token-vs-start control (new, and free from the design)
bag-window, bag-fixed and nearmean-shuffle seed their draw from (seed, window_index) only,
so all five cartoons in one cell receive the identical 21 token grids and differ only in their
start image. Verified from the records: those six cells each contain exactly 1 distinct
token-grid set across 5 records with 5 distinct reference_sha256 values. donor-shuffle has 5
distinct token-grid sets (one per donor); library-shuffle has 4-5 (the composition pick varies
with the cartoon).
That gives a two-way control the sweep never had:
| IM si6 | IM si3 | gastritis si6 | gastritis si3 | |
|---|---|---|---|---|
| tokens fixed, start image varies (5 cartoons) | 0.888 | 0.982 | 0.914 | 0.980 |
| start image fixed, tokens vary (5 arms) | 0.653 | 0.633 | 0.655 | 0.600 |
At si3, replacing the entire 4096x2048 start image — a different cartoon, a different pass-1 canvas — moves the output less than a fifth as far as changing the tokens does. The pass-2 canvas is a function of the conditioning tokens; the start image is nearly inert. At si6 the start image matters somewhat more (0.888-0.914 rather than 0.98), which is consistent with the a1 ladder's monotone IoU collapse, but the ordering is the same.
That is the mechanism behind the null result. The hypothesis assumed the layout would revert to the start image once the tokens stopped carrying one. It does not: with no layout in the tokens, the model simply invents its own, driven by the tokens' appearance statistics. And because those tokens no longer depend on the cartoon, five different cartoons produce one image.
5. The contact sheets, described honestly
packages/a4/eval/sheets/a4-intestinal_metaplasia.png and a4-hpylori_gastritis.png: five rows
(cartoons s11-s15), nine columns — cartoon | a1 pass1 si12 | a1 si3 donor | donor-shuffle si3 |
bag-window si3 | bag-fixed si3 | library-shuffle si3 | nearmean-shuffle si3 | real held-out — 768 px
crops at the same canvas position (1664, 640, 2432, 1408), each labelled ring / D / IoU. Four
a4-zoom-* sheets show the same nine cells for one cartoon at ~620 px so nuclei are judgeable.
Reading down the columns (this is the decisive view). In the IM sheet, columns 2, 3 and 4 — a1 pass 1, a1 si3 donor and donor-shuffle si3 — are five visibly different fields: row 1 a dark palisade along a gland edge, row 2 open pale lumens with thin strands, row 3 a very pale foamy field, row 4 a magenta inflamed-looking field, row 5 a crowded blue-purple one. Columns 5, 6 and 8 — bag-window, bag-fixed and nearmean-shuffle — are five near-copies of each other: the same pale gland with the same vacuole pattern and the same dark nuclear strand in the same corner, five times. Column 7, library-shuffle, is in between: recognisably the same kind of field five times, but with real variation in where things sit. The gastritis sheet says the same thing more strongly — its bag-window, bag-fixed and nearmean-shuffle columns are five copies of one pale foveolar-looking field. This is exactly what the SSIM column reports, and nothing in the sheets contradicts it.
Reading across a row (what the arms look like). On IM s11 si3: the cartoon is flat lilac with dark bean-shaped nuclei and white lumen blobs; a1 pass 1 is a soft, low-contrast, faintly blurry version of it — smoothed cartoon, not tissue; a1 si3 donor is genuinely tissue-like, with dark columnar nuclei palisaded along a gland, pink fibrillar stroma and red cells; donor-shuffle si3 is of the same character — crowded epithelial clusters with clear vacuoles between nuclear strands; bag-window si3 is paler and more vacuolated with large clear spaces (and has the best envelope distance in the package, D 2.9); bag-fixed si3 is similar but with darker nuclear clumps; library-shuffle si3 is darker, denser, flatter, visibly over-stained; nearmean-shuffle si3 is distinctly different — many small round dark nuclei on a magenta ground with red cells, reading more like inflamed lamina propria than intestinal metaplasia. The real held-out field is paler and more delicate than all of them, with a foamy reticulated cytoplasm and thin strands that none of the generated cells reproduces (lap 23.6 against 17-21).
What is absent from every pass-2 cell. The cartoon's geometry. In none of the 100 pass-2 images can I find the cartoon's lumen blobs or gland circles in their cartoon positions — which is the 0.03-0.06 IoU against a 0.41-0.84 ceiling, seen rather than computed. The a1 pass-1 column, by contrast, visibly is the cartoon (IoU 0.35 IM / 0.66 gastritis).
si6 (a4-zoom-*-si6.png). Gastritis si6 is the worst region of the whole programme and A4 does
not repair it: a1 si6 donor is a pale streaky field with bland pink blobs, ring 0.000; donor-shuffle
si6 is paler and smoother still; bag-window and bag-fixed si6 are chunky or foamy but structureless;
nearmean-shuffle si6 is a uniform vacuolated texture with evenly spaced nuclei that reads as a
repeating pattern rather than tissue; library-shuffle si6 is much more purple and denser than any
real field, which is its +1.1 D and -4.5 Laplacian.
6. Verdict per arm
Against the hypothesis: tokens that keep real per-patch appearance but no coherent spatial arrangement let the start image keep the layout at pass 2 while realism stays near the single-donor level.
| arm | layout kept? | realism kept? | repetition? | verdict |
|---|---|---|---|---|
| donor-shuffle | No. si3 IoU 0.048 vs 0.051; paired delta -0.0003, 5/10. si6 0.012 vs 0.015 | Yes, exactly. si3 D 5.13 vs 5.70 (delta -0.004, 5/10), lap 19.1 vs 19.2, ring 0.355 vs 0.382 | Slightly worse than a1: SSIM 0.572/0.604 vs 0.491/0.521 | The cleanest disproof. Destroying the donor's arrangement while keeping its exact 16 tokens changes essentially nothing — not layout, not realism, not the copy screens (own-source 1.000, cosine 0.848). The 4x4 arrangement of the tokens is not what the model uses. |
| bag-window | No. si3 IoU 0.049, delta +0.003 (6/10) | Better than a1. si3 D 3.96 vs 5.70, better on 10 of 10 cartoons; 10/10 inside the envelope band vs 7/10; IM D 2.84 against a real IM median of 2.58 | Fatal. SSIM 0.981/0.986 — one image five times | The best realism number in the package and worthless as it stands: the five outputs of a cell share one token set and are near-identical. Draws from all 24 fields of a category, so provenance spreads (own-source 0.125-0.5, cosine 0.79-0.82, NCC max 0.62, nothing flagged). |
| bag-fixed | No. si3 IoU 0.047, delta -0.007 (4/10) | Mixed: si3 D 4.73 vs 5.70 but ring -0.218 and lap -1.58; gastritis si3 is its best cell (D 4.99, 5/5 in band, IoU 0.061) | Fatal. SSIM 0.983/0.976 | Same trap as bag-window with less within-canvas variety. Broadcasting one 16-token bag to 21 windows costs ring and detail without buying layout. |
| library-shuffle | Partly, at si6 only. si6 IoU 0.091 vs 0.015 (+0.062, 8/10) and ring +0.232 (9/10). At si3 nothing: 0.048 vs 0.051 | No. si6 D +1.10 (8/10 worse) and lap -4.45; si3 D +2.07 and lap -6.00, 0/10 in band, the largest detail regression in the package | SSIM 0.799-0.946, bad but not the worst | The only arm that buys real layout, and only at si6, and it pays about 1.1 D and a third of the detail statistic for it. On the sheets it is visibly over-stained. Rejected on realism. |
| nearmean-shuffle | No. si3 IoU 0.041, delta -0.013, positive on only 2/10 — the worst arm on layout | Split by category: IM si6 is striking (ring 0.629, D 4.07, 5/5 in band, the best IM topology in the package); gastritis si6 is ring 0.000, D 9.64, 0/5 | Fatal. SSIM 0.982/0.976 at si3, 0.882/0.890 at si6 | Reproduces a3's nearmean finding with the shuffle added: coherent, category-dependent, and one image repeated. Shuffling the fixed grid per window did not buy diversity across cartoons, because the grid still does not depend on the cartoon. |
Does any arm dominate the single-donor si3 arm on layout IoU without losing more than ~1 D?
No. Stating it precisely, on the 10 paired cartoons at si3:
- The largest positive paired IoU delta is
bag-windowat +0.0030 (median), positive on 6 of 10 cartoons — against a within-cell IoU spread of 0.023-0.087. That is not a gain, it is noise around zero. Two arms are negative andnearmean-shuffleis positive on only 2 of 10. - Every arm is within +-0.013 IoU of the single-donor arm, against a headroom of 0.57 to the cartoon ceiling. There is nothing to trade off.
- The only arm that gains real layout anywhere is
library-shuffleat si6 (+0.062 IoU, +0.232 ring), and it costs +1.10 D — right at the ~1 D limit — plus a 26% loss of Laplacian detail and 0/10 inside the envelope band. It fails the constraint. bag-windowsi3 does dominate on the envelope (-0.85 D, better on 10/10, 10/10 inside the band), which is the best realism result in the package, but it buys nothing on layout and is disqualified by SSIM 0.98.
The copy screens are clean everywhere: max phikon cosine over all 800 candidate tiles is 0.881
against a 0.95 fail line (min copy margin 0.069, nearmean-shuffle), max pixel NCC 0.747 against
a 0.92 flag, 0 flagged tiles and 0 flagged windows in all 182 pairs. Nothing in A4 reproduces a
real field.
7. What this changes, and what to do instead
- The 4x4 token arrangement is not the lever.
donor-shuffleis a null on every axis. Whatever the 16 tokens do, they do it as an unordered set of appearance descriptors, not as a spatial map. The layout collapse at pass 2 is therefore not caused by the donor's coordinates being copied, and A2's and A3's ~0.22 IoU is not evidence that layout-free tokens preserve the cartoon. - A2/A3's 0.22 was a different experiment. Verified from the sweep records: a2 and a3 used their layout-free tokens at both passes, so their pass-1 output was already layout-free and their pass-2 IoU is measured against a cartoon that pass 1 had already only loosely followed. A4 holds pass 1 fixed (byte-identical to a1) and changes only pass 2, and under that control the layout-free arms give 0.041-0.051, not 0.22.
- The start image is nearly inert at si3 (SSIM 0.98 across five different start images with
fixed tokens, vs 0.60-0.65 across five token sets with a fixed start image). Any plan that hopes
to impose geometry through the img2img start latent at si3 is fighting a factor-of-five
asymmetry. Geometry has to enter through something the denoiser reads per position — the F2
structure adapter, or
region_img2img's per-label lock (lock_mask/lock_labels, already in the generator and unused by this sweep), not through the token grid. - Any conditioning that does not depend on the cartoon collapses the output set. The three
arms whose RNG keys on
(seed, window)alone produce SSIM 0.98. If patch bags are used again, the seed must include the cartoon (e.g.seed*1000 + window + hash(cartoon)), which is a one-line change topatchbag_rng's caller. That would at least restore diversity; it would not restore layout. bag-windowis worth one follow-up for realism alone. D 3.96 pooled (10/10 inside the envelope band, IM 2.84 against a real median of 2.58) is the best envelope result in the programme, and it needs no donor field, no encoder pass and no single slide. Re-run with a cartoon-dependent seed to see whether the envelope gain survives once the five outputs are forced apart.
8. Harness changes made in this package
Three, all in packages/sweep-v1/evaluate_sweep.py, all additive; none of them can change a
sweep-v1 number except where noted.
_library_origins_for()now also readstoken_patchbag_picks, so a patch-bag arm gets an honest source fraction instead of the structural zero EVAL_RESULT.md section 1.2(b) fixed fortoken_library. No sweep-v1 record has that key._library_field_count()had the same bug 1.2(b) fixed elsewhere: it readlibrary_origin or library_file, andlibrary_originis a pixel coordinate ([0, 512]), soPath(str([0, 512])).namereturned"[0, 512]"and the function counted distinct window origins, not distinct donor fields. Fixed to readlibrary_fileonly, and extended to patch bags. This does changen_library_fieldsfor a2 ifpackages/sweep-v1/evalis regenerated; EVAL_RESULT.md section (d)'s "median 2 distinct donor fields per canvas, range 1-3" was computed with the bug and should be re-derived. It is not used in any headline number.- The
sheetsstage is hard-wired to a1/d1/a2/a3/d2/e2/b1 and produced 0 sheets for a4 (it logsno data:for each and exits 0). The sheets this brief asks for are written bypackages/a4/analyse_a4.pyinstead, which also labels each cell with IoU — something_num_labeldoes not carry.
packages/a4/analyse_a4.py re-implements the two EVAL-RUN measurements that were never saved as
scripts (a1-layout-iou, within-arm-diversity) using the harness's own _d1_one,
analysis_masks, label_mask, iou and analysis_masks(...)["grey"][::4,::4] SSIM raster, so the
numbers are directly comparable. As a check that the re-implementation is faithful, its independent
per-tile source fraction reproduces the harness's own_source_fraction exactly on the a1 arms
(0.875 / 1.000 IM si6 / si3; 0.750 / 1.000 gastritis).
9. Caveats
- n = 5 per cell, 10 cartoons total, two categories, one cut. Every "median" is a median of 5. The paired deltas are the more trustworthy statistic and they are medians of 10.
- The three collapsed arms have an effective n far below 5: five outputs at SSIM 0.98 are close to one measurement, so their envelope and ring numbers should be read as "this token set gives D ≈ x", not as a distribution over cartoons.
- Layout is measured only as lumen IoU against the cartoon's own label map, on the
ring_topologyanalysis raster. It is a coarse instrument; a rearranged-but-plausible gland field scores 0 exactly as a wash does. The epithelium IoU is ina4-layout-iou.csvand is noisier (the cartoon's own epithelium ceiling is 0.10-0.42). - The envelope, ring, Laplacian and copy screens are the C1/C2 instruments unchanged; the features self-check reproduced C1's held-out Mahalanobis distances to max |delta| = 0.0000.
bag-window's per-window bag makes 21 independent draws over one canvas; nothing here measures window-boundary seams, which is the failure mode that construction would be most prone to. Recorded as not measured, not as absent.- No pathologist has seen any of this. Yash has not reviewed a sheet. Nothing here is a clinical claim.
- Slots
b,canddwere RUNNING under other packages while this ran; they were not touched. Slotais TERMINATED, confirmed byfleet.sh statusafterdown.