1. What we are doing
A generator whose every output pixel is an exact, owner-labelled blend of training pixels, and an instrument around it that lets the viewer take a source out and watch the picture change. The viewer brings a drawing, generates from a small owned corpus (six public-domain artists plus a museum pool), reads the receipt, switches any artist or sheet off, and regenerates with the same noise. The instrument shows the difference map and pays contributors three ways side by side: by use (what the receipt says was copied), by leave-one-out (what changed when that one source was removed), and by Shapley (average change over all orders of removal). The viewer's own drawing is its own line in the receipt, because it steers the output more than any corpus source.
Working name: Take It Out.
Source: BRIEF.md (sections 0 and 1), read at build time.
2. Status
| Item | What | State | Note |
|---|---|---|---|
| M0 | Brief, log, source registry | done | BRIEF.md, LOG.md |
| M1 | Engine port, float64 reference, tests | done: 51/51 tests pass | reconciled with Riley's repository, 2026-10-01 (measure/riley_reconcile.py) |
| M2 | Corpus, dedupe, paper decision, controls, commons verified, paid-artist works excluded | done | paper verdict: NOT OVER-CREDITED: no policy |
| O12 | Marks resolved at the demo scale | pixel criterion: failed for all 6 crops (area-weighted; design error); edge criterion: passed for 64 px marks | gates everything shown to others |
| Commons licence | Met records matched by image filename | 99/99 matched | not public domain: 0 |
| M3 | Removal instrument, exact artist Shapley | first run done: checks hold; 6 of 10 predictions hold | constant control earned 3 to 7% |
| M4 | The viewer's drawing as a paid party | D1, D3 hold; D2, D4 fail | the drawing out-earns every artist even at low strength; post hoc: mostly for its paper tone |
| T0FIX | Remove the t = 1 head-count vote (schedule S1) | all 6 predictions hold; K2 held in float64: S1 adopted | constant control 0 to 0.36% |
| M5 | Speed and 64 px | measured: certified pruning 1.05 to 1.10x (oracle 1.4x); 64 px 13x the 32 px cost | pruning retired as the speed lever; larger receipts precomputed |
| M6, M6b | Page, receipts, verifier | receipts format 3 (context, planted controls); verifier V1 to V7; tamper suite 8/8 | paid receipts on the 86-pool: controls pass 4/4 (10-pool demo: 2 of 4 fail) |
| O6 | Cost by resolution and pool size | measured 2026-10-02: 32 px 11 to 21 s per picture (pool 10 to 86), 64 px 148 to 258 s; 1.1 / 2.2 GB | measure/o6_cost.json |
| SPLIT | Drawing as paper and lines | L1 to L3 hold | splitting a party moves others' pay; split is description only |
| POOL | Use vs Shapley gap by pool size | P1, P3 hold; P2 fails | use and leave-one-out err in opposite directions |
| ATTN1, ATTN2 | Stage-two attention tests | ATTN1 Q1, Q3 hold, Q2 fails; ATTN2 all hold | global attention copies; frozen-attention receipts differ from the exact posterior |
| O9 | Runs elsewhere | Colab T4: receipt replay 0.005 of tolerance; payouts within 6e-7 | T3 float32 now reported, not pass/fail |
| O7 | Bridge to trained networks | done 2026-10-02: gate r 0.970; direction holds (p = 1/720); size and visibility fail | replication with a second start seed open |
| O10 | Planted controls visible | in every receipt and on the page | |
| O11 | Stranger test | not run (needs three people) | script: STRANGER_TEST.md |
3. Engine
The generator is the patch-ledger ELS machine (Kamb and Ganguli 2025), ported with provenance and extended: explicit device and dtype, a true float64 CPU reference, float64 schedule arithmetic, an exact class sub-ledger and class removal. Every output pixel is an exact convex combination of training pixels, decomposed by owner: m(x) = Σc Wc(x) mc(x), Σc Wc(x) = 1.
Test run
51/51 passed in 13.2 s · torch 2.12.0.dev20260315 · backends cpu/float64, mps/float32 · engine/tests/last_run.json sha256 3b97fdf3f565
| Test | Detail | |
|---|---|---|
| PASS | T1 [cpu/float64] binary pixels | max |(|x|-1)| = 3.43e-13 |
| PASS | T1 [cpu/float64] local majority consistency >= 0.99 | fraction = 0.9948 |
| PASS | T1 [cpu/float64] novel (not a training image) | 8/8 samples are mixed mosaics |
| PASS | T2 [cpu/float64] ideal score memorises | max distance to nearest training image 0.00e+00 |
| PASS | T3 [cpu/float64] output = sum_c W_c m_c | max err 0.00e+00 |
| PASS | T3 [cpu/float64] masses sum to 1 at every step | worst 1.92e-14 |
| PASS | T4 [cpu/float64] brute-force match els abar=0.3 P=5 | output err 2.9e-15, mass err 3.7e-15 |
| PASS | T4 [cpu/float64] brute-force match els abar=0.9 P=3 | output err 7.0e-15, mass err 6.0e-15 |
| PASS | T4 [cpu/float64] brute-force match ls abar=0.3 P=5 | output err 3.1e-15, mass err 3.6e-15 |
| PASS | T4 [cpu/float64] brute-force match ls abar=0.9 P=3 | output err 9.8e-15, mass err 1.2e-14 |
| PASS | T4 [cpu/float64] brute-force match is abar=0.3 P=5 | output err 5.9e-15, mass err 1.6e-15 |
| PASS | T4 [cpu/float64] brute-force match is abar=0.9 P=3 | output err 1.5e-14, mass err 1.2e-41 |
| PASS | T5 [cpu/float64] duplicate == original at prior weight 2 | max diff 5.22e-15; unduplicated output moves by up to 1.04 |
| PASS | T5 [cpu/float64] duplicate splits mass exactly | max |W_orig - W_copy| 0.00e+00 |
| PASS | T6 [cpu/float64] Theorem B.3 approached under step refinement | pixels at nearest-patch centre: 0.695 (50) -> 0.823 (400) |
| PASS | T7 [cpu/float64] coalition mask == removing contributors | max diff 0.00e+00; mass on absent contributors 0.0e+00 |
| PASS | T1 [mps/float32] binary pixels | max |(|x|-1)| = 8.89e-04 |
| PASS | T1 [mps/float32] local majority consistency >= 0.99 | fraction = 0.9948 |
| PASS | T1 [mps/float32] novel (not a training image) | 8/8 samples are mixed mosaics |
| PASS | T2 [mps/float32] ideal score memorises | max distance to nearest training image 0.00e+00 |
| PASS | T3 [mps/float32] output = sum_c W_c m_c | max err 0.00e+00 |
| PASS | T4 [mps/float32] brute-force match els abar=0.3 P=5 | output err 1.8e-06, mass err 1.3e-06 |
| PASS | T4 [mps/float32] brute-force match els abar=0.9 P=3 | output err 3.4e-06, mass err 3.7e-06 |
| PASS | T4 [mps/float32] brute-force match ls abar=0.3 P=5 | output err 1.5e-06, mass err 1.6e-06 |
| PASS | T4 [mps/float32] brute-force match ls abar=0.9 P=3 | output err 2.9e-06, mass err 4.1e-06 |
| PASS | T4 [mps/float32] brute-force match is abar=0.3 P=5 | output err 1.9e-06, mass err 1.3e-06 |
| PASS | T4 [mps/float32] brute-force match is abar=0.9 P=3 | output err 6.0e-08, mass err 2.7e-33 |
| PASS | T5 [mps/float32] duplicate == original at prior weight 2 | max diff 2.74e-06; unduplicated output moves by up to 1.04 |
| PASS | T5 [mps/float32] duplicate splits mass exactly | max |W_orig - W_copy| 0.00e+00 |
| PASS | T6 [mps/float32] Theorem B.3 approached under step refinement | pixels at nearest-patch centre: 0.695 (50) -> 0.823 (400) |
| PASS | T7 [mps/float32] coalition mask == removing contributors | max diff 0.00e+00; mass on absent contributors 0.0e+00 |
| PASS | N1 float64 reference keeps float64 end to end | dtypes ['torch.float64'] |
| PASS | N1 float64 reference matches brute force to 1e-12 | max err 6.4e-15 |
| PASS | N2 exact removal is bit-for-bit on CPU float64 (O2) | 0 differing values; max diff 0.0e+00 |
| PASS | N3 [cpu/float64] same noise twice gives identical output and ledger | 0 output values and 0 mass values differ; max diff 0.0e+00 |
| PASS | N3 [mps/float32] same noise twice gives identical output and ledger | 0 output values and 0 mass values differ; max diff 0.0e+00 |
| PASS | N4 [mps/float32] agrees with the CPU float64 reference (<= 1% of values off by > 1e-3) | max 2.3e-03, median 0.0e+00, fraction > 1e-3: 0.0013 |
| PASS | N5 port == ORIGINAL bit for bit on mps given the same schedule arithmetic | 0 output and 0 mass values differ; unpatched (float32 schedule) mass gap 2.0e-04 |
| PASS | N6 empty coalition raises | a coalition has no present contributor with images; its output is unde |
| PASS | N7 Riley's weights == Kamb-Ganguli weights after rescaling (BRIEF 6.2) | max diff 2.6e-15 |
| PASS | N8 [cpu/float64] class ledger and removal match brute force abar=0.3 P=5 drop=() | max err 3.6e-15 |
| PASS | N8 [cpu/float64] class ledger and removal match brute force abar=0.9 P=3 drop=() | max err 1.7e-14 |
| PASS | N8 [cpu/float64] class ledger and removal match brute force abar=0.5 P=3 drop=(0,) | max err 1.8e-15 |
| PASS | N8 [cpu/float64] class ledger and removal match brute force abar=0.7 P=5 drop=(1,) | max err 8.2e-15 |
| PASS | N8 [mps/float32] class ledger and removal match brute force abar=0.3 P=5 drop=() | max err 1.9e-06 |
| PASS | N8 [mps/float32] class ledger and removal match brute force abar=0.9 P=3 drop=() | max err 7.2e-06 |
| PASS | N8 [mps/float32] class ledger and removal match brute force abar=0.5 P=3 drop=(0,) | max err 9.3e-07 |
| PASS | N8 [mps/float32] class ledger and removal match brute force abar=0.7 P=5 drop=(1,) | max err 3.6e-06 |
| PASS | N9 [cpu/float64] class masses sum to contributor mass; tracking classes changes nothing | sum err 6.1e-15; 0 output values differ |
| PASS | N9 [mps/float32] class masses sum to contributor mass; tracking classes changes nothing | sum err 1.7e-06; 0 output values differ |
| PASS | N10 removing every candidate raises | some output pixel has no allowed training patch (every candi |
Measurements recorded by the tests
| Measurement | Value |
|---|---|
| T4 worst error cpu/float64 | 1.50e-14 |
| T3_float32_mass_sum_error_mps/float32 | 5.25e-06 |
| T4 worst error mps/float32 | 4.07e-06 |
| N1 float64 brute-force error | 6.44e-15 |
| N2 removal max diff cpu float64 | 0.000 |
| N3 run-to-run differing output values cpu/float64 | 0 |
| N3 run-to-run max diff cpu/float64 | 0.000 |
| N3 run-to-run differing output values mps/float32 | 0 |
| N3 run-to-run max diff mps/float32 | 0.000 |
| N4 mps/float32 vs cpu/float64: output max diff | 0.002 |
| N4 mps/float32 vs cpu/float64: output median diff | 0.000 |
| N4 mps/float32 vs cpu/float64: fraction of values off by > 1e-3 | 0.001 |
| N4 mps/float32 vs cpu/float64: final mass max diff | 0.002 |
| N5 float32 schedule rounding alone: output max diff | 2.74e-06 |
| N5 float32 schedule rounding alone: mass max diff | 1.95e-04 |
| N8 class ledger float64 brute-force error | 1.73e-14 |
Cost of one exact 32 px generation
Provenance of the ported code
Provenance of ORIGINAL/
Verbatim copies, never edited. Copied 2026-09-30T10:49:16Z from the earlier patch-ledger project.
| file | sha256 |
|---|---|
| pl/__init__.py | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 |
| pl/machine.py | 2ee175aa061da6dc30fe932f9415ba7219f109b84c7f390493e08540c8b6e4b4 |
| pl/corpus.py | 0dea3aaedcc892e93a34bd3be92e801e3dc6be5824349b0099c23317ee98836b |
| tests/test_machine.py | ba583f25d321720c6f79a8c9fcdd9b4826d8f30bbceff4f914e594f790e7554b |
Source hashes at copy time (must match):
- pl/__init__.py e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- pl/machine.py 2ee175aa061da6dc30fe932f9415ba7219f109b84c7f390493e08540c8b6e4b4
- pl/corpus.py 0dea3aaedcc892e93a34bd3be92e801e3dc6be5824349b0099c23317ee98836b
- tests/test_machine.py ba583f25d321720c6f79a8c9fcdd9b4826d8f30bbceff4f914e594f790e7554b
4. Corpus
| Group | Sources | Licence status | Licences |
|---|---|---|---|
| Cézanne | 15 | recorded from museum or Commons metadata by the hands corpus build | Public domain (NGA Open Access, via Wikimedia Commons) (15) |
| Dürer | 13 | recorded from museum or Commons metadata by the hands corpus build | CC0 (Met Open Access) (7) Public domain (PD-Art, via Wikimedia Commons) (4) CC0 (AIC public domain) (1) CC0 (Cleveland Open Access) (1) |
| Ingres | 20 | recorded from museum or Commons metadata by the hands corpus build | CC0 (Met Open Access) (14) CC0 (NGA Open Access) (3) CC0 (AIC public domain) (2) CC0 (Cleveland Open Access) (1) |
| Kollwitz | 20 | recorded from museum or Commons metadata by the hands corpus build | Public domain (Rijksmuseum) (11) Public domain (Mia) (5) Public domain (SMK open) (2) CC0 (NGA Open Access) (1) CC0 (Cleveland Open Access) (1) |
| Rembrandt | 12 | recorded from museum or Commons metadata by the hands corpus build | Public domain (Rijksmuseum) (8) CC0 (Met Open Access) (3) CC0 (Cleveland Open Access) (1) |
| Van Gogh | 16 | recorded from museum or Commons metadata by the hands corpus build | Public domain (PD-Art, via Wikimedia Commons) (7) CC0 (AIC public domain) (4) Public domain (Rijksmuseum) (3) CC0 (Met Open Access) (2) |
| commons | 100 | verified after the build against Met object records: 99 matched, 0 not public domain (corpus/met_verification.json; the manifest keeps its build-time wording) | Met Open Access assumed (100) |
| msv | 9 | work public domain; image source not recorded | public domain by age (Cézanne d. 1906) (9) |
| CONTROL-duplicate | 1 | planted control | verbatim copy of du-01 |
| CONTROL-scrambled | 1 | planted control | vg-01 with pixel positions permuted, numpy default_rng(7) |
| CONTROL-constant | 1 | planted control | constant 4.0, outside the data range [-1, 1] |
Rules
Build the Take It Out corpus (BRIEF.md M2).
Sources (read only, never edited):
six artists 96 cleaned sheets from the hands books (five in hands/books, Rembrandt in know-between's book);
metadata and licence from each book's things.json (museum-API or Commons records)
commons 100 Met images in ZTOYBOX/Museum Pics named DP-*/DT-*.jpeg (Met image IDs). Verified afterwards against
Met object records by corpus/verify_met.py (99 matched, all public domain; 1 duplicate download)
msv 9 Cezanne Mont Sainte-Victoire paintings (Cezanne/CezanneReal; public domain by age;
image source not recorded)
Rules (declared, deterministic):
sheet crop Book sheets still show the museum mount around the paper. Marks are pixels darker than the sheet's
paper tone: the dark class of Otsu's two-class luminance split (guarded). The crop is the 1st to 99th percentile box of mark
coordinates on each axis, grown by 2% of the image size and clipped. Paintings (commons, msv) are not
cropped.
views As in patch-ledger (pl/corpus.py): from the crop, the centred square of its short side resized to a
256 px master; view 0 is the master; views 1-3 are 128 px squares at positions drawn from
numpy default_rng(crc32(id)); each view is resized to L (LANCZOS). Stored in [-1, 1].
mark maps The same crop and view geometry applied to the mark mask gives, per view and L, the fraction of each
pixel covered by marks (for the blank-paper measurement).
controls CONTROL-duplicate: a verbatim copy of sheet du-01's views, a separate owner.
CONTROL-scrambled: vg-01's views with pixel positions permuted (seed 7), colours kept, structure gone.
CONTROL-constant: 4 constant images at value 4.0, outside the data range. At t = 1 the posterior is
uniform over all patches, so every source touches every output at the first step; this control's
influence is predicted to be that first-step share and essentially nothing after.
Sheet view profiles (paintings and the commons always use "half"):
half the patch-ledger rule above (view 0 = short-side square; views 1-3 = seeded half-side squares)
marks64 the demo profile, chosen by the O12 tests (LOG.md 2026-09-30): 4 squares of side 64 source pixels
(of the 1200 px book image), centres drawn inside the sheet crop box with probability proportional to
the mark mask, from numpy default_rng(crc32("<id>|64|marks")); each resized to L. A declared choice
that favours where the artist drew; stated on every receipt.
Outputs: corpus/build/L<res>/<id>.npy (half views, float32), <id>.marks.npy (mark fraction);
corpus/build/marks64/L<res>/<id>.npy and .marks.npy for sheets and controls; manifest.json; a contact sheet.
Run: python3 corpus/build_corpus.pyEvery source, view 0 at 64 px
Mark detection
5. Source IDs and verification
Every source with its identifiers. Sheets: licence and accession recorded from museum or Commons metadata when the hands corpus was built. Commons: matched to Met object records by exact image filename (corpus/verify_met.py); unmatched files stay unverified. The last column is the first 10 hex digits of the source file's SHA-256.
Met verification (scope: cache only), 6615 object records: 99 files matched, 1 duplicate download(s), 0 unmatched, 0 matched but not public domain.
| ID | Group | Title | Identifier | Licence | Status | Record | File |
|---|---|---|---|---|---|---|---|
cz-01 | Cézanne | Landscape Near Aix-en-Provence 1877–1880 | National Gallery of Art, Washington · 1992.51.9.d | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | 2c6af99a78 |
cz-02 | Cézanne | Kerosene Lamp 1878–1881 | National Gallery of Art, Washington · 1992.51.9.j | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | 65b48cddbf |
cz-03 | Cézanne | Study of Houses 1879–1882 | National Gallery of Art, Washington · 1992.51.9.e | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | d980c3cbe9 |
cz-04 | Cézanne | Study of "Venus de Milo" 1881–1884 | National Gallery of Art, Washington · 1992.51.9.ppp | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | dc31fb6889 |
cz-05 | Cézanne | Pine Tree 1882–1885 | National Gallery of Art, Washington · 1992.51.9.ii | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | 97fc634e3f |
cz-06 | Cézanne | Near the Pool at Jas de Bouffan 1883–1887 | National Gallery of Art, Washington · 1992.51.9.eee | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | e4d5a30c64 |
cz-07 | Cézanne | Trees and Shrubs 1883–1887 | National Gallery of Art, Washington · 1992.51.9.rrr | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | ace4a4f96f |
cz-08 | Cézanne | Madame Cézanne 1886–1889 | National Gallery of Art, Washington · 1992.51.9.l | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | 869ae59734 |
cz-09 | Cézanne | Bellows in Front of a Fireplace 1887–1892 | National Gallery of Art, Washington · 1992.51.9.w | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | 5db2f66282 |
cz-10 | Cézanne | Head of the Artist's Son 1888–1889 | National Gallery of Art, Washington · 1992.51.9.gg | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | 7f4390811e |
cz-11 | Cézanne | The Plaster Mill (La Moulin à plâtre) 1889–1892 | National Gallery of Art, Washington · 1992.51.9.a | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | 4d8bd97a99 |
cz-12 | Cézanne | House Surrounded by Vegetation 1889–1892 | National Gallery of Art, Washington · 1992.51.9.ccc | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | d9081ee8d0 |
cz-13 | Cézanne | Self-Portrait c. 1895 | National Gallery of Art, Washington · 1992.51.9.m | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | 781993a775 |
cz-14 | Cézanne | Study of Puget's "Milo of Crotona" 1895–1898 | National Gallery of Art, Washington · 1992.51.9.b | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | 3b65590822 |
cz-15 | Cézanne | Landscape with Trees 1895–1898 | National Gallery of Art, Washington · 1992.51.9.f | Public domain (NGA Open Access, via Wikimedia Commons) | recorded | record | bd1f47d78c |
du-01 | Dürer | Self-portrait, Study of a Hand and a Pillow (recto); Six Studies of Pillows (verso) 1493 | The Metropolitan Museum of Art · 1975.1.862 | CC0 (Met Open Access) | recorded | record | b5b145bc23 |
du-02 | Dürer | My Agnes (Agnes Dürer) 1494 | Albertina, Vienna · 3063 | Public domain (PD-Art, via Wikimedia Commons) | recorded | record | db2e7d7a0c |
du-03 | Dürer | Young Bull c. 1496 | Art Institute of Chicago · 1965.408 | CC0 (AIC public domain) | recorded | record | 8bcd8d2dd0 |
du-04 | Dürer | Female Nude Praying 1497/1500 | National Gallery of Art, Washington · 1999.31.1 | Public domain (PD-Art, via Wikimedia Commons) | recorded | record | 83e4af9441 |
du-05 | Dürer | Fortuna in a Niche 1498 | The Metropolitan Museum of Art · 1975.1.861 | CC0 (Met Open Access) | recorded | record | 7a52960d84 |
du-06 | Dürer | Male Nude Holding a Mirror c. 1500 | National Gallery of Art, Washington · 1991.182.11.a | Public domain (PD-Art, via Wikimedia Commons) | recorded | record | 10a9245431 |
du-07 | Dürer | Male Nude with a Lion c. 1500 | National Gallery of Art, Washington · 1991.182.11.b | Public domain (PD-Art, via Wikimedia Commons) | recorded | record | f6e33d2916 |
du-08 | Dürer | Standing Male Nude Holding a Bow ("Poynter Apollo") 1501–3 | The Metropolitan Museum of Art · 63.212 | CC0 (Met Open Access) | recorded | record | 1e425e6848 |
du-09 | Dürer | The Holy Family in an Enclosed Garden 1512 | The Metropolitan Museum of Art · 1975.1.860 | CC0 (Met Open Access) | recorded | record | a87ad7c374 |
du-10 | Dürer | Ascension of Christ c. 1515 | Cleveland Museum of Art · 1952.530 | CC0 (Cleveland Open Access) | recorded | record | c9e012fde7 |
du-11 | Dürer | Music-Making Angels 1521 | The Metropolitan Museum of Art · 61.257 | CC0 (Met Open Access) | recorded | record | 780f477362 |
du-12 | Dürer | Knight on Horseback and Landsknecht 1485–1528 | The Metropolitan Museum of Art · 47.100.1283 | CC0 (Met Open Access) | recorded | record | 2079553d76 |
du-13 | Dürer | Saint Catherine of Alexandria 1490–1528 | The Metropolitan Museum of Art · 19.75 | CC0 (Met Open Access) | recorded | record | 011141f355 |
in-01 | Ingres | Madame Guillaume Guillon Lethière, née Marie-Joseph-Honorée Vanzenne, and her son Lucien Lethière 1808 | The Metropolitan Museum of Art · 29.100.191 | CC0 (Met Open Access) | recorded | record | a62b2433a6 |
in-02 | Ingres | Charles François Mallet, Civil Engineer 1809 | Art Institute of Chicago · 1938.166 | CC0 (AIC public domain) | recorded | record | 80b92826be |
in-03 | Ingres | Portrait of a Man 1814 | The Metropolitan Museum of Art · 19.125.1 | CC0 (Met Open Access) | recorded | record | b64dc4f1ce |
in-04 | Ingres | Madame Jean-Auguste-Dominique Ingres, née Madeleine Chapelle 1814 | The Metropolitan Museum of Art · 2004.475.2 | CC0 (Met Open Access) | recorded | record | 886c71d03c |
in-05 | Ingres | Madame Alexandre Lethière, née Rosa Meli, and Her Daughter, Letizia 1815 | The Metropolitan Museum of Art · 2012.150.10 | CC0 (Met Open Access) | recorded | record | d843be389d |
in-06 | Ingres | Lady Mary Cavendish-Bentinck (?-1843) 1816 | The Metropolitan Museum of Art · 43.85.6 | CC0 (Met Open Access) | recorded | record | dcb693c0f9 |
in-07 | Ingres | Mrs. Charles Badham 1816 | National Gallery of Art, Washington · 1991.217.20 | CC0 (NGA Open Access) | recorded | record | e85b3868de |
in-08 | Ingres | The Kaunitz Sisters (Leopoldine, Caroline, and Ferdinandine) 1818 | The Metropolitan Museum of Art · 1998.21 | CC0 (Met Open Access) | recorded | record | 7b656cbf92 |
in-09 | Ingres | General Louis-Étienne Dulong de Rosnay 1818 | The Metropolitan Museum of Art · 2012.150.9 | CC0 (Met Open Access) | recorded | record | 6b4f739ea5 |
in-10 | Ingres | Ursin-Jules Vatinelle (1798–1881) 1820 | The Metropolitan Museum of Art · 43.85.9 | CC0 (Met Open Access) | recorded | record | fbd3e8feed |
in-11 | Ingres | Self-Portrait 1822 | National Gallery of Art, Washington · 1995.47.51 | CC0 (NGA Open Access) | recorded | record | 14666d2c8c |
in-12 | Ingres | Madame Désiré Raoul-Rochette 1830 | Cleveland Museum of Art · 1927.437 | CC0 (Cleveland Open Access) | recorded | record | 267174e39a |
in-13 | Ingres | The Lawyer Paul Grand 1834 | The Metropolitan Museum of Art · 2012.150.11 | CC0 (Met Open Access) | recorded | record | 8195e88a14 |
in-14 | Ingres | The Architect Charles-Victor Famin 1836 | The Metropolitan Museum of Art · 2012.150.15 | CC0 (Met Open Access) | recorded | record | 4c423304d6 |
in-15 | Ingres | Charles Gounod 1841 | Art Institute of Chicago · 1964.77 | CC0 (AIC public domain) | recorded | record | aea7b65b2e |
in-16 | Ingres | Madame Armand Bertin, née Marie-Anne-Cécile Dollfuss 1843 | The Metropolitan Museum of Art · 2012.150.14 | CC0 (Met Open Access) | recorded | record | b1b42e18a6 |
in-17 | Ingres | Portrait of Madame Paul Meurice, née Palmyre Granger ca. 1845–50 | The Metropolitan Museum of Art · 2016.20 | CC0 (Met Open Access) | recorded | record | 1aa8a98d15 |
in-18 | Ingres | Dr. François Mêlier 1849 | The Metropolitan Museum of Art · 1975.1.648 | CC0 (Met Open Access) | recorded | record | e1bff4a60c |
in-19 | Ingres | Study of Hands for "Christ Among the Doctors" 1852–62 | The Metropolitan Museum of Art · 2022.25.11 | CC0 (Met Open Access) | recorded | record | ac73ff1b32 |
in-20 | Ingres | Henri Labrouste 1852 | National Gallery of Art, Washington · 1995.47.52 | CC0 (NGA Open Access) | recorded | record | 9696a631f7 |
kk-01 | Kollwitz | Ein Weberaufstand 1897 | Rijksmuseum, Amsterdam · RP-P-OB-53.192 | Public domain (Rijksmuseum) | recorded | record | 25ead336d0 |
kk-02 | Kollwitz | De dood haalt een man uit zijn gezin 1897 | Rijksmuseum, Amsterdam · RP-P-1947-312 | Public domain (Rijksmuseum) | recorded | record | abdb2faa45 |
kk-03 | Kollwitz | Outbreak (Losbruch), study 1898–1903 | Rijksmuseum, Amsterdam · RP-T-1960-79 | Public domain (Rijksmuseum) | recorded | record | 151d9927ea |
kk-04 | Kollwitz | Beratung 1898 | Rijksmuseum, Amsterdam · RP-P-1947-313 | Public domain (Rijksmuseum) | recorded | record | d2b8c46ea0 |
kk-05 | Kollwitz | Pflugzieher und Weib 1902 | Minneapolis Institute of Art · 2016.136.2 | Public domain (Mia) | recorded | record | 335682b478 |
kk-06 | Kollwitz | Two Studies of a Woman's Head c. 1903 | Minneapolis Institute of Art · 71.65 | Public domain (Mia) | recorded | record | a3a8a849ae |
kk-07 | Kollwitz | Mother with Dead Child 1911 | Minneapolis Institute of Art · 91.131.2 | Public domain (Mia) | recorded | record | 6196e545cf |
kk-08 | Kollwitz | Mutter mit Kind auf dem Arm 1916 | SMK, National Gallery of Denmark · KKS14595 | Public domain (SMK open) | recorded | record | 805a0991bd |
kk-09 | Kollwitz | Mütter 1919 | Rijksmuseum, Amsterdam · RP-P-1954-574 | Public domain (Rijksmuseum) | recorded | record | e7c1b6172b |
kk-10 | Kollwitz | Nachdenkende Frau 1920 | Rijksmuseum, Amsterdam · RP-P-1952-120 | Public domain (Rijksmuseum) | recorded | record | 45ac92f476 |
kk-11 | Kollwitz | Vrouw en de dood in of na 1923 - in of voor 1924 | Rijksmuseum, Amsterdam · RP-P-1974-242 | Public domain (Rijksmuseum) | recorded | record | a514807c05 |
kk-12 | Kollwitz | Beggars 1924 | National Gallery of Art, Washington · 1943.3.5219 | CC0 (NGA Open Access) | recorded | record | d9fe011e49 |
kk-13 | Kollwitz | Prisoners Listening to Music 1925 | Minneapolis Institute of Art · 2000.283.9 | Public domain (Mia) | recorded | record | 5ed9ddf827 |
kk-14 | Kollwitz | Portret van een kind, waarschijnlijk Lotte Nagel 1925 | Rijksmuseum, Amsterdam · RP-P-1942-305 | Public domain (Rijksmuseum) | recorded | record | e0f450d938 |
kk-15 | Kollwitz | Pregnant Woman Contemplating Suicide c. 1926 | Cleveland Museum of Art · 1962.291.a | CC0 (Cleveland Open Access) | recorded | record | 7b7532e912 |
kk-16 | Kollwitz | Zuhörende 1927 | Rijksmuseum, Amsterdam · RP-P-1952-481 | Public domain (Rijksmuseum) | recorded | record | 4e733ce2f7 |
kk-17 | Kollwitz | Zelfportret en profil in or after 1929 - in or before 1930 | Rijksmuseum, Amsterdam · RP-P-1951-310 | Public domain (Rijksmuseum) | recorded | record | b021e02003 |
kk-18 | Kollwitz | Selvportræt 1934 | SMK, National Gallery of Denmark · KKS19214 | Public domain (SMK open) | recorded | record | fdb6c85f28 |
kk-19 | Kollwitz | Tod in or after 1934 - in or before 1937 | Rijksmuseum, Amsterdam · 8/8 | Public domain (Rijksmuseum) | recorded | record | ed834d6456 |
kk-20 | Kollwitz | Selbstbildnis im Profil nach rechts (Self-Portrait in Profile towards Right) 1938 | Minneapolis Institute of Art · P.93.25 | Public domain (Mia) | recorded | record | 6b0a581741 |
rb-01 | Rembrandt | Seated Actor in the Role of Capitano c. 1634 - c. 1636 | Rijksmuseum, Amsterdam · RP-T-1961-76(R) | Public domain (Rijksmuseum) | recorded | record | b6dd711427 |
rb-02 | Rembrandt | Two Studies of a Woman Reading 1635–40 | The Metropolitan Museum of Art · 29.100.932 | CC0 (Met Open Access) | recorded | record | d8f0339ca2 |
rb-03 | Rembrandt | A Cow in a Shed c. 1640 | Rijksmuseum, Amsterdam · RP-T-1930-59 | Public domain (Rijksmuseum) | recorded | record | a0b68c4d1b |
rb-04 | Rembrandt | Boaz and Ruth c. 1645 | Rijksmuseum, Amsterdam · RP-T-1930-9 | Public domain (Rijksmuseum) | recorded | record | 59d03d8ba6 |
rb-05 | Rembrandt | Three Orientals Conversing c. 1645 | Rijksmuseum, Amsterdam · RP-T-1930-47 | Public domain (Rijksmuseum) | recorded | record | 7a49962f14 |
rb-06 | Rembrandt | Cottage with White Paling among Trees c. 1648 | Rijksmuseum, Amsterdam · RP-T-1981-1 | Public domain (Rijksmuseum) | recorded | record | 74d21a793d |
rb-07 | Rembrandt | Cottage among Trees ca. 1650 | The Metropolitan Museum of Art · 29.100.939 | CC0 (Met Open Access) | recorded | record | ed729c725b |
rb-08 | Rembrandt | Walking Man in a High Cap c. 1655 - c. 1660 | Rijksmuseum, Amsterdam · RP-T-1930-40 | Public domain (Rijksmuseum) | recorded | record | 0cdb720b4e |
rb-09 | Rembrandt | Recumbent Lion c. 1660 | Rijksmuseum, Amsterdam · RP-T-1901-A-4524 | Public domain (Rijksmuseum) | recorded | record | 247ff6702e |
rb-10 | Rembrandt | Nude Woman Lying on a Pillow c. 1661 - c. 1662 | Rijksmuseum, Amsterdam · RP-T-1917-1 | Public domain (Rijksmuseum) | recorded | record | 710a44d86b |
rb-11 | Rembrandt | The Meeting of Christ with Martha and Mary after the Death of Lazarus c. 1662–65 | Cleveland Museum of Art · 1962.116 | CC0 (Cleveland Open Access) | recorded | record | ed80f47e44 |
rb-12 | Rembrandt | Woman Reading 1606–69 | The Metropolitan Museum of Art · 26.208 | CC0 (Met Open Access) | recorded | record | 6923241b66 |
vg-01 | Van Gogh | Avenue of Pollard Birches and Poplars March 1884 | Art Institute of Chicago · 2022.74 | CC0 (AIC public domain) | recorded | record | 9531a10d4d |
vg-02 | Van Gogh | Road behind the Parsonage Garden in Nuenen 1884-03 | Rijksmuseum, Amsterdam · SK-A-2225 | Public domain (Rijksmuseum) | recorded | record | 5a692c3d4d |
vg-03 | Van Gogh | Pollard Birches with Shepherd March 1884 | Van Gogh Museum, Amsterdam · F1240 | Public domain (PD-Art, via Wikimedia Commons) | recorded | record | e1895de2e9 |
vg-04 | Van Gogh | Tetards (Pollards) 1884 | Art Institute of Chicago · 1969.268 | CC0 (AIC public domain) | recorded | record | b9286729af |
vg-05 | Van Gogh | Farm in Provence c. 1888-06 | Rijksmuseum, Amsterdam · SK-A-2226 | Public domain (Rijksmuseum) | recorded | record | e5983205a7 |
vg-06 | Van Gogh | Hill with the ruins of Montmajour 1888 | Rijksmuseum, Amsterdam · RP-T-1962-65 | Public domain (Rijksmuseum) | recorded | record | 34a2ed534f |
vg-07 | Van Gogh | Wheat Field July 1888 | The Metropolitan Museum of Art · 64.125.3 | CC0 (Met Open Access) | recorded | record | b2c050fe4f |
vg-08 | Van Gogh | Street in Saintes-Maries-de-la-Mer ca. July 15, 1888 | The Metropolitan Museum of Art · 48.190.1 | CC0 (Met Open Access) | recorded | record | 2a0be6b9d7 |
vg-09 | Van Gogh | La Crau seen from Montmajour July 1888 | Van Gogh Museum, Amsterdam · (F1420) | Public domain (PD-Art, via Wikimedia Commons) | recorded | record | 7fc80d2aa6 |
vg-10 | Van Gogh | Rocky Hill with Trees, Montmajour July 1888 | Van Gogh Museum, Amsterdam · | Public domain (PD-Art, via Wikimedia Commons) | recorded | record | e4dde87795 |
vg-11 | Van Gogh | Garden of the Hospital in Arles April 1889 | Van Gogh Museum, Amsterdam · | Public domain (PD-Art, via Wikimedia Commons) | recorded | record | 1e4fa2826b |
vg-12 | Van Gogh | Fountain in the Garden of Saint-Paul Hospital May 1889 | Van Gogh Museum, Amsterdam · | Public domain (PD-Art, via Wikimedia Commons) | recorded | record | 5a7c8d70a7 |
vg-13 | Van Gogh | Trees with Ivy and a Bench in the Garden of Saint-Paul Hospital May 1889 | Van Gogh Museum, Amsterdam · | Public domain (PD-Art, via Wikimedia Commons) | recorded | record | e977654e22 |
vg-14 | Van Gogh | Weeping Tree 1889 | Art Institute of Chicago · 1945.31 | CC0 (AIC public domain) | recorded | record | 9ee63355c0 |
vg-15 | Van Gogh | Cypresses 1889 | Art Institute of Chicago · 1927.543 | CC0 (AIC public domain) | recorded | record | 6d7d1d9c90 |
vg-16 | Van Gogh | The Enclosed Wheatfield after a Storm July 1889 | Van Gogh Museum, Amsterdam · d0336V1962 (F1547) | Public domain (PD-Art, via Wikimedia Commons) | recorded | record | a920da7777 |
met-dp-12952-001 | commons | Broken Eggs Jean-Baptiste Greuze 1756 | objectID 436579 · 20.155.8 | Met Open Access assumed | matched | record | 1f4b11f001 |
met-dp-1411-001 | commons | Baron Alexander von Humboldt (1769–1859) Julius Schrader 1859 | objectID 437640 · 89.20 | Met Open Access assumed | matched | record | 458839c0d5 |
met-dp-14201-001 | commons | The Shepherd's Song Pierre Puvis de Chavannes 1891 | objectID 437344 · 06.177 | Met Open Access assumed | matched | record | 96bf6c0d8b |
met-dp-14345-001 | commons | The Natchez Eugène Delacroix 1823–24 and 1835 | objectID 436180 · 1989.328 | Met Open Access assumed | matched | record | 4b4da22dd7 |
met-dp-14936-033 | commons | Dancers, Pink and Green Edgar Degas ca. 1890 | objectID 436140 · 29.100.42 | Met Open Access assumed | matched | record | e962620c60 |
met-dp-14976-001 | commons | Reclining Nude Auguste Renoir 1883 | objectID 438013 · 2003.20.12 | Met Open Access assumed | matched | record | 8d70b168ac |
met-dp-15576-001 | commons | The Hall of Antiquities at Charlottenborg Palace, Copenhagen Adam August Müller 1830 | objectID 780292 · 2018.280 | Met Open Access assumed | matched | record | 308760419d |
met-dp-17451-001 | commons | Beaulieu: The Bay of Fourmis Eugène Boudin 1892 | objectID 435750 · 39.65.2 | Met Open Access assumed | matched | record | 792a6390b6 |
met-dp-17679-001 | commons | The Dead Christ with Angels Edouard Manet 1864 | objectID 436950 · 29.100.51 | Met Open Access assumed | matched | record | 617aa480a5 |
met-dp-19488-001 | commons | The Net Mender (Garnbinderen) Christian Krohg 1879 | objectID 839045 · 2020.84.3 | Met Open Access assumed | matched | record | 7564041f46 |
met-dp-19540-001 | commons | A Deerhound Sir Edwin Henry Landseer 1826 | objectID 782306 · 2018.289.4 | Met Open Access assumed | matched | record | c18c64792a |
met-dp-19709-001 | commons | Antoine Laurent Lavoisier (1743–1794) and Marie Anne Lavoisier (Marie Anne Pierrette Paulze, 1758–1836) Jacques Louis David 1788 | objectID 436106 · 1977.10 | Met Open Access assumed | matched | record | a495ecee1e |
met-dp-20099-001 | commons | Mont Sainte-Victoire and the Viaduct of the Arc River Valley Paul Cézanne 1882–85 | objectID 435877 · 29.100.64 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | bdf7852793 |
met-dp-20101-001 | commons | The Dance Class Edgar Degas 1874 | objectID 438817 · 1987.47.1 | Met Open Access assumed | matched | record | 524fd2c885 |
met-dp-20645-001 | commons | Going Home Fritz von Uhde ca. 1889 | objectID 437860 · 17.120.203 | Met Open Access assumed | matched | record | 2bca70575b |
met-dp-21954-001 | commons | Barges at Pontoise Camille Pissarro 1876 | objectID 437302 · 1979.135.16 | Met Open Access assumed | matched | record | 68c524be33 |
met-dp-21955-001 | commons | Washerwoman, Study Camille Pissarro 1880 | objectID 437303 · 56.184.1 | Met Open Access assumed | matched | record | 64f01bc35d |
met-dp-22432-001 | commons | The Birth of Venus Alexandre Cabanel 1875 | objectID 435831 · 94.24.1 | Met Open Access assumed | matched | record | cbbdd6cda1 |
met-dp-23372-001 | commons | Study of a Nude Man Pierre Narcisse Guérin ca. 1810–20 | objectID 436406 · 52.71 | Met Open Access assumed | matched | record | 05c23e03a4 |
met-dp-25035-001 | commons | Study of a Nude Man Gustave Courbet early 1840s | objectID 848137 · 2021.30 | Met Open Access assumed | matched | record | 235f237d72 |
met-dp-25446-001 | commons | The Singer in Green Edgar Degas ca. 1884 | objectID 436159 · 61.101.7 | Met Open Access assumed | matched | record | 4cacf3c5f8 |
met-dp-25466-001 | commons | Boating Edouard Manet 1874 | objectID 436947 · 29.100.115 | Met Open Access assumed | matched | record | 3ec0e52843 |
met-dp-25649-001 | commons | Mademoiselle V. . . in the Costume of an Espada Edouard Manet 1862 | objectID 436945 · 29.100.53 | Met Open Access assumed | matched | record | 423e398a85 |
met-dp123961 | commons | A Limier Briquet Hound Rosa Bonheur ca. 1856 | objectID 435704 · 87.15.77 | Met Open Access assumed | matched | record | f250751e23 |
met-dp124808 | commons | First Steps, after Millet Vincent van Gogh 1890 | objectID 436526 · 64.165.2 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | c0e41b79fb |
met-dp131000 | commons | Race Horses Edgar Degas ca. 1885–88 | objectID 437994 · 1999.288.3 | Met Open Access assumed | matched | record | 676a51753b |
met-dp136056 | commons | Landscape Carl Rottmann ca. 1835–45 | objectID 438849 · 2006.116 | Met Open Access assumed | matched | record | b49278a284 |
met-dp136266 | commons | View of the Seacoast near Wargemont in Normandy Auguste Renoir 1880 | objectID 437426 · 56.135.7 | Met Open Access assumed | matched | record | 7bf0883b1d |
met-dp154560 | commons | Saint Peter Martyr Healing the Leg of a Young Man Antonio Vivarini ca. 1450 | objectID 437909 · 37.163.4 | Met Open Access assumed | matched | record | 2056ad5abb |
met-dp160821 | commons | Frieda Schiff (1876–1958), Later Mrs. Felix M. Warburg Anders Zorn 1894 | objectID 437964 · 1988.72 | Met Open Access assumed | matched | record | 1d1c14e136 |
met-dp169319 | commons | Woman Standing Beside a Balustrade with a Poodle Paul Ranson ca. 1895 | objectID 496203 · 2008.660 | Met Open Access assumed | matched | record | c840407734 |
met-dp169386 | commons | Pallas Athena and the Herdsman's Dogs Briton Riviere 1876 | objectID 437467 · 1980.510.3 | Met Open Access assumed | matched | record | 80d9530c9b |
met-dp169404 | commons | Harbor Scene: An English Ship with Sails Loosened Firing a Gun Peter Monamy | objectID 437103 · 60.94.2 | Met Open Access assumed | matched | record | 4a1e8d3bd2 |
met-dp169441 | commons | Edge of a Wood Théodore Caruelle d'Aligny ca. 1850 | objectID 438618 · 2003.42.1 | Met Open Access assumed | matched | record | 786af30c9d |
met-dp169460 | commons | An Ottoman Man in the Artist's Studio Auguste-Xavier Leprince ca. 1823–26 | objectID 438662 · 2003.42.39 | Met Open Access assumed | matched | record | a87d8e7fdf |
met-dp169651 | commons | Kynance John Brett 1888 | objectID 435775 · 1974.289.2 | Met Open Access assumed | matched | record | c590d806ce |
met-dp170905 | commons | The Drummond Children Sir Henry Raeburn ca. 1808–9 | objectID 437354 · 50.145.31 | Met Open Access assumed | matched | record | efe6ff1e45 |
met-dp207320 | commons | Gathering Wood Anton Mauve | objectID 437041 · 43.86.8 | Met Open Access assumed | matched | record | 552e36456c |
met-dp232029 | commons | Two Dancers, Half-length Edgar Degas | objectID 436167 · 1974.356.31 | Met Open Access assumed | matched | record | b3fc8cee5d |
met-dp253480 | commons | Woman Having Her Hair Combed Edgar Degas ca. 1886–88 | objectID 436173 · 29.100.35 | Met Open Access assumed | matched | record | 02ad1124fe |
met-dp253483 | commons | Woman Bathing in a Shallow Tub Edgar Degas 1885 | objectID 436127 · 29.100.41 | Met Open Access assumed | matched | record | f65319a623 |
met-dp267027 | commons | A Spanish Garden Martín Rico y Ortega 1871 | objectID 437462 · 81.1.666 | Met Open Access assumed | matched | record | a982b21a81 |
met-dp273105 | commons | Moonlight, Strandgade 30 Vilhelm Hammershøi 1900–1906 | objectID 441933 · 2012.203 | Met Open Access assumed | matched | record | 418da7d5d0 |
met-dp273977 | commons | Young Lady in 1866 Edouard Manet 1866 | objectID 436964 · 89.21.3 | Met Open Access assumed | matched | record | a9769c4d71 |
met-dp318843 | commons | The Dream of the Shepherd (Der Traum des Hirten) Ferdinand Hodler 1896 | objectID 634108 · 2013.1134 | Met Open Access assumed | matched | record | 59bfb40e65 |
met-dp320128 | commons | Madame Cézanne (Hortense Fiquet, 1850–1922) in a Red Dress Paul Cézanne 1888–90 | objectID 435876 · 62.45 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | b239355055 |
met-dp346474 | commons | Irises Vincent van Gogh 1890 | objectID 436528 · 58.187 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | 2f7cf0ebbf |
met-dt10159 | commons | The Empress Eugénie (Eugénie de Montijo, 1826–1920, Condesa de Teba) Franz Xaver Winterhalter 1854 | objectID 437942 · 1978.403 | Met Open Access assumed | matched | record | cd210f6195 |
met-dt1027 | commons | Still Life with Teapot and Fruit Paul Gauguin 1896 | objectID 437999 · 1997.391.2 | Met Open Access assumed | matched | record | 50fa62c222 |
met-dt10724 | commons | General Garibaldi's Residence at Caprera Frederick Richard Lee 1865 | objectID 436863 · 1974.159 | Met Open Access assumed | matched | record | 2d4c21ded8 |
met-dt1396 | commons | L'Arlésienne: Madame Joseph-Michel Ginoux (Marie Julien, 1848–1911) Vincent van Gogh 1888–89 | objectID 436529 · 51.112.3 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | c5d5973175 |
met-dt1479 | commons | The Annunciation Petrus Christus ca. 1445 | objectID 435899 · 32.100.35 | Met Open Access assumed | matched | record | 08375c7fbd |
met-dt1494 | commons | Oleanders Vincent van Gogh 1888 | objectID 436530 · 62.24 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | 605609e76c |
met-dt1500 | commons | The Englishman (William Tom Warrener, 1861–1934) at the Moulin Rouge Henri de Toulouse-Lautrec 1892 | objectID 437835 · 67.187.108 | Met Open Access assumed | matched | record | 76a1b52f25 |
met-dt1556 | commons | A Cowherd at Valhermeil, Auvers-sur-Oise Camille Pissarro 1874 | objectID 437300 · 56.182 | Met Open Access assumed | matched | record | 88785ad72e |
met-dt1558 | commons | Honfleur Johan Barthold Jongkind 1865 | objectID 436785 · 16.39 | Met Open Access assumed | matched | record | d544183805 |
met-dt1559 | commons | The Garden of the Tuileries on a Winter Afternoon Camille Pissarro 1899 | objectID 437314 · 66.36 | Met Open Access assumed | matched | record | 583edf5b87 |
met-dt1565 | commons | The Rehearsal of the Ballet Onstage Edgar Degas ca. 1874 | objectID 436155 · 29.160.26 | Met Open Access assumed | matched | record | 3d406ad139 |
met-dt1859 | commons | Jalais Hill, Pontoise Camille Pissarro 1867 | objectID 437299 · 51.30.2 | Met Open Access assumed | matched | record | dd9ddf92c6 |
met-dt1879 | commons | The Daughters of Catulle Mendès, Huguette (1871–1964), Claudine (1876–1937), and Helyonne (1879–1955) Auguste Renoir 1888 | objectID 438014 · 1998.325.3 | Met Open Access assumed | matched | record | 5e8fa87960 |
met-dt1882 | commons | Eugène Murer (Hyacinthe-Eugène Meunier, 1841–1906) Auguste Renoir 1877 | objectID 438011 · 2003.20.9 | Met Open Access assumed | matched | record | 3c7fa544d4 |
met-dt1883 | commons | The Dance Lesson Edgar Degas ca. 1879 | objectID 436132 · 1971.185 | Met Open Access assumed | matched | record | dd3af064d9 |
met-dt1910 | commons | A Woman Ironing Edgar Degas 1873 | objectID 436174 · 29.100.46 | Met Open Access assumed | matched | record | 32a867627e |
met-dt1912 | commons | Portrait of a Woman in Gray Edgar Degas ca. 1865 | objectID 436152 · 57.171 | Met Open Access assumed | matched | record | b80c134682 |
met-dt1917 | commons | Woman Combing Her Hair Edgar Degas ca. 1888–90 | objectID 436170 · 56.231 | Met Open Access assumed | matched | record | c249bfbf61 |
met-dt1924 | commons | The Sofa Henri de Toulouse-Lautrec ca. 1894–96 | objectID 437837 · 51.33.2 | Met Open Access assumed | matched | record | 3d828b5aa4 |
met-dt1926 | commons | Madame Jacques-Louis Leblanc (Françoise Poncelle, 1788–1839) Jean Auguste Dominique Ingres 1823 | objectID 436703 · 19.77.2 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | ac469f3697 |
met-dt1927 | commons | The Pink Dress (Albertie-Marguerite Carré, later Madame Ferdinand-Henri Himmes, 1854–1935) Berthe Morisot ca. 1870 | objectID 438009 · 2003.20.8 | Met Open Access assumed | matched | record | 7505dd7d09 |
met-dt1933 | commons | A Matador Edouard Manet 1866–67 | objectID 436960 · 29.100.52 | Met Open Access assumed | matched | record | 2bdcf7f320 |
met-dt1939 | commons | Dish of Apples Paul Cézanne ca. 1876–77 | objectID 437989 · 1997.60.1 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | a556f0fa8f |
met-dt1943 | commons | The House with the Cracked Walls Paul Cézanne 1892–94 | objectID 435874 · 1993.400.2 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | bef3b0ad21 |
met-dt1947 | commons | Shoes Vincent van Gogh 1888 | objectID 436533 · 1992.374 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | 5499ad3457 |
met-dt1952 | commons | The Siesta Paul Gauguin ca. 1892–94 | objectID 436449 · 1993.400.3 | Met Open Access assumed | matched | record | b4d895bf46 |
met-dt1954 | commons | Three Tahitian Women Paul Gauguin 1896 | objectID 438000 · 1997.60.3 | Met Open Access assumed | matched | record | 1bf199a61c |
met-dt1973 | commons | The Calm Sea Gustave Courbet 1869 | objectID 436005 · 29.100.566 | Met Open Access assumed | matched | record | 796e854b59 |
met-dt1977 | commons | Antoine Dominique Sauveur Aubert (born 1817), the Artist's Uncle, as a Monk Paul Cézanne 1866 | objectID 435869 · 1993.400.1 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | cd79f3d4fc |
met-dt1978 | commons | Woman with a Rake Jean-François Millet probably 1856–57 | objectID 437099 · 38.75 | Met Open Access assumed | matched | record | 169729cbd3 |
met-dt1980 | commons | Still Life with Flowers and Fruit Henri Fantin-Latour 1866 | objectID 436293 · 1980.3 | Met Open Access assumed | matched | record | e24aa4f698 |
met-dt2000 | commons | Jerusalem from the Mount of Olives Charles-Théodore Frère by 1880 | objectID 436418 · 87.15.106 | Met Open Access assumed | matched | record | c42f82703d |
met-dt2006 | commons | Alfred Dedreux (1810–1860) as a Child Théodore Géricault ca. 1819–20 | objectID 436454 · 41.17 | Met Open Access assumed | matched | record | c69932db0a |
met-dt2010 | commons | Reverie Camille Corot 1857 or later | objectID 435981 · 29.100.563 | Met Open Access assumed | matched | record | 04f53867aa |
met-dt2013 | commons | Hagar in the Wilderness Camille Corot 1835 | objectID 435962 · 38.64 | Met Open Access assumed | matched | record | 1bbaeb9d8e |
met-dt209324 | commons | Graziella Jules-Joseph Lefebvre 1878 | objectID 436866 · 87.15.111 | Met Open Access assumed | matched | record | bcac368124 |
met-dt2130 | commons | Still Life with Ham Philippe Rousseau 1870s | objectID 437513 · 1982.320 | Met Open Access assumed | matched | record | 97beb5eee6 |
met-dt2141 | commons | The Laundress Honoré Daumier 186[3?] | objectID 436091 · 47.122 | Met Open Access assumed | matched | record | 637a1c8a25 |
met-dt2159 | commons | Vase of Flowers (Pink Background) Odilon Redon ca. 1906 | objectID 437382 · 59.16.3 | Met Open Access assumed | matched | record | 339ae1e7b3 |
met-dt2163 | commons | Peasant Woman Cooking by a Fireplace Vincent van Gogh 1885 | objectID 436531 · 1984.393 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | 8f59706385 |
met-dt2167 | commons | Albert (René) Grenier (1858–1925) Henri de Toulouse-Lautrec 1887 | objectID 437836 · 1979.135.14 | Met Open Access assumed | matched | record | 84520ae294 |
met-dt224757 | commons | Penelope Charles-François Marchal ca. 1868 | objectID 436970 · 17.138.2 | Met Open Access assumed | matched | record | fd6cf52aa2 |
met-dt234058 | commons | An Egyptian Peasant Woman and Her Child Léon Bonnat 1869–70 | objectID 435711 · 87.15.97 | Met Open Access assumed | matched | record | 3bfe905d4d |
met-dt2553 | commons | Countess Alexander Nikolaevitch Lamsdorff (Maria Ivanovna Beck, 1835–1866) Franz Xaver Winterhalter 1859 | objectID 437943 · 67.187.119 | Met Open Access assumed | matched | record | 331fe265bb |
met-dt2566 | commons | Breton Brother and Sister William Bouguereau 1871 | objectID 435754 · 87.15.32 | Met Open Access assumed | matched | record | 86fa556118 |
met-dt403 | commons | Jacques-Louis Leblanc (1774–1846) Jean Auguste Dominique Ingres 1823 | objectID 436706 · 19.77.1 | Met Open Access assumed | matched excluded: paid artist in the unpaid pool | record | ca3d7f8b5d |
met-dt4937 | commons | View near Rouen Richard Parkes Bonington ca. 1825 | objectID 438449 · 2001.45 | Met Open Access assumed | matched | record | 5b1d49dab6 |
met-dt50 | commons | The Repast of the Lion Henri Rousseau (le Douanier) ca. 1907 | objectID 438822 · 51.112.5 | Met Open Access assumed | matched | record | 5b6b198a25 |
met-dt8475 | commons | In the Studio Alfred Stevens 1888 | objectID 437755 · 1986.339.2 | Met Open Access assumed | matched | record | 507558dec2 |
met-dt872-1 | commons | In the Studio Alfred Stevens 1888 | objectID 437755 · 1986.339.2 | Met Open Access assumed | duplicate download of met-dt872 excluded (duplicate) | record | b71e270b9b |
met-dt872 | commons | Portrait of a Child Camille Corot ca. 1835 | objectID 435980 · 29.100.564 | Met Open Access assumed | matched | record | 86082595a8 |
met-dt9199 | commons | Asters and Fruit on a Table Henri Fantin-Latour 1868 | objectID 437997 · 2001.202.3 | Met Open Access assumed | matched | record | 36f8196a1f |
met-dp130799 | commons | The Spanish Singer Edouard Manet 1860 | objectID 436944 · 49.58.2 | Met Open Access assumed | matched | record | 136b67c645 |
msv-a | msv | A. Toward Mont Sainte-Victoire (Vers la Montagne Sainte-Victoire) | · | public domain by age (Cézanne d. 1906) | work PD, image source unrecorded | 9c74829cea | |
msv-b | msv | B. Mont Sainte-Victoire and the Viaduct of the Arc River Valley | · | public domain by age (Cézanne d. 1906) | work PD, image source unrecorded | 9b441655ee | |
msv-c | msv | C. Montagne Sainte-Victoire with Large Pine | · | public domain by age (Cézanne d. 1906) | work PD, image source unrecorded | d666f41552 | |
msv-d | msv | D. Montagne Sainte-Victoire | · | public domain by age (Cézanne d. 1906) | work PD, image source unrecorded | d6c558055b | |
msv-e | msv | E. Mont Sainte-Victoire (La Montagne Sainte-Victoire) | · | public domain by age (Cézanne d. 1906) | work PD, image source unrecorded | 9a58d78169 | |
msv-f | msv | F. Mont Sainte-Victoire | · | public domain by age (Cézanne d. 1906) | work PD, image source unrecorded | 5e805cebce | |
msv-g | msv | G. Mont Sainte-Victoire | · | public domain by age (Cézanne d. 1906) | work PD, image source unrecorded | b7ced7b516 | |
msv-h | msv | H. Mont Sainte-Victoire | · | public domain by age (Cézanne d. 1906) | work PD, image source unrecorded | 43a8611a09 | |
msv-i | msv | I. Mont Sainte-Victoire | · | public domain by age (Cézanne d. 1906) | work PD, image source unrecorded | d9711b06f6 |
6. Duplicates
20910 pairs compared. Identical files: 0. Identical pixels: 0. Near-duplicates (normalised RMS distance below 0.35):
met-dt872-1andmet-dt872: distance 0.0
Pair-distance percentiles: 0.1th 0.6008, 1st 0.8021, 5th 0.9919, median 1.2973.
Interpretation. The one near-duplicate is the same painting saved as two differently encoded files. Hash and pixel checks miss it, and because views are seeded from the id, the two copies even produce different training views. Dedupe now runs on the source image. This is the duplicate-gaming case of the brief, met naturally.
7. Measurement: does use-based credit over-pay blank paper?
Rule fixed in LOG.md before the run: F ≥ 2 in 3 of 4 seeds, pool paper use mass; F ≤ 1 in 3 of 4, no policy; otherwise inconclusive.
| Seed | Paper share of artists' use | Removal effect, paper | Removal effect, marks | F |
|---|---|---|---|---|
| 5000 | 0.801 | 0.216 | 0.018 | 0.334 |
| 5001 | 0.690 | 0.145 | 0.020 | 0.298 |
| 5002 | 0.721 | 0.146 | 0.017 | 0.301 |
| 5003 | 0.633 | 0.153 | 0.028 | 0.318 |
Verdict: NOT OVER-CREDITED: no policy
Paper fraction of each artist's use mass, per seed
| Artist | 5000 | 5001 | 5002 | 5003 |
|---|---|---|---|---|
| Cézanne | 0.823 | 0.817 | 0.822 | 0.751 |
| Dürer | 0.901 | 0.828 | 0.843 | 0.810 |
| Ingres | 0.906 | 0.903 | 0.907 | 0.883 |
| Kollwitz | 0.616 | 0.478 | 0.518 | 0.429 |
| Rembrandt | 0.802 | 0.672 | 0.709 | 0.637 |
| Van Gogh | 0.714 | 0.620 | 0.628 | 0.571 |
Interpretation. Paper is not over-credited; by consequence it is under-credited. The reason matters more than the verdict: at 32 px a pen or graphite stroke is under one pixel wide, so the outputs are paper-toned blotches and removing every mark barely changes them. At this scale the instrument would pay artists for the colour of their paper. This became requirement O12.
8. Test: can a tighter crop make the marks matter (O12)?
Rule fixed in LOG.md before the run: a configuration passes if Q = Rmark / Rpaper ≥ 1 in at least 3 of 4 seeds; among passing ones prefer the largest crop, then uniform placement.
| Configuration | Q per seed | Mark share of artists' use | O12 |
|---|---|---|---|
| crop 256 px, uniform | 0.086, 0.135, 0.118, 0.176 | 0.206, 0.312, 0.287, 0.372 | fail |
| crop 256 px, marks | 0.129, 0.174, 0.167, 0.229 | 0.266, 0.374, 0.341, 0.423 | fail |
| crop 128 px, uniform | 0.097, 0.139, 0.115, 0.186 | 0.224, 0.332, 0.306, 0.400 | fail |
| crop 128 px, marks | 0.171, 0.223, 0.211, 0.328 | 0.351, 0.451, 0.428, 0.512 | fail |
| crop 64 px, uniform | 0.102, 0.170, 0.130, 0.206 | 0.249, 0.372, 0.339, 0.438 | fail |
| crop 64 px, marks | 0.253, 0.294, 0.336, 0.418 | 0.450, 0.529, 0.514, 0.594 | fail |
Choice: None
Interpretation (written after the result). The crops worked on the training data: at 64 px strokes are several pixels wide, and the marks' share of use rises from about 0.2 to 0.6 with tighter, mark-centred crops. Q stays below 1 because the criterion compares removing all paper with removing all marks under pixel MSE, which weights area; even a resolved drawing is mostly paper. The criterion measured whether marks dominate the area, not whether they carry the hand. A measurement-design error in O12 as written.
Second test: the edge value function (designed after the first test, registered before it ran)
Same corpus builds, seeds and conditions for the two 64 px configurations; removal effect measured on Sobel edge maps of luminance instead of pixels. Pass: Qedges ≥ 1 in at least 3 of 4 seeds.
| Configuration | Q edges per seed | Q pixel per seed | Pixel Q reproduces test 1 | Result |
|---|---|---|---|---|
| crop 64 px, marks | 1.462, 1.065, 1.920, 1.891 | 0.253, 0.294, 0.336, 0.418 | yes | pass |
| crop 64 px, uniform | 0.744, 0.882, 0.878, 1.089 | 0.102, 0.170, 0.130, 0.206 | yes | fail |
Confirmation on the final corpus (paid-artist works removed from the commons)
Registered before it ran: the chosen configuration re-run on the corpus as it now stands, same seeds, same rule. The pixel Q is expected to differ from the first test here, because the corpus changed.
| Configuration | Commons size | Q edges per seed | Q pixel per seed | Result |
|---|---|---|---|---|
| crop 64 px, marks | 86 | 1.598, 1.142, 2.391, 2.171 | 0.272, 0.316, 0.353, 0.460 | pass |
Exclusions in force: 14 (met-dp-20099-001, met-dp124808, met-dp320128, met-dp346474, met-dt1396, met-dt1494, met-dt1926, met-dt1939, met-dt1943, met-dt1947, met-dt1977, met-dt2163, met-dt403, met-dt872-1).
9. M3: the removal instrument's first run
Protocol measure/M3_PROTOCOL.md, frozen before any run (measure/m3_freeze.json). Game A: the six artists, commons as baseline. Games B and C: planted controls with and without the duplicate. Seeds 6000 to 6003; exact Shapley over all 64 coalitions.
| ID | Result | Numbers |
|---|---|---|
| K1 efficiency | holds | max error 5.6e-17 |
| K2 symmetry du-01 == duplicate | holds | max relative difference 9.3e-05 |
| T1 | holds | tv use shapley [0.400, 0.346, 0.488, 0.297] median 0.373 |
| T1e | holds | tv use shapley [0.363, 0.308, 0.346, 0.323] median 0.335 |
| T2a | fails | most substitutable pair per seed [[ingres, vangogh], [cezanne, ingres], [rembrandt, vangogh], [cezanne, ingres]] |
| T2b | fails | loo below shapley for both per seed [False, False, True, True] |
| T4 | fails | paper fraction of artist use [0.297, 0.371, 0.168, 0.434] median 0.334 |
| T5b | holds | pair over alone [2.021, 2.003, 2.008, 1.974] median 2.006 |
| T5c | holds | scrambled share pixel [0.000, 0.000, 0.000, 0.000]; edges [0.015, 0.000, 0.000, 0.000]; blur [0.000, 0.000, 0.000, 0.000]; colour [0.000, 0.000, 0.000, 0.000] |
| T5d | fails | constant share pixel [0.052, 0.056, 0.064, 0.052]; edges [0.029, 0.026, 0.044, 0.034]; blur [0.054, 0.058, 0.067, 0.054]; colour [0.058, 0.056, 0.066, 0.051] |
| T6a | holds | top artist per seed [ingres, ingres, vangogh, ingres] |
| T6b | holds | ranking per seed [[ingres, cezanne, durer, vangogh, rembrandt, kollwitz], [ingres, cezanne, durer, rembrandt, kollwitz, vangogh], [vangogh, ingres, durer, cezanne, rembrandt, kollwitz], [ingres, cezanne, durer, rembrandt, vangogh, kollwitz]] |
Shares by rule, edges value function, four seeds
Post hoc: how visible is removing one artist?
| Seed | Cézanne | Dürer | Ingres | Kollwitz | Rembrandt | Van Gogh | All six |
|---|---|---|---|---|---|---|---|
| 6000 | 6.06 (27%) | 4.55 (17%) | 8.15 (42%) | 2.78 (8%) | 3.0 (8%) | 2.15 (4%) | 30.4 (88%) |
| 6001 | 7.17 (34%) | 5.07 (19%) | 9.29 (50%) | 2.98 (7%) | 3.17 (9%) | 2.39 (6%) | 37.54 (98%) |
| 6002 | 5.63 (20%) | 4.41 (13%) | 7.5 (34%) | 3.04 (8%) | 2.69 (6%) | 3.26 (10%) | 27.87 (94%) |
| 6003 | 6.53 (28%) | 4.55 (14%) | 9.13 (48%) | 2.42 (6%) | 2.31 (5%) | 1.9 (4%) | 38.57 (98%) |
Mean absolute change in 0 to 255 levels (fraction of values changing by more than 8 levels). Not predicted; computed after the verdicts.
Interpretation. The instrument measures exactly (efficiency to 1e-16, the duplicate symmetric) and separates use from consequence by about a third of the money. The constant control earning 3 to 7% shows removal credit paying for trajectory perturbation through the t = 1 average; that needs a design fix, registered before testing, before any payout is shown. Single artists move the picture only a few levels; the page shows the difference map with an adjustable gain.
10. The t = 1 vote and its fix (T0FIX)
M3's constant control (a source of nonsense images) earned 3 to 7% of the credit. Two exploratory diagnostics, then a protocol frozen before its run (measure/T0FIX_PROTOCOL.md).
Diagnostic 1: how much of a source's removal effect enters at t = 1?
| Source | Share explained by step 0 (seeds 6000 to 6003) |
|---|---|
| CONTROL-constant | 1.00, 1.00, 1.00, 1.00 |
| CONTROL-scrambled | 0.08, 0.51, 0.18, 0.65 |
| du-01 | 0.52, 0.53, 0.60, 0.50 |
Interpretation. At t = 1 the posterior ignores the picture: every source votes by head count in a blind average, and the trajectory carries the shift. All of the constant's effect, and half of a real sheet's, is that vote.
Diagnostic 2: chaos floor, leave-one-out effects (pixel MSE)
| Schedule | Seed | Constant | Scrambled | du-01 | Chaos floor |
|---|---|---|---|---|---|
| S0 | 6000 | 4.05e-04 | 3.18e-04 | 4.28e-05 | 2.39e-12 |
| S0 | 6001 | 4.90e-04 | 5.17e-05 | 5.17e-05 | 1.45e-12 |
| S0 | 6002 | 6.55e-04 | 2.16e-04 | 3.85e-05 | 1.92e-12 |
| S0 | 6003 | 4.07e-04 | 4.10e-05 | 5.52e-05 | 3.17e-12 |
| S1 | 6000 | 1.90e-09 | 1.40e-04 | 1.92e-05 | 3.02e-12 |
| S1 | 6001 | 1.52e-09 | 3.14e-05 | 1.09e-04 | 2.14e-12 |
| S1 | 6002 | 2.29e-12 | 1.78e-04 | 7.93e-06 | 2.81e-12 |
| S1 | 6003 | 1.47e-07 | 1.46e-05 | 2.45e-05 | 2.17e-12 |
T0FIX results (schedule S1, paired with M3)
| ID | Result | Numbers |
|---|---|---|
| K1 efficiency | holds | max error 2.8e-17 |
| K2 symmetry | fails | max relative difference 1.4e-04 |
| F1 | holds | constant share pixel [1.4e-04, 1.4e-04, 4.8e-06, 0.003]; edges [1.2e-04, 5.2e-05, 3.9e-06, 7.1e-04]; blur [1.6e-04, 1.6e-04, 5.6e-06, 0.004]; colour [7.8e-04, 1.7e-05, 0.000, 0.003] |
| F2 | holds | scrambled share pixel [0.000, 0.000, 0.000, 0.000]; edges [0.008, 0.000, 0.003, 0.004]; blur [0.000, 0.000, 0.000, 0.000]; colour [0.000, 0.000, 0.000, 0.000] |
| F3 | holds | pair over alone [2.018, 1.890, 2.043, 1.903] median 1.960 |
| F4 | holds | tv use shapley [0.383, 0.334, 0.380, 0.295] median 0.357 |
| F5 | holds | top artist [ingres, ingres, vangogh, ingres] |
| F6 | holds | tv S0 S1 [0.099, 0.101, 0.187, 0.138] median 0.119 |
K2 re-check on the float64 reference (registered after the results, before running)
| Quantity | Value |
|---|---|
| seed | 6002 |
| schedule | S1 |
| dtype | float64 CPU |
| seconds | 1712.900 |
| max_abs_output_difference_symmetric_pairs | 6.3e-14 |
| phi_du01_minus_phi_dup | pixel 3.4e-18; edges 9.5e-18; blur 4.2e-19; colour 0.000 |
| relative_to_float32_phi_du01 | pixel 1.7e-14; edges 2.6e-14; blur 2.2e-15; colour 0.000 |
| holds | True |
HOLDS: S1 adopted (instrument/config.py)
11. How big a pool can the demo keep?
Rule fixed in LOG.md before the run: an artist is visible at pool size N if its median removal change is at least 5 levels of 255; choose the largest N with at least 4 of 6 visible, else the smallest tested. Schedule S1, seeds 8000 to 8003.
| Pool N | Cézanne | Dürer | Ingres | Kollwitz | Rembrandt | Van Gogh | Visible | Artists' use |
|---|---|---|---|---|---|---|---|---|
| 86 | 3.59 | 2.82 | 4.72 | 2.69 | 2.20 | 2.38 | 0 | 0.47, 0.54, 0.44, 0.44 |
| 43 | 4.22 | 3.23 | 5.53 | 3.96 | 2.59 | 3.00 | 1 | 0.64, 0.71, 0.61, 0.61 |
| 21 | 4.88 | 3.30 | 6.33 | 5.54 | 2.71 | 3.50 | 2 | 0.77, 0.84, 0.78, 0.75 |
| 10 | 4.84 | 3.23 | 6.50 | 6.75 | 2.78 | 4.17 | 2 | 0.87, 0.92, 0.88, 0.86 |
Choice: pool of 10 (none passed: smallest N)
Interpretation. A smaller pool raises the artists' share of the picture from about half to about nine tenths, but a single artist's removal levels off at 3 to 7 levels: the other five hands fill in. The page shows single removals through the difference map, with the gain stated.
12. Receipts, verifier and the page
Receipts (receipt/make.py, format take-it-out-receipt/1) record generator and corpus hashes, the request, every coalition's value and output hash, and the credit, under a SHA-256 seal. The verifier (receipt/verify.py) is written independently of the instrument. The page (page/, served on 127.0.0.1:7472) reads sealed receipts only.
Tamper tests
| Test | Detail | |
|---|---|---|
| PASS | E1 untouched receipt passes V1 to V5 (full replay, bit-identical) | fails: [] |
| PASS | E2 edited share, old seal: V1 catches it | fails: ['V1 seal', 'V4 credit recomputed from v (permutation Shapley, LOO, shares, efficiency)'] |
| PASS | E3 edited share, re-sealed: V4 catches it | fails: ['V4 credit recomputed from v (permutation Shapley, LOO, shares, efficiency)'] |
| PASS | E4 forged v (consistent, re-sealed): V1 to V4 pass, full replay V5 catches it | without replay: []; with full replay: ["V5 replay on the receipt's backend (mps/float32): 64 coalitions, outputs bit-identical and v(S) recomputed exactly"] |
| PASS | E4 note: spot replay (8) would sample the forged coalition | forged coalition 5 is NOT in the spot sample [2, 9, 21, 27, 29, 34, 38, 44]; spot replay is probabilistic |
| PASS | E5 swapped source hash, re-sealed: V2 catches it | fails: ["V2 every owner's source file matches"] |
| PASS | E6 edited nearest-image claim, re-sealed: V6 catches it (untouched receipt passes with --outputs) | untouched fails []; edited fails ['V6 nearest training image recomputed from the corpus arrays'] |
| PASS | E7 flipped control pass flag, re-sealed: V7 catches it | fails ['V7 planted controls recomputed from the recorded values'] |
Found by these tests: the first verifier compared only regenerated output hashes, so a receipt with a forged value, recomputed consistently and re-sealed, passed even a full replay. Fixed: the replay also recomputes every value exactly. A spot replay remains probabilistic, and the page says so.
13. M4: the viewer's drawing as a paid party
Protocol measure/M4_PROTOCOL.md, frozen before any run. The drawing is a seventh player: absent, sampling starts from noise; present, it starts at step k from the drawing blended with the same noise. Three test drawings, k in 4, 9, 14, seeds 9100 and 9101, commons 10, schedule S1.
| ID | Result | Numbers |
|---|---|---|
| K1 efficiency | holds | max error 2.2e-16 |
| D1 | holds | per case [True, True, True, True, True, True] |
| D2 | fails | per case [False, False, False, True, True, True] |
| D3 | holds | per case [True, True, True, True, True, True] |
| D4 | fails | per case [False, False, False, False, False, False] |
Post hoc: lines or paper? (exploratory, after the verdicts)
| Seed | k | circle pixel | circle edges | house pixel | house edges | hatch pixel | hatch edges |
|---|---|---|---|---|---|---|---|
| 9100 | 4 | 0.011 | 0.065 | 0.023 | 0.116 | 0.025 | 0.070 |
| 9100 | 9 | 0.016 | 0.113 | 0.037 | 0.230 | 0.032 | 0.090 |
| 9100 | 14 | 0.029 | 0.231 | 0.055 | 0.445 | 0.049 | 0.207 |
| 9101 | 4 | 0.008 | 0.058 | 0.017 | 0.094 | 0.020 | 0.097 |
| 9101 | 9 | 0.011 | 0.088 | 0.020 | 0.151 | 0.022 | 0.130 |
| 9101 | 14 | 0.024 | 0.301 | 0.037 | 0.394 | 0.028 | 0.176 |
Share of the drawing's effect added by its lines on top of a blank sheet in the same paper colour.
Interpretation. By pixels, 94 to 99% of what a drawing does is its paper tone; by edges the lines matter more and rise with k. The drawing is paid mostly for its paper, as the artists were in M2. Next: register a split of the input into ground and lines. At k = 14 the drawn shape appears, made of the artists' marks.
14. SPLIT: the drawing as paper and lines
Protocol measure/SPLIT_PROTOCOL.md, frozen before any run. The input becomes two players: its ground (a blank sheet in the corpus paper colour) and its lines (the drawing minus that sheet, float64, so the two add back to the drawing exactly). Same seeds, drawings and pool as M4; k in 9, 14; 256 coalitions per game.
| ID | Result | Numbers |
|---|---|---|
| K1 efficiency | holds | max error 3.3e-16 |
| K2 both parts == the drawing | holds | max differing values 0 |
| L1 | holds | per case [True, True, True, True, True, True, True, True, True, True, True, True] |
| L2 | holds | per case [True, True, True, True, True, True] |
| L3 | holds | per case [True, True, True, True, True, True] |
Shares per case
| Case | pixel: paper | pixel: lines | pixel: artists (split) | pixel: artists (M4) | edges: paper | edges: lines | edges: artists (split) | edges: artists (M4) |
|---|---|---|---|---|---|---|---|---|
| 9100_circle_k9 | 0.660 | 0.002 | 0.337 | 0.405 | 0.564 | 0.389 | 0.047 | 0.061 |
| 9100_circle_k14 | 0.644 | 0.039 | 0.316 | 0.383 | 0.417 | 0.542 | 0.041 | 0.057 |
| 9100_house_k9 | 0.661 | 0.000 | 0.339 | 0.410 | 0.511 | 0.436 | 0.053 | 0.066 |
| 9100_house_k14 | 0.647 | 0.035 | 0.318 | 0.384 | 0.314 | 0.651 | 0.036 | 0.053 |
| 9100_hatch_k9 | 0.659 | 8.01e-05 | 0.341 | 0.408 | 0.557 | 0.381 | 0.062 | 0.069 |
| 9100_hatch_k14 | 0.642 | 0.040 | 0.318 | 0.384 | 0.435 | 0.514 | 0.051 | 0.069 |
| 9101_circle_k9 | 0.639 | 0.086 | 0.275 | 0.334 | 0.568 | 0.348 | 0.084 | 0.098 |
| 9101_circle_k14 | 0.615 | 0.129 | 0.256 | 0.316 | 0.366 | 0.589 | 0.044 | 0.067 |
| 9101_house_k9 | 0.645 | 0.079 | 0.275 | 0.336 | 0.538 | 0.368 | 0.093 | 0.106 |
| 9101_house_k14 | 0.618 | 0.125 | 0.258 | 0.319 | 0.315 | 0.627 | 0.059 | 0.080 |
| 9101_hatch_k9 | 0.643 | 0.078 | 0.278 | 0.341 | 0.575 | 0.337 | 0.088 | 0.106 |
| 9101_hatch_k14 | 0.623 | 0.115 | 0.262 | 0.325 | 0.435 | 0.504 | 0.061 | 0.086 |
Splitting a player moves the others' pay (reported, not predicted)
| Value function | artists' summed share: one-player input minus split input, min | max |
|---|---|---|
| pixel | 0.059 | 0.070 |
| edges | 0.008 | 0.026 |
| blur | 0.061 | 0.081 |
| colour | 0.079 | 0.123 |
Interpretation. By pixels a drawing is paid for its paper (lines 0 to 13%); by edges at k = 14 its lines out-earn its paper, and the lines' share grows with strength. Cutting the input into two players lowered the artists' total by 0.008 to 0.12: Shapley is not splitting-proof, so a payee could raise their share by declaring more parts. Decision: the split is shown as description only; pay uses the drawing as one player. Cross-run check: the one-player game read off the split game reproduces M4's separately run Shapley values exactly (difference 0 in all 24 case and value-function pairs, computed in the page).
15. POOL: does the use gap grow with the pool?
Protocol measure/POOL_PROTOCOL.md, frozen before any run. Nested commons pools N = 86, 43, 21, 10 (one fixed order); fresh seeds 9200 to 9203; six artists as players; S1, MPS float32.
| ID | Result | Numbers |
|---|---|---|
| K1 efficiency | holds | max error 5.6e-17 |
| P1 | holds | per seed [True, True, True, True] |
| P2 | fails | per seed [False, False, True, True] |
| P3 | holds | medians 86 43 21 10 [0.278, 0.246, 0.215, 0.170] |
Why: the pool substitutes for the artists
| N | artists' share of all mass, 9200 | 9201 | 9202 | 9203 | v(all artists) pixel, 9200 | 9201 | 9202 | 9203 |
|---|---|---|---|---|---|---|---|---|
| 86 | 0.696 | 0.551 | 0.533 | 0.603 | 0.063 | 0.045 | 0.042 | 0.056 |
| 43 | 0.832 | 0.729 | 0.689 | 0.728 | 0.087 | 0.078 | 0.070 | 0.086 |
| 21 | 0.906 | 0.854 | 0.800 | 0.838 | 0.110 | 0.107 | 0.100 | 0.113 |
| 10 | 0.957 | 0.922 | 0.885 | 0.916 | 0.115 | 0.118 | 0.122 | 0.133 |
Interpretation. By pixels (and blur, colour) paying by use drifts further from Shapley as the pool grows; by edges there is no trend (P2 failed). Leave-one-out does the opposite: it drifts as the pool shrinks, because the artists then make up most of the mass and substitute for each other. No cheap rule tracks Shapley across pool sizes, so the receipt states the rule and the pool size, and exact Shapley pays wherever it is affordable.
16. M5 diagnostic: can exact credit be bought cheaply?
Exploratory (measure/m5_prune_diag.py): one trajectory, CPU float64, 64 query pixels per step, every allowed candidate computed exactly. need: the fewest candidates holding all but 1e-6 of the mass (the ceiling for any pruning). certified: candidates a scheme with a provable bound must evaluate (projection onto the top 16 principal directions).
| Step | Patch | abar | need (oracle) | certified pca16 | certified means |
|---|---|---|---|---|---|
| 0 | 11 | 0.006 | 1.000 | 1.000 | 1.000 |
| 1 | 11 | 0.024 | 0.999 | 1.000 | 1.000 |
| 2 | 11 | 0.054 | 0.984 | 1.000 | 1.000 |
| 3 | 11 | 0.094 | 0.922 | 1.000 | 1.000 |
| 4 | 9 | 0.144 | 0.865 | 1.000 | 1.000 |
| 5 | 9 | 0.203 | 0.735 | 1.000 | 1.000 |
| 6 | 9 | 0.269 | 0.594 | 1.000 | 1.000 |
| 7 | 9 | 0.341 | 0.458 | 1.000 | 1.000 |
| 8 | 7 | 0.416 | 0.546 | 0.996 | 0.997 |
| 9 | 7 | 0.494 | 0.440 | 0.984 | 0.991 |
| 10 | 7 | 0.572 | 0.335 | 0.945 | 0.968 |
| 11 | 7 | 0.647 | 0.238 | 0.872 | 0.919 |
| 12 | 5 | 0.720 | 0.366 | 0.739 | 0.827 |
| 13 | 5 | 0.787 | 0.263 | 0.631 | 0.740 |
| 14 | 5 | 0.847 | 0.170 | 0.504 | 0.650 |
| 15 | 5 | 0.899 | 0.093 | 0.355 | 0.550 |
| 16 | 3 | 0.941 | 0.234 | 0.300 | 0.468 |
| 17 | 3 | 0.972 | 0.112 | 0.154 | 0.338 |
| 18 | 3 | 0.992 | 0.025 | 0.037 | 0.183 |
Interpretation. The posterior is broad until the last steps: an oracle saves 1.4x over the schedule, a certified bound 1.05x to 1.10x. Pruning is retired as the speed lever; 64 px receipts will be precomputed, and any structural speed-up is a declared model change.
Cost at 64 px (one full-coalition picture each, MPS float32)
| L | Schedule | Patch sizes | Seconds per picture | 64-coalition game, hours (upper) |
|---|---|---|---|---|
| 32 | S1 | [3, 5, 7, 9, 11] | 11.5 | 0.21 |
| 64 | S1 | [3, 5, 7, 9, 11] | 150.8 | 2.68 |
| 64 | S1 patches x2 | [7, 11, 15, 19, 23] | 217.7 | 3.87 |
Resolution alone does not make drawings appear; the viewer's drawing does (M4, SPLIT).
17. RESOLVE: can you tell in advance whether credit is recoverable?
Protocol measure/RESOLVE_PROTOCOL.md, frozen before the sweep (measure/resolve_freeze.json). The attribution literature retreats to crediting data groups because exact removal needs retraining; here removal is exact, so the question can be asked directly: does a bank's geometry decide whether credit to its individual members is recoverable? 16 banks of 7 from the 205 sources, 4 noise seeds, exact Shapley over 27 = 128 coalitions per game, CONTROL-constant as the baseline so the empty coalition is defined, schedule S1, MPS float32, 64 games. Primary measure R: the Spearman correlation between the per-member Shapley vectors from two different noise seeds, averaged over the 6 seed pairs. A ranking that cannot be reproduced is not credit.
Verdicts against the frozen predictions
| ID | Prediction | Result | Outcome |
|---|---|---|---|
| R1 | composition predictor tracks R, Spearman ≥ +0.6 | -0.174 | fails |
| R2 | narrow_msv unresolvable: R < 0.4 and ≥ 5 of 7 effective members | R 0.488, 6.94 of 7 | fails |
| R4 | the two value functions rank differently, cross-Spearman < 0.8 | 0.616 | observed |
| R5 | pixel control predictor tracks R at least as strongly | 0.179 | fails |
| R6 | composition adds nothing beyond pixel proximity | -0.181 | observed |
The headline question is answered no. R is not flat (edges 0.006 to 0.702 across banks, pixel 0.202 to 0.851); it simply does not vary with anything measured about the corpus. The hoped-for capability, telling a contributor at ingest whether their collection is individually creditable, does not follow from either predictor, and compositional vocabulary is retired as a candidate value function. R2 failing is its own small result: 7 paintings of one mountain give R = 0.488 and 6.94 of 7 effective members, indistinguishable from any other bank, so compositional near-duplication does not make contributors interchangeable here.
Control bank, before the sweep
| Check | Outcome | Numbers |
|---|---|---|
| K1 Shapley efficiency | observed | max |error| 2.78e-17 |
| K2 coalition mask = physically reduced corpus | observed | max |difference| 0.0 |
| K3 scrambled control < 1% of positive mass | observed | pixel 0.000 edges 0.006 blur 0.000 colour 0.000 |
| K4 constant control < 1% of positive mass | observed | pixel 3.5e-04 edges 2.0e-04 blur 3.9e-04 colour 0.000 |
The first control run failed K4 at 2.9 to 6.5% and is kept as measure/resolve_controls.S0_failed.json. The cause was the runner, not the bank: Machine.__init__ defaults to schedule S0 and neither script had set S1, so the values reproduced M3's T5d almost exactly. Fixed and rerun. The planted duplicate pays exactly 2.0000 of du-01 alone on usage while taking the same Shapley share as its twin.
Per bank
| Bank | composition | pixel | R pixel | eff pixel | R edges | eff edges | vf agreement |
|---|---|---|---|---|---|---|---|
| narrow_mixed | 1.017 | 14.217 | 0.690 | 7.00 | 0.333 | 6.81 | 0.464 |
| narrow_msv | 1.048 | 10.146 | 0.768 | 7.00 | 0.488 | 6.94 | 0.732 |
| span01 | 1.111 | 14.139 | 0.262 | 7.00 | 0.190 | 6.66 | 0.661 |
| span02 | 1.284 | 16.887 | 0.810 | 7.00 | 0.696 | 6.60 | 0.545 |
| span03 | 1.461 | 17.194 | 0.750 | 7.00 | 0.702 | 6.82 | 0.679 |
| span04 | 1.637 | 15.449 | 0.851 | 7.00 | 0.565 | 6.67 | 0.705 |
| ingres7 | 1.794 | 6.440 | 0.518 | 7.00 | 0.607 | 6.88 | 0.679 |
| span05 | 1.813 | 17.922 | 0.202 | 7.00 | 0.351 | 6.75 | 0.643 |
| span06 | 1.991 | 13.545 | 0.696 | 7.00 | 0.411 | 6.76 | 0.214 |
| span07 | 2.168 | 12.801 | 0.690 | 7.00 | 0.637 | 6.17 | 0.500 |
| span08 | 2.345 | 11.285 | 0.530 | 7.00 | 0.006 | 6.72 | 0.446 |
| span09 | 2.522 | 16.319 | 0.440 | 7.00 | 0.321 | 5.86 | 0.777 |
| span10 | 2.700 | 14.000 | 0.643 | 7.00 | 0.571 | 6.21 | 0.839 |
| span11 | 2.879 | 12.487 | 0.548 | 7.00 | 0.304 | 6.79 | 0.438 |
| span12 | 3.049 | 15.921 | 0.643 | 7.00 | 0.494 | 6.62 | 0.795 |
| wide_commons | 3.142 | 16.388 | 0.268 | 7.00 | 0.351 | 6.33 | 0.732 |
What was not predicted: credit is near-uniform under pixel MSE
Across all 64 games, exact Shapley under pixel gives a largest-to-smallest member share ratio with median 1.02, never above 1.06, so every game reads 7.00 of 7 effective members. In the same games usage mass varies by 2.92× and leave-one-out by 2.37×. Under edges Shapley does discriminate (ratio median 2.00) but its ranking reproduces only moderately. The three payout columns therefore disagree structurally, not marginally, on the same bank in the same run.
Alternative explanation, stated. This uniformity is equally consistent with the weakness O12 already recorded for pixel MSE, that it weights area: seven members each supplying about a seventh of a 32 px mosaic would give near-equal pixel effects for that reason alone. This run does not separate “credit is uniform” from “pixel MSE cannot see it”, and the two have opposite consequences for per-item settlement. It is carried as an open question in BRIEF section 13, testable by re-running the frozen banks with a third value function and at 64 px. Either way it is direct support for design rule 9: the value function is a declaration, and the same bank yields uniform or discriminating credit depending on which one is declared.
Scope: 32 px, banks of 7, one engine, 191 sources, two value functions. Exact Shapley is only available at this scale; nothing here speaks to banks of thousands.
Banks span the predictor from 1.017 to 3.142; the composition and pixel predictors correlate at 0.024 across them, and bank overlap is 0.18 shared members per pair (max 1), so R1 and R5 are separable and the banks are close to independent.
Stage two: attention
Machine: engine/tio/static_attention.py, Riley's static-attention construction with several heads and support-aware rank handling from Russell's library (ch. 48); 9/9 tests, including agreement with Riley's code (2.9e-15) and a brute-force Gaussian (1.0e-15). Exact vs frozen attention law: instrument/attention_law.py (ch. 49), matching the library's Study 13 fixtures to 1e-16.
ATTN1: does attention change who gets paid?
| ID | Result | Numbers |
|---|---|---|
| K1 efficiency | holds | max error 2.2e-16 |
| K2 batched == one at a time | fails | differing values 53964 |
| Q1 | holds | tv [0.272, 0.154, 0.270, 0.086] |
| Q2 | fails | tv global local [[0.163, 0.117], [0.502, 0.054], [0.223, 0.051], [0.742, 0.078]] |
| Q3 | holds | top local none [[0.351, 0.182], [0.259, 0.210], [0.343, 0.209], [0.229, 0.186]] |
| Family | effective images per patch, steps 0, 3, 6, 9, 12, 15, 18 (seed 9300) | ||||||
|---|---|---|---|---|---|---|---|
| NONE | 421.091 | 383.640 | 319.839 | 240.743 | 155.476 | 72.211 | 7.090 |
| LOCAL | 384.733 | 207.265 | 105.739 | 50.582 | 19.453 | 4.544 | 1.106 |
| GLOBAL | 270.296 | 50.011 | 18.245 | 5.783 | 2.094 | 1.207 | 1.004 |
| Seed | Family | nearest RMS (levels) | nearest owner |
|---|---|---|---|
| 9300 | NONE | 54.214 | rb-09 |
| 9300 | LOCAL | 38.495 | rb-09 |
| 9300 | GLOBAL | 22.160 | kk-15 |
| 9301 | NONE | 55.787 | kk-15 |
| 9301 | LOCAL | 40.786 | kk-19 |
| 9301 | GLOBAL | 37.127 | vg-09 |
| 9302 | NONE | 55.666 | rb-09 |
| 9302 | LOCAL | 30.810 | du-07 |
| 9302 | GLOBAL | 47.809 | du-07 |
| 9303 | NONE | 56.345 | rb-09 |
| 9303 | LOCAL | 31.495 | du-12 |
| 9303 | GLOBAL | 0.000 | met-dp-20645-001 |
Interpretation. Attention shares information across patches; the posterior collapses toward one image, pay concentrates, use drifts from Shapley, and with global attention one output is a verbatim copy of an unpaid commons painting while the artists are paid 100%. Receipts now report the nearest training image and the players' total effect beside the shares.
ATTN2: do frozen-attention receipts report the source?
| ID | Result | Numbers |
|---|---|---|
| K1 weights sum to 1 | holds | max error 3.3e-15 |
| K2 row inversion | holds | max error 5.6e-16 |
| R1 | holds | mean tv steps 10 18 [0.888, 0.526, 0.523, 0.751] |
| R2 | holds | tv last step5 [[1.000, 0.424], [0.556, 0.335], [0.508, 0.488], [1.000, 0.255]] |
| R3 | holds | top differs last [True, True, True, True] |
Last step, beta 4: exact posterior r, then the frozen receipt m, over cezanne, durer, ingres, kollwitz, rembrandt, vangogh, pool.
| beta | seed | r | r | r | r | r | r | r | m | m | m | m | m | m | m | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 4 | 9400 | 2.29e-321 | 6.45e-169 | 0.000 | 3.25e-48 | 1.000 | 2.47e-42 | 8.13e-150 | 2.32e-09 | 0.485 | 0.035 | 0.480 | 2.81e-88 | 5.27e-157 | 1.24e-68 | |
| 4 | 9401 | 0.000 | 1.000 | 0.000 | 1.44e-19 | 0.000 | 2.77e-215 | 3.24e-166 | 3.04e-08 | 0.444 | 0.001 | 0.555 | 8.26e-63 | 9.40e-148 | 2.34e-89 | |
| 4 | 9402 | 2.20e-297 | 4.40e-295 | 0.000 | 1.000 | 2.05e-226 | 6.09e-154 | 8.70e-201 | 0.001 | 0.498 | 0.008 | 0.492 | 8.21e-36 | 2.10e-73 | 1.98e-45 | |
| 4 | 9403 | 5.28e-179 | 2.53e-108 | 0.000 | 2.91e-32 | 2.43e-78 | 1.000 | 1.04e-65 | 1.83e-05 | 0.484 | 3.07e-04 | 0.516 | 1.34e-76 | 6.51e-120 | 1.95e-43 |
Interpretation. Plugging realised attention into the static formula pays a near-fixed Dürer/Kollwitz split whatever the picture, while the exact posterior names a different artist per seed. Static-attention receipts are not receipts for attention models. Limits: scalar tokens, one head, 16 px greyscale, row retained; posterior accounting, not removal credit.
Reconciliation with Riley Peterlinz's repository
github.com/CardiacMangoes/diffusion at commit 6b757a546369, used with his permission. Script measure/riley_reconcile.py, CPU float64.
| ID | Check | Largest difference |
|---|---|---|
| R1 | Whole-image score vs our 'is' variant (time conversion) | 1.2e-14 |
| R2 | Static-attention form, patch 1, S = I, vs our 'ls' variant, by jitter | jitter 1e-05: 1.3e-06, jitter 1e-07: 2.4e-08, jitter 1e-09: 3.8e-08 |
| R3 | 2 x 2 Gaussian algebra vs brute force (dense S) | 3.9e-16 |
| R4 | Removal exact in the static-attention form (renormalisation; ledger identity) | 3.3e-16; 8.9e-16 |
Our engine equals the repository's whole-image form, and its static-attention form at patch size 1 with S = I up to the jitter level. Removal is exact in the static-attention form, so the removal instrument applies to it unchanged. Russell's library (ch. 48) extends the same construction to several heads with an exact rank condition; engine/tio/static_attention.py implements that and is checked against both (9/9 tests).
Receipts format 3: context and planted controls
Every receipt states the players' total effect, their share of all posterior mass and the nearest training image (copy flag), and runs its own planted controls (T0FIX game B on its own noise and pool; rules F1 to F3 from T0FIX, registered on the 86-painting pool). Main games are bit-identical to formats 1 and 2. Demo receipts (pool 10) and paid receipts (pool 86, receipt/receipts_full/, made 2026-10-02 by receipt/make_paid.py, which calls make.py unchanged), edges:
| Pool: seed | copy ratio (rule 1.6 to 2.4) | scrambled max share (< 0.01) | constant max share (< 0.01) | total effect | nearest training image |
|---|---|---|---|---|---|
| 10: 9000 | 1.813 pass | 0.000 pass | 0.012 fail | 0.249 | in-17, 39.604 (none) |
| 10: 9001 | 1.855 pass | 0.022 fail | 0.004 pass | 0.237 | kk-19, 41.766 (none) |
| 10: 9002 | 1.843 pass | 0.003 pass | 0.006 pass | 0.322 | cz-08, 41.981 (none) |
| 10: 9003 | 1.820 pass | 0.001 pass | 0.002 pass | 0.373 | kk-20, 46.602 (none) |
| 86: 9000 | 1.956 pass | 0.000 pass | 0.008 pass | 0.104 | in-17, 43.788 (none) |
| 86: 9001 | 1.963 pass | 0.002 pass | 0.002 pass | 0.073 | kk-19, 42.439 (none) |
| 86: 9002 | 1.994 pass | 0.004 pass | 0.005 pass | 0.101 | kk-20, 47.013 (none) |
| 86: 9003 | 1.906 pass | 7.27e-04 pass | 3.79e-04 pass | 0.156 | vg-03, 48.937 (none) |
With the 10-painting demo pool the nonsense contributors' shares exceed the 1% rule on 2 of 4 seeds (the 86-pool test never exceeded 0.0036). Decision: paid receipts use the full pool; the visual demo keeps the 10-pool, labelled. On the full pool every control passes on all four seeds.
Sketch receipts
receipt/make_drawing.py: the drawing as one paid player at strength k = 14, pixels stored for replay, paper and lines as description. Edges:
| Drawing | Shapley shares (paid) | description: paper, lines | copy flag |
|---|---|---|---|
| 1c2e1bd456 | kollwitz 0.062, drawing 0.938 | ground 0.448, lines 0.509 | none |
| 6922bc251f | kollwitz 0.057, drawing 0.943 | ground 0.417, lines 0.542 | none |
6922bc251f is the circle test drawing (seed 9100): it matches M4's frozen run to three decimals and its replay is bit-identical. 1c2e1bd456 was made from the page.
Running elsewhere: Colab Tesla T4 (O9)
Tesla T4, Python 3.13.15, torch 2.11.0+cu128 (this Mac: torch 2.12.0.dev20260315, MPS). Shipped receipt replayed on CUDA: worst value difference 0.005 of the tolerance. Fresh receipt on CUDA against the shipped one:
| Value function | worst |dv| / tolerance | Shapley shares moved (TV) |
|---|---|---|
| pixel | 0.003 | 1.7e-07 |
| edges | 0.005 | 5.9e-07 |
| blur | 0.005 | 1.1e-07 |
| colour | 0.000 | 0.0e+00 |
Engine T3 (masses sum to 1) measured 1.5e-5 in float32 on CUDA against a 1e-5 threshold taken from MPS runs; a plain log-sum-exp on the T4 is tight (2.4e-7), and the error grows at the last, lowest-noise step with the log-mass magnitude. T3 is now pass/fail in float64 and a reported measurement in float32.
Stage two (O7): the bridge to trained networks
Protocol measure/O7_PROTOCOL.md, frozen. 64 px, demo pool, width-128 convolutional networks (patch-ledger recipe, ported with provenance). Phase A trains the full network, calibrates the machine to it and gates on agreement (median r >= 0.85); phase B trains six leave-one-artist-out networks and a second full network (training-noise floor); phase C (direction, resolvability, magnitude) runs after.
Gate: median r 0.970 vs 0.85: passed.
2026-10-01 23:26:55 end (exit 0) python3 stage2/train.py --L 64 --seed 0 --steps 10000 --tag no_rembrandt --exclude rembrandt 2026-10-01 23:26:55 start python3 stage2/train.py --L 64 --seed 0 --steps 10000 --tag no_vangogh --exclude vangogh done no_vangogh in 6008s 2026-10-02 01:07:04 end (exit 0) python3 stage2/train.py --L 64 --seed 0 --steps 10000 --tag no_vangogh --exclude vangogh 2026-10-02 01:07:04 start python3 stage2/train.py --L 64 --seed 1 --steps 10000 --tag full_s1 done full_s1 in 6007s 2026-10-02 02:47:13 end (exit 0) python3 stage2/train.py --L 64 --seed 1 --steps 10000 --tag full_s1 2026-10-02 02:47:13 PHASES A AND B COMPLETE
Phase C results
| ID | Result | Numbers |
|---|---|---|
| P1 | holds | p exact 0.001 |
| P2 | fails | resolvable cezanne False; durer False; ingres False; kollwitz False; rembrandt True; vangogh False |
| P3 | fails | spearman edges -0.143 |
| P4 | fails | first step 0.040 last step 0.119 |
D: rows are the machine's predicted change for removing an artist, columns the network trained without an artist; diagonal in bold.
| prediction \ network | cezanne | durer | ingres | kollwitz | rembrandt | vangogh |
|---|---|---|---|---|---|---|
| cezanne | 0.148 | -0.052 | 0.054 | 0.066 | 0.039 | -0.038 |
| durer | -0.054 | 0.051 | -0.062 | -0.035 | -0.122 | 0.029 |
| ingres | 0.104 | 0.085 | 0.177 | -0.077 | 0.098 | -0.170 |
| kollwitz | -0.029 | -0.051 | -0.002 | 0.143 | -0.050 | -0.156 |
| rembrandt | 0.008 | 0.015 | -0.010 | 0.118 | 0.184 | 0.265 |
| vangogh | -0.045 | 0.039 | -0.067 | -0.111 | -0.146 | 0.076 |
F and M (edges): finished-image distance from full_s0, median over 16 noises; training-noise floor (full_s0 vs full_s1) 0.064.
| Artist | network removal | machine removal | above floor |
|---|---|---|---|
| cezanne | 0.008 | 0.016 | no |
| durer | 0.026 | 0.012 | no |
| ingres | 0.023 | 0.025 | no |
| kollwitz | 0.036 | 0.036 | no |
| rembrandt | 0.125 | 0.008 | yes |
| vangogh | 0.026 | 0.024 | no |
| t | mean diagonal (direction agreement) |
|---|---|
| 0.850 | 0.040 |
| 0.800 | 0.069 |
| 0.750 | 0.084 |
| 0.700 | 0.122 |
| 0.650 | 0.159 |
| 0.600 | 0.145 |
| 0.550 | 0.186 |
| 0.500 | 0.170 |
| 0.450 | 0.130 |
| 0.400 | 0.189 |
| 0.350 | 0.162 |
| 0.300 | 0.129 |
| 0.250 | 0.096 |
| 0.200 | 0.146 |
| 0.150 | 0.119 |
Interpretation. Direction transfers at 64 px (p = 1/720, positive at every step); size does not (Spearman across artists negative); single-artist removal is visible above training noise for one artist. Limits: one start seed for the leave-out networks, one network family.
18. Re-trace every step
Run from this experiment's folder, in order (steps that need data or clones outside it say so). Hashes are the first 12 hex digits of SHA-256 at the time this page was built; if a script's hash differs from the one here, the results on this page came from a different version of it.
| # | Step | Command | Produces | Script |
|---|---|---|---|---|
| 1 | Engine tests | python3 engine/tests/test_engine.py | engine/tests/last_run.json 3b97fdf3f565 | engine/tests/test_engine.py 1f5521c3cc7b |
| 2 | Benchmark (GPU) | python3 bench/bench_engine.py | bench/results_mps_float32.json 1d6e80b76445 | bench/bench_engine.py 4fcea406e35d |
| 3 | Benchmark (float64 CPU) | python3 bench/bench_engine.py --cpu64 | bench/results_cpu_float64.json 8f307079933d | bench/bench_engine.py 4fcea406e35d |
| 4 | Build corpus | python3 corpus/build_corpus.py | corpus/manifest.json 01b1b92124ce | corpus/build_corpus.py 1072985430ef |
| 5 | Duplicate scan | python3 corpus/scan_duplicates.py | corpus/duplicates.json e30fd2e80906 | corpus/scan_duplicates.py 0fe1475cf853 |
| 6 | Met verification | python3 corpus/verify_met.py | corpus/met_verification.json 5f14dab0c722 | corpus/verify_met.py 9156bfaea215 |
| 7 | Paper measurement | python3 measure/paper_credit.py | measure/paper_credit.json 662b0ad637ca | measure/paper_credit.py b1145ec2d564 |
| 8 | Crop-scale test | python3 measure/crop_scale.py | measure/crop_scale.json e854feb59aac | measure/crop_scale.py 9104dbe9f641 |
| 9 | M3 freeze | python3 measure/m3_run.py freeze | measure/m3_freeze.json c10c7dc564e9 | measure/m3_run.py 8e83d228151e |
| 10 | M3 run | python3 measure/m3_run.py run | measure/m3/A_6000.json 8f66f0db0ce5 | measure/m3_run.py 8e83d228151e |
| 11 | M3 analysis | python3 measure/m3_analyze.py | measure/m3_results.json 0a79d4a06046 | measure/m3_analyze.py 13be0a13f0ba |
| 12 | t = 1 diagnostic | python3 measure/t0_diagnostic.py | measure/t0_diagnostic.json f9567e2092a3 | measure/t0_diagnostic.py 9599977854f6 |
| 13 | Chaos floor | python3 measure/chaos_floor.py | measure/chaos_floor.json 2dd8b2aca3ce | measure/chaos_floor.py d6eab1e7f79f |
| 14 | T0FIX freeze and run | python3 measure/t0fix_run.py freeze; python3 measure/t0fix_run.py run | measure/t0fix/A_6000.json 69bb3eec20bd | measure/t0fix_run.py 4b700e9fa99c |
| 15 | T0FIX analysis | python3 measure/t0fix_analyze.py | measure/t0fix_results.json e47074c40c7d | measure/t0fix_analyze.py ada4b2f8f36d |
| 16 | K2 float64 re-check | python3 measure/k2_float64.py | measure/k2_float64.json 9861143c79e5 | measure/k2_float64.py 39a843277ebc |
| 17 | Pool-size test | python3 measure/commons_size.py | measure/commons_size.json 72b2f836e6e7 | measure/commons_size.py 9237a0475440 |
| 18 | Demo receipts | sh receipt/make_demo.sh | receipt/make_demo.log 895881d63a12 | receipt/make.py ba81a7eb3a44 |
| 19 | Page data | python3 page/build_data.py | page/data/index.json 380fe0a37aeb | page/build_data.py 2ae96bad375c |
| 20 | Receipt tamper tests | python3 receipt/tests/test_receipt.py <receipt> | receipt/tests/last_run.json e6289e6836c2 | receipt/tests/test_receipt.py 1033ff72201c |
| 21 | Test drawings | python3 corpus/inputs/make_test_drawings.py | corpus/inputs/test_drawings.json b598255eb230 | corpus/inputs/make_test_drawings.py 5762363a6b3a |
| 22 | M4 freeze and run | python3 measure/m4_run.py freeze; python3 measure/m4_run.py run | measure/m4/9100_house_k9.json ea3603f7b1bb | measure/m4_run.py bcdaf9f443fb |
| 23 | M4 analysis | python3 measure/m4_analyze.py | measure/m4_results.json c55d4a6dfb76 | measure/m4_analyze.py fd4074420e2a |
| 24 | M4 post hoc: blank sheet | python3 measure/m4_blank_posthoc.py | measure/m4_blank_posthoc.json 8b1fb096796a | measure/m4_blank_posthoc.py d10f3eae4c64 |
| 25 | SPLIT tests | python3 instrument/tests/test_parts_game.py | instrument/tests/last_run_parts.json 1c4704082c82 | instrument/tests/test_parts_game.py a8653355d292 |
| 26 | SPLIT freeze and run | python3 measure/split_run.py freeze; python3 measure/split_run.py run | measure/split/9100_house_k14.json f7cffcded822 | measure/split_run.py 072045502314 |
| 27 | SPLIT analysis | python3 measure/split_analyze.py | measure/split_results.json a38c29a4f7a7 | measure/split_analyze.py 90c479c7d7c4 |
| 28 | SPLIT panel and splitting table | python3 measure/split_panel.py | measure/split_splitting.json 8332cc8d56fb | measure/split_panel.py 73bd68f8483b |
| 29 | Page drawing data | python3 page/build_drawings.py | page/data/drawings.json 20bc58e4a58e | page/build_drawings.py 7d015aae4d07 |
| 30 | POOL freeze and run | python3 measure/pool_run.py freeze; python3 measure/pool_run.py run | measure/pool/9200_N86.json ec7927a1523f | measure/pool_run.py 3cc648a8e78d |
| 31 | POOL analysis | python3 measure/pool_analyze.py | measure/pool_results.json 54bf89103935 | measure/pool_analyze.py 038893411204 |
| 32 | M5 pruning diagnostic | python3 measure/m5_prune_diag.py | measure/m5_prune_diag.json fcef4ecf29ba | measure/m5_prune_diag.py 144ffb34ac90 |
| 33 | M5 cost at 64 px | python3 measure/m5_cost64.py | measure/m5_cost64.json 07ed2772dfc0 | measure/m5_cost64.py 01af1aa5409b |
| 34 | Bundle for running elsewhere | python3 colab/build_notebook.py; python3 colab/make_bundle.py | colab/take-it-out-bundle.zip 825ba5000967 | colab/make_bundle.py 810948542100 |
| 35 | Static-attention tests | RILEY=<clone> python3 engine/tests/test_static_attention.py | engine/tests/last_run_static_attention.json ca27afb147bd | engine/tests/test_static_attention.py fb66c5f5544e |
| 36 | ATTN1 freeze, run, analysis | python3 measure/attn1_run.py freeze; python3 measure/attn1_run.py run; python3 measure/attn1_analyze.py | measure/attn1_results.json 0d0dab13e5b6 | measure/attn1_run.py 25944cba7e2a |
| 37 | ATTN1 post hoc copies | python3 measure/attn1_posthoc_copy.py | measure/attn1_posthoc_copy.json c5302199964f | measure/attn1_posthoc_copy.py 8c47e94c303e |
| 38 | Attention-law tests | python3 instrument/tests/test_attention_law.py | instrument/attention_law.py f57fed0fb7b1 | instrument/tests/test_attention_law.py 90ccc643c60f |
| 39 | ATTN2 freeze, run, analysis | python3 measure/attn2_run.py freeze; python3 measure/attn2_run.py run; python3 measure/attn2_analyze.py | measure/attn2_results.json 62b1a1e8c0fb | measure/attn2_run.py a2536e255372 |
| 40 | Riley reconciliation | RILEY=<clone> python3 measure/riley_reconcile.py | measure/riley_reconcile.json ce6a435c19b5 | measure/riley_reconcile.py 5399e483e960 |
| 41 | Statistics on the registered results | python3 measure/intervals.py | measure/intervals.json 41e550aee90a | measure/intervals.py 6e2123a17c0a |
| 42 | Arithmetic on RFS's scale assumptions (reads RFS_training, outside this folder) | python3 measure/rfs_scale.py | measure/rfs_scale.json 1214545ac0b6 | measure/rfs_scale.py 88eab7d40141 |
| 43 | O7 phases A and B (freeze, train, calibrate, gate) | python3 stage2/o7.py freeze; zsh stage2/overnight.sh | stage2/nets/gate.json 86bf7acfe81a | stage2/overnight.sh 42acf1bab2da |
| 44 | O7 phase C (freeze, run) | python3 stage2/phase_c.py freeze; python3 stage2/phase_c.py | measure/o7_results.json e4064aa6644a | stage2/phase_c.py dcc3fa034e07 |
| 45 | O6 cost table | python3 measure/o6_cost.py | measure/o6_cost.json 704c220a07f1 | measure/o6_cost.py 2c01ff11bb43 |
| 46 | Paid receipts (86-painting pool) | python3 receipt/make_paid.py 9000 9001 9002 9003 | receipt/receipts_full/seed9000_edges_07892a0b7f.json 6f62372061cd | receipt/make_paid.py c34a15b63ddb |
| 47 | Frozen versions of later-edited files | python3 measure/frozen_code/check.py | measure/frozen_code/README.md 871263bab804 | measure/frozen_code/check.py c3e475d8c0c7 |
| 48 | Findings report | python3 report/build_report.py | report/FINDINGS.html c262c7cec151 | report/build_report.py f54284e0bc59 |
| 49 | This labbook | python3 labbook/build_labbook.py | labbook/labbook.html beb681a4fe08 | labbook/build_labbook.py 870ea564e602 |
19. Sources
From BRIEF.md section 11, read at build time.
Status key: R read in full; P read in part; U used as data; X external, not yet read. Originals are never edited; copies are made into this project with provenance.
11.1 Local sources (paths relative to the local research archive)
| Path | What it is | Status | Use |
|---|---|---|---|
image-steering-accreditation-claude/patch-ledger/pl/machine.py | Exact LS/ELS/IS machines, contributor ledger, coalition masking, DDIM cosine sampler (236 lines) | R | Engine base (M1) |
.../patch-ledger/pl/corpus.py | Corpus loader, views rule, caching (73 lines) | R | Corpus pattern (M2) |
.../patch-ledger/tests/test_machine.py | 16 self-tests (221 lines) | P | Port and extend (M1) |
.../patch-ledger/README.md, PROTOCOL.md, RESULTS.md | Design, frozen protocol, verdicts | R | Findings, discipline |
.../patch-ledger/PHASE3_TEST.md, PHASE3_PROTOCOL.md, PHASE3_RESULTS.md, PHASE3B_RESULTS.md, SCORE_TEST_PROTOCOL.md, REPLICATION_PROTOCOL.md | Trained-network bridge tests | P | Stage two design (M7) |
.../patch-ledger/CODE_COMPARISON.md | Line-by-line check against Kamb and Ganguli's released code, calibration recipe | P | Schedule calibration |
.../patch-ledger/VALUE_FUNCTION_PROTOCOL.md, value_functions.py, DIAL_PROTOCOL.md, redundancy_dial.py, group_ratios.py | Value functions, redundancy sweep, group ratios | P | Payout columns |
.../patch-ledger/train.py, score_test.py, score_test_rep.py | Network training and single-step score test | P | Stage two |
.../patch-ledger/paper/PATCH_LEDGER_PAPER.md | Working paper, related work, references with provenance | P | Literature (11.3) |
image-steering-accreditation-claude/MATH.md, README.md, PROTOCOL.md | Steering exposure statement, settlement math | X (to read in M3) | Payout policy |
image-steering-accreditation/library/pdf/kamb-2025-local-score.pdf | Kamb and Ganguli 2025 | R (2026-09-18) | Math 6.2 |
image-steering-accreditation/START_HERE.md, MATH.md, CLAIMS.md, GAPS.md | Research database (original, read-only) | P | Background |
| github.com/CardiacMangoes/diffusion, commit 6b757a5 (clone outside the project) | Riley's code: AnalyticScore, AnalyticScoreDiT (static attention), DiT and DiT_ablated, training, 2D toy notebook. No licence file; Riley's permission to use freely confirmed by Russell 2026-10-01 (copies keep provenance) | R, run (measure/riley_reconcile.py) | Math 6.1, M1 reconciliation, stage two |
RFS_training/training-data.zip, training-data.html (RFS, 2026-10-01) | A complete toy training-data release from a procedural stage: nine datasets (t2i, i2svg, i2code, i2maps, i2i_edit on a five-part request, sft_requests, pref_pairs, seq_camera, pack_adapter with consent gating), tokenizers, attention, an evaluation harness with family-bootstrap intervals, a trained toy checker, scale arithmetic, and a mapping from project records to training rows ("shares are not influence") | R, run (check.py 109/109; rebuild reproduces the release fingerprint, 110/110; evaluate.py reproduces report.json byte-identical; toy training not run) | Evaluation practice (intervals, family splits, graded graders); the influence and tombstone questions this project measures |
image-steering-accreditation/references/48_conditional_denoising_attention.md, 49_input_dependent_attention_laws.md, 75_..., 46_... (Russell's library; Studies 12 and 13 in its experiments/) | Static attention with several heads, rank condition, singular support; exact input-dependent scalar attention law; frozen-window posterior can reverse source preference (C72); posterior accounting vs removal vs allocation | R (2026-10-01) | Stage two design, 6.1 |
Riley/COMPLETE Derivation.pdf | Riley's derivation, 13 pp. | R (pp. 1 to 7 text) | Math 6.1 |
Riley/Research_Presentation.pdf | Diffusion with Tracing, without Training, 34 pp. | X | Math 6.1, slides |
Riley/Attribution Slides.pdf, research_averages.pdf | Three-case comparison; averages | X | Page design reference |
intonarumori/Instrument/untitled folder 3/riley_diffusion_transformer_playground.html (also in participant kit assets) | Riley's playground page | X | Reference |
| Riley's current code repository | His implementation of the derivation; requested 29 Sep and updated by Riley; received 2026-10-01 as github.com/CardiacMangoes/diffusion (row above) | Received and reconciled 2026-10-01 | LOG.md, measure/riley_reconcile.py |
hands/corpus/<artist>/manifest.json and images | Five artists' public-domain sheets with museum, accession, licence, URL (Cézanne 15, Dürer 13, Ingres 20, Kollwitz 20, Van Gogh 17) | U | Corpus (M2) |
know-between/work/know-between/books/rembrandt/ | Rembrandt's 12 sheets (sixth hand) | U | Corpus (M2) |
hands/tools/build_book.py, build_*_corpus.py | Sheet cleaning and corpus build | P | Corpus cleaning |
hands/library/*.hand.json, hands/studio/ | Hand files and studio receipts | R | Receipt design reference |
ZTOYBOX/Museum Pics/ (DP*/DT* files, 100) | Met Open Access (CC0) images | U | Commons pool |
Cezanne/CezanneReal/ (9) | Mont Sainte-Victoire series (public domain) | U | Substitutes test set |
11.3 Literature
Checked means the source page or full text was read on the date shown (carried from the patch-ledger paper unless stated).
| Reference | Relevance | Status |
|---|---|---|
| Finn, Keller, Theodosis, Ba, Origins of Creativity in Attention-Based Diffusion Models, arXiv 2506.17324 (2025) | Extends the ELS machine to a CNN with one final self-attention layer; content-dependent attention, solved only in a top-1 simplification; 4x4 toy images (consistency 64% vs 11% for CNN alone) | Abstract and HTML summary read 2026-10-01 |
| Niedoba, Zwartsenberg, Wood, Filtered Posterior Mean Collections, arXiv 2605.24192 (2026) | Unifies patch-based analytic denoisers; conditioning by diagonal precision only (no mixing across positions, no attention); r^2 0.76 vs networks on CIFAR-10 | Abstract and HTML summary read 2026-10-01 |
| Niedoba et al., Towards a Mechanistic Explanation of Diffusion Model Generalization, arXiv 2411.19339 (ICML 2025) | Patch-based local empirical denoisers approximate network denoisers; code plai-group/pspc | Search result 2026-10-01 |
| Li, Min, Vidal, Transformers Learn the Optimal DDPM Denoiser for Multi-Token GMMs, arXiv 2604.10074 (2026) | Trained transformer attention approximates the MMSE estimator, population objective on Gaussian mixtures (not training-set denoisers) | Abstract read 2026-10-01 |
| Haddadi et al., Denoising Diffusion Generative Models Secretly Calculate Attentions, arXiv 2609.00885 (2026) | The empirical optimal denoiser's softmax over training data is itself an attention computation | Abstract read 2026-10-01 |
| Kamb, M. and Ganguli, S. (2025). An analytic theory of creativity in convolutional diffusion models. ICML 2025; arXiv:2412.20292. Code: github.com/Kambm/convolutional_diffusion (MIT) | The engine | Read in full, code compared, 2026-09-18 |
| Niedoba, M., Zwartsenberg, B., Murphy, K. and Wood, F. (2024). Towards a mechanistic explanation of diffusion model generalization. arXiv:2411.19339 | Concurrent patch-based local score model | Cited from Kamb and Ganguli; X |
| Zhao, Y., Du, C., Zheng, X., Pang, T. and Lin, M. (2025). Nonparametric data attribution for diffusion models. arXiv:2510.14269 | Attribution built on the analytic machine, validated against 64 retrained networks | Full text read 2026-09-19 |
| Briq, R., Fried, O., Kamp, M. and Kesselheim, S. (2026). Tracing generated samples to training-data clusters in flow-matching models. arXiv:2608.30081 | Closed-form cluster attribution, flow matching | Checked 2026-09-19 |
| Dai, Z. and Gifford, D. K. (2026). Outputs of generative diffusion models are often unattributable. Nature Communications | Why the box matters: large-model outputs spread across redundant data | Checked 2026-09-19 |
| Lin, C., Lu, M., Kim, C. and Lee, S.-I. (2025). An efficient framework for crediting data contributors of diffusion models. ICLR 2025; arXiv:2407.03153 | Shapley credit for diffusion contributors | Checked 2026-09-19 |
| Wang, J. T., Deng, Z., Chiba-Okabe, H., Barak, B. and Su, W. J. (2024). An economic solution to copyright challenges of generative AI. arXiv:2404.13964 | Shapley-based royalties | Checked 2026-09-19 |
| Wang, S.-Y., Hertzmann, A., Efros, A. A., Zhu, J.-Y. and Zhang, R. (2024). Data attribution for text-to-image models by unlearning synthesized images. NeurIPS 2024; arXiv:2406.09408 | States this project's premise from the other side: finding influential images requires retraining from scratch, which is infeasible, so they simulate unlearning and validate against retraining as the gold standard. The strongest external citation for why exact removal matters | Abstract page read 2026-10-14 |
| Data attribution for diffusion models: timestep-induced bias in influence estimation. arXiv:2401.09031 (2024) | Diffusion-TracIn and Diffusion-ReTrac; per-timestep influence is biased by a dominating-norm effect. Bears on whether per-step credit is a meaningful quantity | Search result 2026-10-14 |
| Rola, P. (2026). An equality condition for the Dobrushin bound on attention rollout and how often it holds in trained transformers. arXiv:2610.05558, 4 October 2026 | The published version of the contraction result in RFS_transformers, with the equality condition those notes lack and measurements across 8 trained models. The reason not to build contraction experiments in this project | Abstract page read 2026-10-14 |
| Dong, Y., Cordonnier, J.-B. and Loukas, A. (2021). Attention is not all you need: pure attention loses rank doubly exponentially with depth. ICML 2021; Kim, H., Papamakarios, G. and Mnih, A. (2021). The Lipschitz constant of self-attention. ICML 2021; arXiv:2006.04710; Mitrophanov, A. Yu. (2005). Sensitivity and convergence of uniformly ergodic Markov chains. J. Appl. Prob. | Together these place the mathematics in RFS_transformers: rank collapse, attention sensitivity, and the ergodicity-coefficient perturbation bound its Theorem 2 has the shape of | Search results 2026-10-14 |
| Ghorbani, A. and Zou, J. (2019). Data Shapley. ICML 2019 | Shapley for data | Standard reference, X |
| Park, S. M. et al. (2023). TRAK. ICML 2023 | Gradient attribution baseline, LDS evaluation | Standard reference, X |
| Zheng, X., Pang, T., Du, C., Jiang, J. and Lin, M. (2024). Intriguing properties of data attribution on diffusion models. ICLR 2024; arXiv:2311.00500 | D-TRAK, LDS on diffusion. Reports that design choices lacking theoretical justification beat principled baselines by a large margin on the linear datamodeling score and on counterfactual evaluation. A caution for O3: exactness here may not score better on their benchmarks | Abstract page read 2026-10-14 |
| Wang, S.-Y., Efros, A. A., Zhu, J.-Y. and Zhang, R. (2023). Evaluating data attribution for text-to-image models. ICCV 2023 (code: github.com/peterwang512/gendataattribution) | Customization-based ground truth | Standard reference, X |
| Nichol, A. and Dhariwal, P. (2021). Improved denoising diffusion probabilistic models | Cosine schedule used by the engine | Standard reference, X |
| Song, J., Meng, C. and Ermon, S. (2021). DDIM (arXiv:2010.02502) | Sampler | Standard reference, X |
| SAGA (rohit-kundu.github.io/SAGA) | Attribution method named in discussion | X, read before M3 |
---
20. Log
From LOG.md, newest first.
2026-10-14 (RESOLVE sweep complete: the headline prediction FAILS, and credit is near-uniform)
64 bank-seed games, 16 banks of 7, 4 seeds, 128 coalitions each, schedule S1, MPS float32. Run against resolve_freeze.json; the six games that survived a session crash mid-run verified against the freeze and were kept, the rest resumed. Results in measure/resolve_results.json, per-game files in measure/resolve/.
Verdicts against the frozen predictions
| ID | Prediction | Result | Outcome |
|---|---|---|---|
| R1 | Composition predictor tracks credit reproducibility, Spearman >= +0.6 | -0.17 | fails |
| R2 | narrow_msv unresolvable: R < 0.4 and >= 5 of 7 effective members | R = 0.49, 6.94 of 7 | not observed |
| R4 | The two value functions rank members differently, cross-Spearman < 0.8 | 0.62 | observed |
| R5 | Pixel control predictor tracks R at least as strongly | +0.18 | fails |
| R6 | Composition adds nothing beyond pixel proximity (partial < +0.3) | -0.18 | composition adds nothing |
The headline question is answered no. Credit reproducibility is not predicted by the bank's geometry, in either space. R is not flat (edges: 0.006 to 0.702 across banks; pixel: 0.202 to 0.851), it simply does not vary with anything we measured about the corpus. So the hoped-for product capability, telling a contributor in advance whether their collection is individually creditable, does not follow from either predictor. The vocabulary-as-value-function idea is retired, which is the reason this was run before building it.
R2 failing is its own small result: 7 paintings of the same mountain give R = 0.49 and 6.94 effective members, indistinguishable from any other bank. Compositional near-duplication does not make contributors interchangeable in this posterior.
The larger finding, which was not pre-registered
Across all 64 games, exact Shapley under pixel MSE assigns essentially uniform credit: the ratio between the largest and smallest member share has median 1.02 and never exceeds 1.06, so the effective number of credited members is 7.00 of 7 in every game. In the same games, usage mass varies by 2.92x and leave-one-out by 2.37x, median.
Under the edge value function Shapley does discriminate (share ratio median 2.00), but the ranking it produces reproduces across noise seeds only moderately (R median 0.45) and unpredictably.
So the three payout columns do not disagree at the margin, they disagree structurally: usage says some members matter three times more than others, Shapley-on-pixels says every member is equal, and leave-one-out says something else again. TV(use, shapley) median 0.144 on pixel and 0.112 on edges.
Alternative explanation, stated: the uniformity under pixel MSE is consistent with the weakness O12 already recorded for that value function, that it weights area. Seven members each supplying about a seventh of a 32 px mosaic would produce near-equal pixel effects for that reason alone. This run does not separate "credit really is uniform" from "pixel MSE cannot see the difference", and the edge criterion exists in this project precisely because of that failure mode. Design rule 9 gains direct support: the value function is a declaration, and the same bank yields uniform or discriminating credit depending on which one is declared.
Scope
32 px, banks of 7, one engine, 191 sources, two value functions. Exact Shapley is only available at this scale. Nothing here speaks to banks of thousands.
2026-10-14 (RESOLVE steps 1 and 2; protocol frozen, sweep not yet run)
Banks built and the control bank checked. No sweep result exists. measure/resolve_freeze.json written 2026-10-14T14:21:55Z over the protocol, the four scripts, the bank file, the engine, instrument/removal.py, corpus/load.py and the manifest.
Five corrections came out of doing steps 1 and 2, all before any frozen result.
- Cost was wrong by about four times. The protocol's estimate counted one image per bank member, but every source contributes 4 views and the baseline adds 4 more. Banks of 10 would have been 44 images, 1.76 s per generation, 1024 coalitions, 12.0 hours. Banks of 8 give 36 images, 1.44 s, 256 coalitions, 6.1 min per bank-seed, 2.5 hours for 6 banks x 4 seeds. Measured on two real bank-seeds: 342.2 s and 339.6 s, so the corrected arithmetic holds. Bank size changed to 8; exact Shapley stays exact and the predictor is still stable.
- The spine decision was wrong. It read the spine on the L64 views because "the machine sees nothing else". An L64 view is 4 x 3 x 64 x 64 and the Parallax Portrait config is tuned for a 1536 px long edge:
edge_margin_px = 2discards 6% of each edge at 64 px against 0.13% at 1536, andmt_min_island_distance = 24spans 37% of the frame. Replaced by each source's crop at native resolution. A pixel control predictor in L32 view space was added beside it, which turns the "different spaces" objection into measurements R5 and R6. - K4 was unattainable as written ("constant receives exactly 0"). The project already knew: M3's T5d failed at 3 to 7% under schedule S0, and T0FIX replaced the schedule with S1 and set the standard at under 1%. K4 now reads that way. K1, K3 and the duplicate reproduction are likewise pre-validated by M3 and T0FIX.
- The first control run failed K4 at 2.9 to 6.5%, reproducing M3's T5d almost exactly. The cause was the runner, not the bank:
Machine.__init__defaults to S0 and neither script had set S1. Kept asmeasure/resolve_controls.S0_failed.json. Fixed withmachine.schedule = default_schedule()[1:]in both runners. Corpus.subsetkeeps the original owner indices rather than renumbering, which made the first sweep attempt raise "a coalition has no present contributor with images". Also found:corpus/load.pydrops 14 paid-artist commons entries, and sheet views live undercorpus/build/marks64/L32while paintings usecorpus/build/L32.
Control bank, schedule S1, after the fix: all four pass. K1 efficiency 2.78e-17; K2 coalition mask equals the physically reduced corpus at exactly 0.0 on CPU float64; K3 scrambled 0.000 to 0.006 of positive Shapley mass; K4 constant 0.0002 to 0.0004, against 0.029 to 0.065 under S0. The planted duplicate pays exactly 2.0000 of du-01 alone on usage while taking the same Shapley share as its twin (0.0058 each on edges).
Banks (measure/resolve_banks.json): six of eight, composition predictor from 0.978 to 3.053 (3.1x). The composition and pixel predictors correlate at Spearman +0.60 across the banks and dissociate usefully: ingres8 is the closest bank in pixel space (6.4) but mid-range in composition (1.6).
Baseline decided: CONTROL-constant alone for the sweep banks, because the POOL round measured that a commons pool substitutes for removed members and would mask the ranking R is trying to reproduce; the commons pool for the control bank, so it matches M3 game B unchanged.
Re-cut before any run, same day: 6 banks of 8 became 16 banks of 7. The first freeze was discarded unused. Reason: R1, R5 and R6 are correlations across banks, so the bank count is the sample size for the headline claim, and 6 is not enough. At 6 banks the registered R1 threshold of +0.6 carries p = 0.21 two-tailed and significance would need rho = 0.81; at 16 banks the same +0.6 gives p = 0.014 and the threshold for p < 0.05 falls to 0.50. Cost is 32 images, 2.7 min per bank-seed, 2.9 h for 16 x 4, against 2.5 h for the underpowered version. Trading one member per bank for ten more banks barely changes what the question means and is the difference between answerable and not.
Two unplanned improvements came with it. The twelve filler banks are drawn by binning 3,000 seeded candidates on the predictor and taking one per bin, so coverage of the x axis is built rather than hoped for, and composition now spreads evenly from 1.02 to 3.14. And across the 16 stratified banks the composition and pixel predictors correlate at +0.02, against +0.60 across the old 6, so R6's partial correlation is no longer fighting collinearity. Bank overlap is 0.18 shared members per pair, maximum 1.
Frozen again 2026-10-14. All 16 banks dry-load at 7 players, 32 images, 19 schedule steps (S1).
Next: python3 measure/resolve_run.py run (about 2.9 hours, resumable), then resolve_analyze.py.
2026-10-14 (prior-art sweep on RFS's transformer notes; RESOLVE drafted, not frozen)
No run. Prior-art sweep on RFS_transformers and on the attribution literature, with the results added to BRIEF 11.3 (one row upgraded, four added).
- The contraction mathematics in those notes is published. Lemma 1 (Dobrushin contraction on attention rollout) is Rola, arXiv:2610.05558, 4 October 2026, which also proves the equality condition the notes lack and measures how often it holds across eight trained models (essentially always for DINOv2 and the language models, 91% for DeiT-B, 64% for ViT-B/16, 11 to 44% for FT-Transformer). Theorem 2 has the shape of Mitrophanov's 2005 ergodicity-coefficient perturbation bound; the collapse picture is Dong, Cordonnier and Loukas, ICML 2021. Decision: do not build contraction or drift-bound experiments in this project. Three were sketched on 2026-10-13 (credit-resolution decay, receipt drift bound, non-closure as a settlement rule) and all three are dropped. Russell's own DINOv2 measurement in
russell/disagreement-halflifealready tested the mechanism on 1,341 portraits and did not support it once input spread was matched, which is stronger evidence than those experiments would have produced. - Already in the registry, re-checked: Zhao et al. arXiv:2510.14269 (read in full 2026-09-19) and Lin et al. ICLR 2025 arXiv:2407.03153 (checked 2026-09-19). The second is the published form of the collection-level credit conclusion, so this project does not get to claim that conclusion as new.
- Newly registered: Wang, Hertzmann, Efros, Zhu and Zhang, NeurIPS 2024, arXiv:2406.09408, which states the premise from the other side (exact removal is the gold standard and is infeasible, so they simulate unlearning); and arXiv:2401.09031 on timestep-induced bias, whose topic the 2026-10-02 sweep had already found to be known.
- Gap this project still occupies: removal here is exact and costs one rerun. What the literature lacks is not a contraction theorem but a statement of when individual credit is recoverable at all. ICLR 2025 concludes "use groups" without saying which groups or why.
- Drafted:
measure/RESOLVE_PROTOCOL.md. Does a bank's compositional spread decide whether credit to its individual members is recoverable? Not frozen, nothing generated, no bank built. Order of work is in the file: build banks, run the control-bank checks K1 to K4, freeze, then sweep.
2026-10-02 (Patch Ledger paper, version 2)
report/build_paper_v2.py builds ~/Documents/parallaxmetrology/patch_ledger_paper.v2.html from the first draft there (read only, unchanged) plus this project's frozen results, every number read from the result files. Added: section 3.10 (the blind first step: M3 T5d, the t = 1 and chaos-floor diagnostics, T0FIX, the float64 K2 recheck), section 4.6 (O7 at 64 px), key findings 12 and 13, design rule 8, a related-work paragraph, and rows or items in the evidence ledger, sections 6 to 8 and appendices B and C; two references (Lin, S. et al. 2024; Xie et al. 2024). Prior-art search on 2026-10-02: the mechanism (the terminal step predicts the data mean) and timestep bias in influence estimators are known; not found: the effect as a real counterfactual change paid by exact credit, measured with planted null sources, with starting below pure noise as the remedy. Stated in the paper: the first draft's study 1 sampled from t = 1, so its numbers include the vote and have not been rerun. Then added: section 3.11 (study 1's usage, duplicate and generation-time-input findings re-tested on this corpus under T0FIX F3/F4, M4 D1/D3, POOL P1/P3; SPLIT post hoc), key finding 14, design rule 9 (declare the unpaid pool and each party's division), the 64 px size result beside section 4.5's "No evidence", and section 3.10 in the reading guide by role.
2026-10-02 (paid receipts on the full pool; two frozen versions preserved)
Paid receipts, seeds 9000 to 9003, 86-painting pool (receipt/make_paid.py, make.py unchanged; receipt/receipts_full/): every planted control passes on 4 of 4 seeds (constant at most 0.78%, scrambled at most 0.37%, copy ratio 1.91 to 1.99; the 10-painting demo pool failed one control on 2 of 4). With the full pool the six artists hold 48% to 63% of the posterior mass (demo 89% to 94%) and their total effect under edges is 0.073 to 0.156 (demo 0.237 to 0.373). Shapley shares, edges: Ingres first on every seed (0.25 to 0.27). No copies (nearest training image 42.4 to 48.9 levels against typical 72.8 to 77.6). Verifier on every receipt: all checks pass. Page: a Pool selector (10 paintings, visual demo / 86 paintings, paid receipts); browser-checked on seed 9000 with a 4-combination replay (bit-identical, V1 to V7 pass). Report finding 15, built list and open items, labbook receipts section and status rows (M6, O6) updated.
Freeze audit while preparing the package: 91 frozen file hashes match; two do not, both engine/tio/static_attention.py (ATTN1 and ATTN2 froze it). Traced from the session record: after ATTN1 the documented batch-invariance fix (above, ATTN1 K2); after ATTN2 a docstring wording change only (code identical with docstrings removed). Both earlier versions reconstructed by reversing the recorded edits; each matches its freeze hash exactly. Kept, read-only, in measure/frozen_code/ with a checker (check.py, 2/2) and instructions for re-running either test exactly. Frozen files themselves untouched.
2026-10-02 (preparing to share: names and channel references removed from the brief)
For sharing: the brief no longer cites team-channel or thread IDs or names people from team discussion; those sources are described by date and topic. One phrase in section 2 reworded ("keeps returning to one question"). A stale description of a collaborator's public profile was replaced. Credit for work (Riley Peterlinz's construction and repository, RFS's training-data release) keeps its names. Labbook rebuilt (it embeds the brief's source list).
2026-10-02 (O6 cost table; paid receipts on the full pool started)
measure/o6_cost.py -> measure/o6_cost.json (measurement): one full-coalition picture, MPS float32. At 32 px: pool 10 (424 images) 11.3 s, 21 (468) 12.7 s, 43 (556) 15.6 s, 86 (728) 20.7 s: time grows about linearly with the images in play. At 64 px: pool 10, 148 s; pool 86, 258 s. GPU memory flat at 1.1 GB (32 px) and 2.2 GB (64 px) because the engine works in chunks. A receipt (64 artist coalitions plus 64 control coalitions) at most 0.4 to 0.74 hours at 32 px and 5.3 to 9.2 hours at 64 px. Speed measured in M5 (pruning 1.05 to 1.10x) completes O6. Paid receipts on the full pool (receipt/make_paid.py, wrapper around make.py, unchanged; output receipt/receipts_full/) started for seeds 9000 to 9003.
2026-10-02 (O7 result: direction transfers strongly at 64 px; size and finished-image visibility do not)
Phase C finished 09:22 (measure/o7_results.json; frozen record stage2/phase_c_freeze.json). Ledger reconstruction of the machine's predictions 1.3e-7 to 1.9e-7 at every step.
- P1 HOLDS: direction, p = 1/720, the smallest possible (S = 0.142; own-prediction rank per network cezanne 1, durer 2, ingres 1, kollwitz 1, rembrandt 1, vangogh 2). At 32 px the patch-ledger had S 0.039 and 0.059: the specificity is stronger at 64 px.
- P2 FAILS: 1 of 6 artists resolvable above the training-noise floor in finished images (edges floor median 0.0636; artists cezanne 0.0081, durer 0.0258, ingres 0.0228, kollwitz 0.0365, rembrandt 0.1248, vangogh 0.0261; only Rembrandt exceeds it).
- P3 FAILS: Spearman -0.14 between the machine's exact leave-one-out sizes and the networks' (edges). Rembrandt is the largest network effect (0.125) and the smallest machine effect (0.0077).
- P4 FAILS, in the opposite direction from the 32 px pattern: the per-step direction agreement is positive at every measured step (t 0.85: 0.040, peak near t 0.4 to 0.55, t 0.15: 0.119); at 32 px it was negative in the early, noisy steps.
Reading: at 64 px the exact machine tells which way a trained network changes when an artist is removed, more specifically than at 32 px, and from the noisiest measured step on; it does not tell how much, and in finished images single-artist removal is mostly below the difference between two training runs. Limits: one start seed for the leave-out networks; a network's leave-out difference includes training divergence (same start weights, different data), the floor uses a different start seed; one network family (convolutional, receptive field 17).
2026-10-02 (O7 phase B complete; phase C frozen and running)
Phase B finished 02:47 with no errors: no_cezanne, no_durer, no_ingres, no_kollwitz, no_rembrandt, no_vangogh and full_s1, about 100 minutes each. Phase C frozen 04:43 (stage2/phase_c_freeze.json: the code, the protocol, the calibration and all eight networks' final.pt hashes) and started (stage2/phase_c.log), estimated 5.5 GPU hours.
2026-10-01 (O7 phase C code written and tested; not yet frozen)
The Claude session crashed mid-afternoon; the overnight run (a separate process) was unaffected: no_cezanne finished 16:20, no_durer started 16:20. stage2/phase_c.py implements the protocol's D, F, M and T exactly (D ported from patch-ledger score_test.py). Tests: (1) CPU smoke on one noise and two steps with the two finished networks: the per-contributor ledger reconstructs the machine's prediction to 1.8e-7 and 2.2e-7 (float32); (2) synthetic_check() on planted data (network changes = machine predictions + noise for the matching artist): D recovers the planted assignment at the smallest possible p (1/720), every own-rank 1; F and M computable (6 resolvable, Spearman 1.0). Each stage now saves its pieces to stage2/phase_c/. Freeze (stage2/phase_c.py freeze, code plus every network's final.pt hash) after phase B completes, then run; estimated 5.5 GPU hours (machine leave-one-out at 64 px dominates).
2026-10-01 (O7 phase A: the gate passes, median r 0.970)
full_s0 trained 10:33 to 12:26 (113 minutes, 10,000 steps, 64 px). Calibration 12:26 to 14:11 (105 minutes): the machine's best patch size per step falls from coarse to fine as noise falls, 13 13 13 13 13 11 9 9 7 7 7 5 5 5 5 3 3 3 3 (t 0.95 to 0.05). Agreement on 8 noises (seed 70000): Pearson r 0.965 to 0.973, median 0.970 against the registered 0.85: gate passed (prediction G held). At 32 px the patch-ledger reference was 0.94. Phase B started 14:35 (six leave-one-artist-out networks and full_s1; about 113 minutes each, finishing about 03:50).
2026-10-01 (RFS's cost arithmetic, checked)
measure/rfs_scale.py reads SCALE.md from his zip (read-only): people $311,825 of $319,421 = 97.62% (stated as 98%); edit triplets $170,000, 22.5 times the $7,562 compute. Under the same assumptions one training run is about 420 GPU-hours, $1,260; ten group-level retrainings (how removal credit is measured on trained models) about $12,603, 4.0% of the people bill. Added to the findings' smaller results as arithmetic on his stated assumptions.
2026-10-01 (how strong each registered result is: sign tests and family-bootstrap intervals)
measure/intervals.py -> measure/intervals.json (post hoc; verdicts unchanged). Independent units are noise seeds. With four seeds the best possible one-sided sign-test p is 0.0625 (POOL P1, ATTN1 Q3, ATTN2 R2, O12 all 4/4, p 0.0625); with two seeds (M4, SPLIT) it is 0.25. No single registered result reaches p < 0.05 on its own. Effects are large relative to seed spread (e.g. SPLIT L1 paper minus lines 0.581 [0.532, 0.629]; POOL P1 0.119 [0.102, 0.136]); POOL P2, which failed, is the one interval containing zero (0.053 [-0.007, 0.113]). Bootstrap over 2 to 4 seeds understates uncertainty; stated in the findings. Added to the findings as "How strong each result is", with RFS's release in the smaller results.
2026-10-01 (RFS's training-data release: read and reproduced)
RFS_training/training-data.zip unpacked to the scratchpad (original untouched). check.py: 109/109; check.py --rebuild: the rebuild reproduces the identical release fingerprint, 110/110; evaluate.py re-run: evals/report.json byte-identical to the shipped one. The toy attention training (tens of CPU minutes) was not run while stage two holds the GPU. Links to this project: its record mapping separates what went into a picture, how payment is divided (shares) and measured influence ("needs its own method and its own evaluation"), the separation this project measures (use, LOO, Shapley); its tombstone record asks for a review of models trained on earlier releases, the question O7 tests; family splits, a graded oracle and the attention-map caveat parallel this project's duplicate rule, planted controls and ATTN2. Opportunity taken from it: intervals and sign tests for this project's per-seed results.
2026-10-01 (resumed: paid sketch receipts work end to end; stage two launched)
- First sketch receipt run failed at the last stage: the shared receipt writer listed the drawing as a corpus party (KeyError 'input'). Fixed in
receipt/make_drawing.py(artists only passed as request players; the drawing is described in request.input and named "drawing" in results.players);receipt/make.pyuntouched. - Circle test drawing, seed 9100, k 14 (
receipt/receipts/drawings/6922bc251f_*): verifier V1 to V7 all pass, including a spot replay of input-present coalitions from the stored pixels, bit-identical. Shares (edges) drawing 0.943, Kollwitz 0.057, others 0, matching M4's frozen run on the same seed to three decimals (the receipt's drawing is the uint8-rounded one); description paper 0.417, lines 0.542, matching SPLIT. Seed 9100's planted controls all pass. - Page: a drawn X through "Pay the artists for this drawing" produced sealed receipts in 278.6 s (job 1c2e1bd456): drawing 93.8%, Kollwitz 6.2%; paper 44.8%, lines 50.9%; not a copy; controls pass. Browser-checked.
- Stage two: smoke run (timings, disclosed in the protocol): training 0.636 s per step at 64 px (about 106 minutes per network), calibration about 98 minutes. O7 frozen (
measure/o7_freeze.json) andstage2/overnight.shlaunched 10:33: phase A (full_s0, calibration, agreement, gate) then phase B (six leave-one-artist-out networks and full_s1), about 16 hours. Log:stage2/overnight.log.
2026-10-01 (paused for the day, Russell travelling)
The first sketch receipt (circle test drawing, seed 9100) was stopped by hand at its third stage (drawing combinations) so nothing runs while the laptop travels. Its two caches finished and are kept (receipt/cache/absent_9100_...pt, controls_9100_...json); the next sketch receipt starts from them. Nothing else was running. Resume list: sketch receipt and paid-button browser check; stage-two smoke test, disclose, freeze, launch stage2/overnight.sh; findings report rebuild; memory update.
2026-10-01 (receipts format 3 made; planted controls fail on 2 of 4 seeds with the small pool; stage two prepared)
- Demo receipts regenerated as format 3 (version 2 moved to
receipt/receipts_v2/): every main game bit-identical to version 2. Planted controls per receipt (rules from T0FIX, registered on the 86-painting pool): seed 9000 copy 1.81 pass, scrambled 0.00% pass, constant 1.18% (colour) fail; seed 9001 copy 1.85 pass, scrambled 2.19% (edges) fail, constant 0.44% pass; seed 9002 copy 1.84, scrambled 0.33%, constant 0.59%, all pass; seed 9003 copy 1.82, scrambled 0.15%, constant 0.18%, all pass. With the 10-painting pool every share is larger, the nonsense contributors' included. Rules not changed; receipts and page show the failures. - Decision (Russell, on recommendation): paid receipts will use the full 86-painting pool (controls hold there); the visual demo keeps the 10-painting pool, labelled. Remaking paid receipts on the full pool (about 4 to 5 GPU hours) is queued after stage two.
- Tests after these changes: engine 51/51 (T3 float32 on MPS reported: 5.25e-6); tamper suite 8/8 including E7.
- Stage two prepared (
stage2/): patch-ledgertrain.py,phase3_checks.py,score_test.py,phase3_predict.pycopied verbatim and read-only intostage2/ORIGINAL/(hashes in its PROVENANCE.md, identical to source). Ported:net.py(network class, time embedding and schedule checked verbatim against the original),train.py(demo corpus at L, leave-one-artist-out, NaN abort),check.py(calibration and agreement on this engine and schedule S1),o7.py(freeze, verify, gate),overnight.sh. Protocolmeasure/O7_PROTOCOL.md(64 px, demo pool, gate median r >= 0.85, phases A and B overnight, phase C fixed now and coded later).
2026-10-01 (findings report; receipts format 3 with planted controls; paid sketch receipts; T3 redefined)
report/build_report.py->report/FINDINGS.html(local): what was built, ten findings with their numbers read from the result files at build time, each labelled held / mixed / failed / exploratory / measured with its evidence, implications, limits, open items. Colab numbers saved asmeasure/o9_cuda_run.jsonso the report can cite them.- Receipts format 3 (
receipt/make.py): acontrolsblock in every receipt, T0FIX game B on the receipt's own noise and pool (copy, scrambled, constant), C read off B's outputs, pass rules = T0FIX F1 to F3; control views hashes. Verifier V7 recomputes Shapley for B and C from the recorded v by permutation, the shares, the copy ratio and the pass flags; new tamper test E7 (a flipped pass flag). Page section 5 shows the picture's own controls. receipt/make_drawing.py: sealed, paid receipts for a viewer's own sketch (drawing as one player, pixels stored for replay, paper/lines as description, the seed's controls and no-drawing half cached and reused exactly). Verifier V5 replays input-present coalitions from the stored pixels with its own copy of the coupled start (same operation order as the engine). Server job endpoints and a page button. Not yet run (waits for the GPU).- Engine test T3 in float32 changed from pass/fail to a reported measurement (float64 keeps the check at 1e-12), after the CUDA run showed the float32 sum error is rounding that grows with log-mass magnitude (1.5e-5 on a T4, under 1e-5 on MPS) and the old threshold was taken from MPS runs. Recorded here as a definition change made after a measurement.
measure/O7_DRAFT_PROTOCOL.md: stage-two draft (trained networks at 64 px; direction, magnitude, resolvability), for review; nothing trained.
2026-10-01 (O9: first CUDA run, Colab Tesla T4; the receipts hold across hardware)
Run by Claude in Russell's signed-in Chrome with his explicit go-ahead for the upload (notebook Untitled7.ipynb in his Drive; the bundle went to the Colab session's temporary storage, deleted when the runtime ends). Environment: Tesla T4, Python 3.13.15, torch 2.11.0+cu128 (ours: torch 2.12 dev on MPS), so a different GPU vendor and torch build.
The result O9 asks for:
- Shipped receipt (made on MPS) replayed on CUDA: V1 to V6 pass; V5 worst |dv| at 0.005 of the cross-backend tolerance; source images NOT RUN (not in the bundle), as designed.
- Fresh receipt made on the T4 against the shipped one: worst |dv| / tolerance pixel 0.003, edges 0.005, blur 0.005, colour 0.000; Shapley shares moved by TV 1.7e-7, 5.9e-7, 1.1e-7, 0. About 3.5 minutes for 64 coalitions (MPS: about 7).
- Tests on CUDA (second run, corrected bundle): engine 51/52, removal 16/16, input 5/5, parts 4/4.
Found by the run, and what was done: 1. The bundle was missing files the tests import: measure/crop_scale_edges.py and its imports (crop_scale.py, corpus/build_corpus.py) for test R5, and engine/ORIGINAL/ for test N5. Added; the bundle builder now has these, and every test was run from an unpacked bundle on this Mac before re-uploading (52/52, 16/16, 5/5, 4/4). 2. V6 compared the nearest-image distance across backends at 1e-6; across hardware the distance differs in the sixth decimal (39.603884 vs 39.603886). V6 now uses 1e-6 only when the output is bit-identical to the receipt's and 0.01 levels otherwise (owner and flag must still match exactly). Passed on the second run. 3. The notebook's cells relied on imports in its first (upload) cell; each cell now imports what it uses. 4. T3 [cuda/float32] masses sum to 1: 1.51e-05 against a 1e-5 tolerance (open). Diagnosed in the same session: a plain log-sum-exp normalisation on the T4 is tight (2.4e-7), while the engine's mass sums are 1.3e-6 to 3.9e-6 at every step and 1.5e-5 at the final, lowest-noise step, where log-masses are largest, so float32 rounding of exp(lse_c - lse) grows with their magnitude. A float32 conditioning limit of the engine, larger on CUDA than on MPS, not a hardware fault; the CPU float64 reference passes T3 exactly and payouts are unaffected (above). The tolerance was set from MPS runs. Not loosened after the fact: the next step is to state the float32 bound from the log-mass magnitudes and test against that bound on every backend, or to normalise against a per-pixel reference inside the engine (which changes outputs bit-for-bit, so it would need new receipts).
2026-10-01 (receipts format 2: total effect and copy check, after ATTN1)
receipt/make.py->take-it-out-receipt/2: acontextblock with the players' total effect (v(all) - v(none), which the Shapley values sum to), their fraction of all posterior mass, and the nearest training image to the full output among the owners in play (owner, group, RMS in levels of 255, typical distance, and a declared flag: copy <= 1 level, near copy <= 8 levels).receipt/verify.pyV6: total effect and mass fraction recomputed from the receipt's own numbers; the nearest image recomputed independently from the corpus arrays on disk and the full output (from a replay, or from--outputsafter its hash is checked); NOT RUN, and reported so, when no output is available.- Version-1 demo receipts moved (not deleted) to
receipt/receipts_v1/. Seeds 9000 to 9003 regenerated on MPS: every output hash and every v(S) identical to version 1. Context: total effect (edges) 0.249, 0.237, 0.322, 0.373; artists hold 89% to 94% of the mass; nearest training images 39.6 to 46.6 levels away against typical 59.8 to 72.0: no copies in the demo. - Tamper tests on the format-2 receipt: 7/7, including new E6 (an edited nearest-image claim, re-sealed, is caught by V6 from the saved outputs with no generation; the untouched receipt passes).
- Page: section 2 states what is being shared and the copy check under the payouts (browser-checked on seeds 9000 and 9003, and the copy branch checked with a substituted context, then restored). Bundle rebuilt.
2026-10-01 (ATTN2: frozen-attention receipts do not report the source; they pay a fixed pair)
instrument/attention_law.py (library ch. 49 in VP coordinates), tests 3/3: our exact and frozen posteriors reproduce the library's Study 13 fixtures to 1e-16 (three-token reversal: exact 0.924 / 0.076, frozen 0.158 / 0.842; two-token equality), and query plus row recovers a 16 x 16 noisy image to 1.3e-15. Static-attention engine made batch-invariant (rows denoised one at a time) after ATTN1's K2; new test A9 (batch of 8 equals one at a time, bit for bit): 9/9.
Protocol measure/ATTN2_PROTOCOL.md frozen after a timing-only smoke run; 12 runs (4 seeds x beta 1, 4, 16), greyscale 16 x 16 demo corpus, CPU float64. measure/attn2_results.json.
- K1 HOLDS (weights sum to 1 within 3.3e-15); K2 HOLDS (row inversion error 5.6e-16).
- R1 HOLDS (4/4): mean TV between the frozen receipt and the exact posterior over steps 10 to 18 (beta 4): 0.89, 0.53, 0.52, 0.75.
- R2 HOLDS (4/4): the gap grows as noise falls (last step 1.00, 0.56, 0.51, 1.00 against step 5 0.42, 0.33, 0.49, 0.25).
- R3 HOLDS (4/4): the top-paid group at the last step is wrong on every seed.
- Reported: at beta 4 and 16 the frozen receipt converges to about Dürer 0.5, Kollwitz 0.5 on every seed, while the exact posterior names one artist that changes with the seed (beta 4: Rembrandt, Dürer, Kollwitz, Van Gogh). The frozen receipt describes the generator's attractor, not the picture's source. At beta 1 it is diffuse (every group 0.1 to 0.3) while the exact posterior is one artist. The fraction of pixels whose own frozen top group matches the exact one at the last step: 0.00 to 0.55.
Reading. Plugging realised attention into the static formula, the natural first route for extending any static-attention construction to attention models, gives payouts that are neither the posterior of what the layer observed nor stable to the picture. The library's three-token counterexample (C72) holds at image scale and is the typical case, not an edge case. Limits, stated with it: scalar tokens, one head, greyscale 16 px, no learned projections or residual stream; the exact posterior here is the whole-image one because the row is retained (a layer that keeps only its output has a different, harder law, ch. 49 section 6); and this is posterior accounting, not removal credit (ch. 48 section 7). Consequence: static-attention receipts are not receipts for attention models. The static machine stays useful as a generator in its own right (its attention is genuinely fixed).
2026-10-01 (ATTN1: attention changes who gets paid; global attention copies; a receipt flaw)
Static-attention machine extended to several heads with support-aware rank handling (library ch. 48); tests 8/8 (A6 two heads equal a brute-force Gaussian over the full observation, 1.0e-15; A7 a duplicated head and A8 a self-only head change nothing, difference 0, no jitter). Protocol measure/ATTN1_PROTOCOL.md frozen after a timing-only smoke run; 12 games, CPU float64, about 4 s each. measure/attn1_results.json.
- K1 efficiency HOLDS (2.2e-16).
- K2 FAILS as registered (bitwise): batched coalitions differ from one-at-a-time runs in 53,964 values. Diagnosed: one denoise step differs by 1.3e-15 between batch sizes (summation order in the batched contraction), 1.5e-13 in outputs after a full run; Shapley values move by 6e-16 relative. Not a logic error, but this machine is not batch-invariant to the last bit, so a receipt from it replays bit for bit only at the same batch size. Fix after this test: rows denoised one at a time. (Correction, 2026-10-02:
engine/tio/static_attention.pywas one of ATTN1's frozen files, so this fix changed a frozen file; the frozen version is preserved, hash-checked, inmeasure/frozen_code/attn1/.) - Q1 HOLDS (3/4): by edges, local attention moves 9% to 27% of the money compared with none (0.27, 0.15, 0.27, 0.09).
- Q2 FAILS (1/4): global context moves pay far more than local, not less: by pixels TV(none, global) 0.16, 0.50, 0.22, 0.74 against TV(none, local) 0.12, 0.05, 0.05, 0.08.
- Q3 HOLDS (4/4): local attention concentrates pay on the top artist (edges: 0.35 vs 0.18, 0.26 vs 0.21, 0.34 vs 0.21, 0.23 vs 0.19).
- Reported: the posterior sharpens with attention. Effective training images per patch at steps 0, 5, 10, 15, 18 (seed 9300): none 421, 343, 213, 72, 7.1; local 385, 132, 38, 4.5, 1.1; global 270, 25, 3.8, 1.2, 1.0. Use vs Shapley TV (pixel) grows with attention: none 0.15 to 0.17, local 0.16 to 0.33, global 0.36 to 0.52. Global pay is winner-take-most and seed-dependent (9301: Van Gogh 0.49; 9303: Kollwitz 0.49, Rembrandt 0.51, the rest 0).
Post hoc, exploratory (measure/attn1_posthoc_copy.py, panel measure/attn1/attn1_panel.png): nearest training image to each full-coalition output, RMS in levels of 255. None 54 to 56; local 31 to 41; global 22 to 48, and on seed 9303 0.0: a verbatim copy of a commons painting (met-dp-20645-001). In that game the artists' summed effect is small (pixel 0.065 against 0.21 to 0.46 elsewhere under global) and they hold 21% of the posterior mass, yet normalised shares pay them 100% of the artist pool (Kollwitz 0.49, Rembrandt 0.51) while the copied work, in the unpaid pool, gets nothing. Reading: attention shares information across patches, the posterior collapses toward a whole image, which is the library's ch. 49 point (observing the full row recovers the input) seen at image scale. The more global the attention, the closer the machine comes to the memorising ideal score, the more pay concentrates, and the further use drifts from Shapley.
Receipt flaw exposed (applies to every machine, not just attention): normalised shares hide the size of the total being shared, and nothing in a receipt says when the output is a copy. Required additions, to be registered and built: (1) every receipt reports the nearest training image to the output, its owner and distance, and flags a copy; (2) every receipt reports the players' total effect beside the shares, so 100% of a tiny effect is visible as such.
2026-10-01 (Russell's library on attention: complements the repository; stage two planned around both)
Read image-steering-accreditation/references/48_conditional_denoising_attention.md, 49_input_dependent_attention_laws.md, 75_learnable_denoising_representation_bottlenecks.md, 46_anml_attribution_guarantees.md (section 4) and the attention rows of CLAIMS.md (C67 to C75, C215) and GAPS.md.
- 48 section 3 (2026-09-09) already derives the static-attention form, from Riley's drafts, in the conditional factorisation that
engine/tio/static_attention.pyuses (conditional covariance t^2 S_-i S_-i^T): the "cleaner form" logged above is the library's, not new here. It extends the same construction in three directions: several heads with cross-head covariance S S^T, the exact rank condition (positive definite iff the off-self columns S_-i have full row rank H, C68), and support-aware treatment of singular cases (jitter changes the model; "determinant 0 -> estimate 0" is wrong on the support). - 48 section 5 and 49 (C69, C72): attention computed from the input is not attention frozen at its value. For a scalar dot-product head the exact law is derived; the frozen-window posterior can reverse source preference (a three-token counterexample), and is exact in an invertible two-token case. Observing a query and a full attention row recovers the noisy input (C71), which pushes the posterior toward the whole-image form. Directly relevant: a static-S machine is a model of exogenous attention, not of a transformer, and attribution under it can rank sources in the wrong order.
- 48 section 7 and 46 section 4: posterior accounting, removal effects and allocation are different objects, the same separation our use / leave-one-out / Shapley results measured (POOL, M3).
- 75: "learnable attention is missing" is too broad a gap; a contribution must say which assumption it removes. Li, Min and Vidal give a restricted training theorem.
Consequence for stage two: extend the repository's single-head form with 48's multi-head, rank and support-aware treatment; and make the frozen-versus-input-dependent question (C72) part of the registered test, since it is what decides whether static-attention receipts say anything about transformers.
2026-10-01 (stage two: a static-attention machine of our own, checked against Riley's)
engine/tio/static_attention.py: Riley's construction, implemented independently in this engine's variance-preserving coordinates, with owner masses and member masks like machine.py. One change in form, not in result: the context is split as v_i = S_ii x_i + r_i (r_i the off-diagonal mixture), whose noise is independent of the patch's own given a training image, so the weight exponent is ||dx_i||^2 + ||dr_i||^2 / d_i with d_i = sum_{j != i} S_ij^2 computed directly. Same as inverting his 2 x 2 covariance, but no inverse and no jitter; d_i = 0 (S = I) is exact, where his a*c - b*b cancels.
engine/tests/test_static_attention.py, 5/5: A1 S = I, p = 1 equals our "ls" machine over a full run (2.3e-15); A2 equals Riley's AnalyticScoreDiT with a dense S, p = 2, jitter 0 (3.1e-15); A3 a member mask equals a corpus without the owner (difference 0); A4 masses sum to 1 and the output is the weighted sum of training patches; A5 MPS float32 agrees with CPU float64 (max 2.9e-8).
2026-10-01 (prior-art search on Riley's static-attention form)
Searched for a closed-form denoiser in which each patch conditions on itself and a fixed linear mixture of the other patches (Riley's AnalyticScoreDiT). Closest found (BRIEF 11.3): Finn et al. 2025 (content-dependent attention after a CNN, top-1 simplification, 4x4 toys); Niedoba et al. 2026 FPMC (diagonal precision only, explicitly no mixing across positions); Li, Min, Vidal 2026 (transformers approach the population MMSE denoiser on Gaussian mixtures); Haddadi et al. 2026 (the empirical denoiser's softmax is an attention computation). None found conditions on a fixed cross-position mixture with the joint Gaussian; the form looks unpublished as far as this search goes (abstracts and summaries, not full texts of every paper). It is a fixed-S result; content-dependent attention, which trained transformers use, is the natural next step (Finn et al. approach it from the CNN side).
2026-10-01 (Riley's code: permission)
Russell confirms Riley's permission: the team may use, copy and change the repository freely. Recorded here as the grant. A licence file would let anyone outside the team who receives our code see the same terms; an opportunity to mention when convenient.
2026-10-01 (Riley's repository arrived: read, reconciled with the engine)
Source: github.com/CardiacMangoes/diffusion, commit 6b757a5 (2026-09-02), cloned to the scratchpad and run from the clone (permission to use it freely confirmed the same day, entry above).
What it holds: AnalyticScore (the whole-image MMSE result of BRIEF 6.1, rectified-flow time), AnalyticScoreDiT (new to us: a closed form for a patch denoiser with a static attention matrix S; each non-overlapping patch i weighs training images by the exact joint Gaussian of its own noisy value z_i and the mixed context v_i = sum_j S_ij z_j, covariance t^2 [[1, S_ii], [S_ii, sum_j S_ij^2]] per feature), trained DiT and DiT_ablated models with fixed attention windows, training code, and tests_2d.ipynb (88 cells, a two-pixel toy comparing one-layer DiTs trained with S = [[a, 1 - a], [1 - a, a]] against the analytic form, as videos). This advances the attention case the derivation PDF (pp. 12 to 13) left open: it is solved here for a fixed S.
measure/riley_reconcile.py -> measure/riley_reconcile.json (CPU float64):
- R1 his whole-image score equals our "is" variant after the time conversion: max relative difference 1.2e-14.
- R2 his DiT form with patch size 1 and S = I equals our "ls" variant with P = 1: 1.3e-6 at his default jitter 1e-5, 2.4e-8 at 1e-7, 3.8e-8 at 1e-9 (with S = I the covariance is singular, so the jitter sets the agreement level, with a floating-point floor near 4e-8).
- R3 his closed-form 2 x 2 algebra equals a brute-force Gaussian log-density for a random dense row-stochastic S: weights agree to 3.9e-16, sum to 1 within 4.4e-16.
- R4 removal is exact in his form: weights without image k equal the full weights renormalised (3.3e-16); output equals the weighted sum of training patches (8.9e-16). Our removal instrument applies to his generator unchanged.
Opportunities noted while running the repository (shared with Riley; nothing changed in his code): (1) on Python 3.13 and later, scores.py line 1 (from re import T) needs the name re.T, which newer Python no longer provides; defining it before import is enough here, and the line can simply be removed. (2) AnalyticScore returns E[eps | z] (R1 confirms it); its docstring describes the score, so aligning the two would help readers. (3) The notebook predates the current AnalyticScoreDiT(x, p, jitter) signature (S now passed to forward); updating its calls would let it run against the current code. (4) Adding the trained weights (model_weights/), or a script to regenerate them, would let others reproduce the notebook's comparisons.
2026-10-01 (M5: cost at 64 px measured; one picture each, exploratory)
measure/m5_cost64.py -> measure/m5_cost64.json, measure/m5_cost64.png. MPS float32, demo corpus (728 images, commons 10), full coalition (the most expensive), seed 9000, after a warm-up.
| Setting | Patch sizes (px) | Seconds per picture | 64-coalition game, upper bound |
|---|---|---|---|
| L 32, S1 | 3 to 11 | 11.5 | 0.21 h |
| L 64, S1 patch sizes as they are | 3 to 11 | 150.8 (13x) | 2.7 h |
| L 64, patch sizes doubled | 7 to 23 | 217.7 (19x) | 3.9 h |
The 13x is close to the cost model's 16x (L^4), a little under it because the border positions grow more slowly. Looking at the pictures: at 64 px, without a drawing, the output is still a mosaic of paper tones and painting colours, smoother with doubled patches; it does not look like a drawing. One picture is not a test, but it does not support O12's hope that resolution alone makes drawings appear. What did make lines appear was the viewer's drawing (M4, SPLIT at k = 14). Next for 64 px, when it is worth three hours of GPU: a receipt for one test drawing at k = 14.
2026-10-01 (O9: notebook executed end to end here, on MPS and on CPU; tamper tests after the verifier change)
- Receipt tamper tests re-run after the V2 split: 6/6 (E5 now caught by "V2 every owner's source file matches").
- Notebook executed from the unpacked bundle (
jupyter nbconvert --execute, scratchpad copies), twice: - MPS: bundle 638 files, no mismatch; tests engine 52/52, removal 16/16, input 5/5, parts 4/4; shipped receipt V1 to V5 pass (spot replay bit-identical); a fresh receipt made today is bit-identical to the shipped one (every v, every share: difference 0), 64 coalitions in 400 s.
- CPU float32 (cross-backend against the MPS receipt): V5 spot replay worst |dv| at 0.006 of the tolerance; fresh receipt worst |dv| at 0.000 to 0.009 of the tolerance, Shapley shares moved by TV at most 9.5e-7. 64 coalitions in 560 s.
- Found while reading the outputs: the test cell printed each script's last line, which for the engine is a PASS line, not the total. Fixed (exit code, "n/n passed", any FAIL lines); cell ids added (nbformat warning).
- Still open for O9: a CUDA runtime (Colab). The bundle and notebook are ready; uploading them is Russell's call. In the source-image check, these runs found the originals (they exist on this Mac); the NOT RUN path was tested by simulation earlier and is what a Colab run will show.
2026-10-01 (POOL: results. The use gap grows with the pool; leave-one-out's gap shrinks)
Run about 3 h 35 min (16 games). measure/pool_results.json.
- K1 efficiency HOLDS (5.6e-17).
- P1 HOLDS (4/4): by pixels, TV(use, Shapley) is larger with the full pool (N = 86: 0.26, 0.29, 0.32, 0.27) than with the demo pool (N = 10: 0.12, 0.20, 0.19, 0.15) on every seed.
- P2 FAILS (2/4): by edges there is no pool trend (N = 86: 0.15, 0.17, 0.29, 0.17; N = 10: 0.16, 0.17, 0.16, 0.09; N = 43 is highest on two seeds).
- P3 HOLDS: pixel medians fall at every step, 0.278 (86), 0.246 (43), 0.215 (21), 0.170 (10).
- Reported: blur and colour follow pixel (colour 0.34 at 86 to 0.19 at 10, medians). The artists' share of all posterior mass rises as the pool shrinks (0.53 to 0.70 at 86; 0.89 to 0.96 at 10), and the artists' summed effect v(all artists) by pixels roughly doubles (0.04 to 0.06 at 86; 0.12 to 0.13 at 10): a big pool substitutes for them. No artist had a negative Shapley value by pixels at any size.
Not predicted: leave-one-out moves the other way. TV(leave-one-out, Shapley) by pixels rises as the pool shrinks: 0.11 to 0.15 at 86, 0.20 to 0.26 at 10. With a big pool the artists act nearly independently (removing one is close to its average effect); with a small pool they are most of the mass and substitute for each other, so one removal at a time misreads them. Neither cheap rule tracks Shapley across pool sizes: use errs most with a large pool, leave-one-out with a small one. Exact Shapley does not depend on this choice; receipts state the rule and the pool size.
Registered consequence (P1 held): receipts and the page state the pool size beside every use-based share and say that use over-reads as the pool grows. Done on the page (section 2 text now quotes these measurements). Receipt format unchanged: every receipt already records its baseline owners, from which the pool size is read.
2026-10-01 (O9: a bundle and a notebook for running it elsewhere; verifier V2 split)
receipt/verify.pyV2 split in two. The views arrays the generator reads are always checked. The original source images (absolute paths on this machine, 252 MB) are checked when present; when none is present, as in a bundle, the check prints NOT RUN and is recorded with ok = null, never as a pass. Some present and some missing fails. Re-run on seed 9000 edges here: all pass, including the source-image check. Tamper tests (E1 to E5, need MPS full replays) to be re-run after POOL frees the GPU.colab/make_bundle.py->colab/take-it-out-bundle.zip(local file; sharing is Russell's call): code, demo corpus arrays, seed 9000 receipts, notebook, BRIEF and LOG, with a SHA-256 list of every file. 638 files, 6.9 MB.colab/build_notebook.py->colab/take_it_out.ipynb: checks bundle hashes; runs engine and instrument tests on every available backend; verifies a shipped receipt with a spot replay on the local device (cross-backend tolerance); makes a fresh receipt there and reports, per value function, the worst |dv| against the tolerance and how far the Shapley shares moved. Not yet executed end to end (waits for the GPU).
2026-10-01 (M5 diagnostic: certified pruning is not the speed lever at this scale)
Exploratory, not registered (measure/m5_prune_diag.py -> measure/m5_prune_diag.json; CPU float64, one trajectory, seed 7, demo corpus with commons 10, 64 random query pixels per step, every allowed candidate computed exactly). First attempt reported fractions above 1: it divided per-query counts by the mean candidate count, but edge pixels allow 424 candidates and interior ones up to 381,600. Fixed to per-query fractions; summed work reported separately.
- The posterior is broad. Candidates needed to hold all but d of the mass (the ceiling for any pruning, even an oracle): at d = 1e-6, 92 to 100% of candidates in steps 0 to 3, 46 to 87% in steps 4 to 9, falling to 2.5% only at the last step. Schedule-weighted (by patch dimension), an oracle saves 1.9x at d = 1e-3, 1.4x at d = 1e-6, 1.3x at d = 1e-9.
- Certified bounds are loose where it matters. Bounding each candidate's logit from an orthonormal projection (patch means per channel; top 16 or 32 principal directions) and evaluating until the bound on the rest is below d: 1.05x to 1.10x overall. Useful only in the last few steps (pca16 at the final step: 3.7% of candidates).
- Weighting caveat: steps weighted by patch dimension only; allowed-candidate totals also vary by step (205k to 382k for interior pixels), which would shift these ratios slightly, not their order.
Reading (an operating window, not a dead end): at 32 px with this corpus the ELS machine mixes over thousands of patches at most noise levels, so exact credit cannot be bought cheaply by skipping candidates. BRIEF M5's planned lever is retired. What remains: (1) measure the real cost at 64 px directly (one sample, GPU, after POOL); (2) 64 px demo receipts precomputed, not live (a 64-coalition game is then hours, not minutes); (3) any structural change that cuts cost (a locality window on allowed positions) is a model change, to be declared and measured against the equivariant machine, never presented as an approximation of it.
2026-10-01 (SPLIT: results; all hold. A new gaming route found)
Run took about 95 minutes (12 games, 256 coalitions each). measure/split_results.json.
- K1 efficiency HOLDS; K2 HOLDS: in all 12 games ground plus lines reproduces the drawing's own run bit for bit.
- L1 HOLDS (12/12): by pixels the paper out-earns the lines in every case (paper share 0.62 to 0.66; lines 0.000 to 0.13; on seed 9100 at k = 9 the lines earn 0.000 to 0.002).
- L2 HOLDS (6/6): by edges at k = 14 the lines out-earn the paper (lines 0.50 to 0.65, paper 0.31 to 0.44).
- L3 HOLDS (6/6): by edges the lines' share rises from k = 9 (0.34 to 0.44) to k = 14.
- Panel
measure/split/split_panel.png(k = 14; columns drawing, full, paper only, lines only, neither): paper alone gives a blank paper-toned mosaic; lines alone give the drawn shape on grey, built from the artists' marks.
Reported, not predicted: splitting a player changes the other players' pay (measure/split_panel.py -> measure/split_splitting.json). Same games, same outputs where both exist: the six artists' summed Shapley share drops when the input is two players instead of one, by 0.06 to 0.07 (pixel), 0.008 to 0.026 (edges), 0.06 to 0.08 (blur), 0.08 to 0.12 (colour). Shapley is not invariant to how a party is cut into players (a known property: it is not "splitting-proof"). Consequence for the receipts: the viewer could raise their share against the artists just by declaring their input as more parts. Rule added to BRIEF 5b: the input's partition is fixed by the protocol, never chosen by the payee, and the receipt reports artist credit under the one-player input as well.
Cross-run check (page, browser): the one-player game read off the split game (input present = both parts, absent = neither) reproduces M4's separately run, frozen Shapley values with difference 0 in all 6 cases x 4 value functions. Two runs a day apart, same engine, bit-identical.
Decision: adopt the split for the page and receipts as a description (paper and lines shown separately), with artists' pay computed against the input as one player, so the split cannot move money. Recorded in BRIEF 15.
2026-10-01 (page: a drawing as a player, and a sketch pad)
page/build_drawings.pypackages each finished SPLIT game at k = 14 (where M4 showed the drawn shape first appears) intopage/data/draw_<seed>_<drawing>.json: all 256 outputs, the run's reports with coalition values, source hashes. Consistency check on build: Shapley recomputes from the saved outputs (same code).page/draw.js, section 3 of the page: toggle six artists, Paper and Lines; the page recomputes every Shapley value from the 256 coalition values with its own subset formula. On seed 9100, circle: largest difference 0, efficiency 2.2e-16 (browser-verified).- Sketch pad with
/api/draw(page/server.py): one unpaid picture from the viewer's 32 px sketch, CPU float32, about 5 s, so it never shares the GPU with a measurement. Check: the circle drawing through the endpoint (as uint8 pixels, on CPU) against the SPLIT run's full coalition (MPS): max 0.0016, mean 0.00014 levels of 255. - Bug found in the browser test: fast strokes left gaps (only pointer events were painted); strokes are now joined pixel by pixel. Browser-verified with a drawn X: the engine's picture shows the X built from the artists' marks.
2026-10-01 (POOL: written and frozen; runs after SPLIT)
measure/POOL_PROTOCOL.md, measure/pool_run.py, measure/pool_analyze.py, frozen (measure/pool_freeze.json). Does the use vs Shapley gap grow with the commons pool? Nested pools N = 86, 43, 21, 10, fresh seeds 9200 to 9203. Disclosed in the protocol: the prior numbers it is designed around (T0FIX N = 86: TV median 0.36; demo receipts N = 10: pixel 0.14 to 0.27, edges 0.09 to 0.21, recomputed from the receipts today). A first draft of a fourth prediction (P4, a mechanism ratio) was removed before the freeze: it was not stated sharply enough to fail.
2026-10-01 (SPLIT: the input as ground and lines; built, tested, frozen, running)
- New module
instrument/parts_game.py: the viewer's input as several players, each an image component; present parts are summed and started at step k (coupled, as M4).ground_and_linessplits a drawing into a blank sheet in the corpus paper colour and the drawing minus that blank. - Tests
instrument/tests/test_parts_game.py4/4. First run failed Q2: lines stored in float32 did not add back to the drawing exactly (off about 1e-6). Fix: both components kept in float64, where the sum is exact; both-parts coalitions now equal M4's input-present coalitions bit for bit. Q4 corrected in the docstring: a part whose component is all zeros is not a null player (alone it starts from a mid-grey sheet). - Protocol
measure/SPLIT_PROTOCOL.md(predictions L1 to L3, checks K1, K2), runnermeasure/split_run.py, analyzermeasure/split_analyze.py. Runner bug caught before the freeze: the shared cache would have carried lines-only runs from one drawing to the next; it now keeps only ground-only runs across drawings, with an assertion. - Smoke run on seed 1 (identity and timing only, disclosed in the protocol). Frozen, run started in the background.
2026-10-01 (M4: results; post hoc, the drawing is paid for its paper)
Frozen 00:17 UTC (measure/m4_freeze.json), run to about 02:10 UTC. measure/m4_results.json.
- K1 efficiency HOLDS (2.2e-16).
- D1 HOLDS (6/6): at k = 9 the drawing out-earns every artist.
- D2 FAILS (3/6): under edges the drawing's share does not rise with k on seed 9100 (0.947, 0.939, 0.943 for the circle: flat near 0.94); it does on seed 9101 (0.884, 0.902, 0.933).
- D3 HOLDS (6/6): at k = 14 the drawing takes over half.
- D4 FAILS (0/6), as the smoke test hinted (disclosed before the freeze): even at k = 4 the drawing takes 85 to 95% under edges (55 to 63% under pixel).
- Reported: with a drawing in the game, under edges five of the six artists' Shapley values are negative (paid 0) and Kollwitz keeps 6 to 11%; in the artists-only game the six shares are 12 to 25% each. Under pixel the drawing takes 55 to 68%.
- Images (
measure/m4/m4_panel.png): at k = 4 and 9 the circle, house and hatch outputs look nearly the same (paper- toned mosaics); at k = 14 the drawn shape appears, built from the artists' marks. Without the drawing the output is darker, coloured by the commons paintings.
Post hoc, exploratory (measure/m4_blank_posthoc.py): a blank sheet in the same paper colour as the input, compared with each drawing (full coalition). Lines' share of the drawing's effect (distance from blank to drawing over distance from none to drawing): pixel 0.8 to 5.5% (so 94 to 99% of what a drawing does is its paper tone), edges 6 to 12% at k = 4 rising to 18 to 45% at k = 14 (the house most). The drawing is paid mostly for its paper colour, not its marks, the same finding M2 made for the artists, now for the viewer.
Design response (to be registered before testing, not adopted): split the input into two parties, its ground (a blank sheet in its paper tone) and its lines (the drawing on that ground), so a viewer who chooses the paper colour is not paid as if they had drawn the picture. Also: k = 14 is the strength at which the drawing's shape shows; the page's input feature should use a high k and say why.
2026-10-01 (receipt tamper tests: 6/6 after the fix)
- E1 untouched receipt: V1 to V5 pass, full replay bit-identical with v(S) recomputed exactly. E2 edited share, old seal: V1 catches. E3 edited share, re-sealed: V4 catches. E4 forged v, consistent, re-sealed: V1 to V4 pass (as designed) and the full replay now catches it. E5 swapped source hash: V2 catches.
- Limit kept in view: spot replay is probabilistic (the forged coalition 5 was not in the 8-coalition spot sample). The page's verify button runs a spot check of 4 and now says so, with the command for the complete check.
- M4 written:
instrument/input_game.py(the viewer's drawing as a seventh player, coupled start at step k; tests 5/5 including exact reuse of the input-absent half), three test drawings (corpus/inputs/, corpus paper and ink colours), protocolmeasure/M4_PROTOCOL.mdwith runner and analyzer. Smoke test next, then freeze.
2026-09-30 (receipt tamper tests: a verifier bug found and fixed)
receipt/tests/test_receipt.py on seed9000_edges: first run 5/6. E1 (untouched, full replay bit-identical), E2 (edited share, old seal: V1 catches), E3 (edited share, re-sealed: V4 catches), E5 (swapped source hash: V2 catches) passed. E4 FAILED: a forged v(S) with every payout recomputed consistently and re-sealed passed V1 to V4 as designed, but also passed the full replay. Cause: on the same backend V5 compared only the regenerated outputs' hashes with the receipt's, and the forger had not touched the output hashes; the v discrepancy was computed but not used in that branch. Fix: same-backend V5 now also requires every v(S) recomputed from the regenerated outputs to equal the receipt's exactly. A receipt could otherwise claim values different from the pictures it certifies. Re-running.
2026-09-30 (M6b receipts and verifier; M6 page)
- Receipts
receipt/make.py, formattake-it-out-receipt/1: one game yields one sealed receipt per value function (generator code hashes and explicit schedule; corpus manifest hash and every owner's source-file and views hashes; exclusions; baseline; request; v(S) for all 64 coalitions; Shapley, leave-one-out, use, shares; every output's hash; a SHA-256 seal over the canonical JSON). Demo receipts: commons 10, S1, marks64, seeds 9000 to 9003 (receipt/make_demo.sh), 16 receipts. - Verifier
receipt/verify.py, written independently of the instrument (Shapley recomputed by averaging over all 720 orderings from the receipt's own v): V1 seal, V2 manifest and all 182 owners' files and views, V3 code hashes, V4 credit, V5 optional replay (same backend: bit-identical outputs; other backend: |dv| within 1e-6 + 1e-3|v|). seed 9000 edges, V1 to V4: ALL PASSED (credit to 7.8e-16). Tamper tests running. - Page
page/(index.html, app.js, build_data.py, server.py; launch entrytake-it-out-page, 127.0.0.1:7472): the picture with artist toggles over all 64 exact coalitions, a difference map with stated gain, change statistics; use / leave-one-out / Shapley per artist under any value function; the Shapley arithmetic (32 weighted marginal contributions); the checks from the frozen analyses; the receipt with download and a live verify (spot replay).build_data.pyrefuses to package outputs whose hashes differ from the receipts'. - Checked in the browser: no console errors; fits 375 px. The page's change statistics equal Python's recomputation from the saved outputs (Ingres + Kollwitz removed, seed 9000: 5.12 levels, 18.2%, both). The page's own sum of the 32 weighted contributions reproduces the receipt's Shapley value exactly (difference 0) for all six artists under all four value functions.
- Two faults found and fixed on the page: the header said "182 sources" though only 96 sheets and 10 paintings are in play (now stated from the receipt); a limits line said use and Shapley "disagree on about a third of the money", true for the 86-painting pool but not here (seed 9000, edges: 9.4%); it now quotes the current picture's number. Also: a no-cache header on the local server and a versioned script reference (a stale cached app.js hid the fixes).
- Observation, not registered: with the commons at 10, use and Shapley disagree much less (9.4% on seed 9000, edges) than with 86 (about a third). When the artists supply most of the picture, what was copied comes closer to what mattered. Worth a registered test across seeds and pool sizes.
2026-09-30 (commons-size test: result)
Median visibility over seeds 8000 to 8003 (mean absolute change, levels of 255), schedule S1:
| commons N | Cézanne | Dürer | Ingres | Kollwitz | Rembrandt | Van Gogh | visible (>= 5) | artists' use |
|---|---|---|---|---|---|---|---|---|
| 86 | 3.59 | 2.82 | 4.72 | 2.69 | 2.20 | 2.38 | 0 | 0.44 to 0.54 |
| 43 | 4.22 | 3.23 | 5.53 | 3.96 | 2.59 | 3.00 | 1 | 0.61 to 0.71 |
| 21 | 4.88 | 3.30 | 6.33 | 5.54 | 2.71 | 3.50 | 2 | 0.75 to 0.84 |
| 10 | 4.84 | 3.23 | 6.50 | 6.75 | 2.78 | 4.17 | 2 | 0.86 to 0.92 |
- No N passes (at least 4 of 6 visible). Per the rule: N = 10 (the smallest tested), and the page leans on the difference map.
measure/commons_size.json,measure/commons_size.png. - Interpretation: shrinking the pool raises the artists' share of the picture from about half to about nine tenths, but single-artist visibility levels off at 3 to 7 levels. The limit is substitution among the six hands: when one leaves, the others fill in (the negative Shapley interactions). A single artist's removal is real and exact but small; the page shows it through the difference map, with its gain stated.
- Next: receipts for the demo (commons 10, S1, marks64) on seeds 9000 to 9003.
2026-09-30 (commons-size visibility test, rule fixed BEFORE the run)
Question: how large a commons (unpaid pool) can the demo keep while removing one artist visibly changes the picture?
- Corpus: demo corpus (marks64, L = 32, six artists) with the commons subsampled to N in {86, 43, 21, 10} paintings (declared rule: numpy default_rng(0).permutation of the 86 sorted commons ids, first N; smaller pools are subsets of larger ones). Schedule S1 (
instrument/config.py). Seeds 8000 to 8003 (not used before). - Per N and seed: the full output and the output with each artist removed (7 generations).
- Visibility of an artist = mean absolute change in 0 to 255 levels when that artist is removed.
- Rule: an artist is visible at N if its median over seeds is at least 5 levels. Choose the largest N at which at least 4 of the 6 artists are visible. If none, the smallest N tested, and the page leans on the difference map.
- Reported without verdict: the artists' share of use; each artist's visibility per seed; images.
2026-09-30 (K2 float64 re-check: HOLDS; S1 adopted)
measure/k2_float64.py(registered before running): game B, seed 6002, S1, CPU float64, 33 coalitions, 28.5 min. Symmetric coalition outputs differ by 6.3e-14 (float32: 2.0e-5 to 3.2e-5). phi(du-01) - phi(duplicate): pixel 3.4e-18, edges 9.5e-18, blur 4.2e-19, colour 0; relative 0 to 2.6e-14, against the registered 1e-9. HOLDS.- Per the registered rule: K2's float32 failure is float32 rounding; S1 is adopted as the instrument's schedule. Recorded in
instrument/config.py(SCHEDULE = S1, K2 on the float64 path, PROFILE = marks64), not by editing frozen files, so M3 and T0FIX stay re-runnable against their freezes. - Lesson for protocols: symmetry checks with relative tolerances fail near zero; state them on the float64 path, or relative to the largest player's value.
2026-09-30 (T0FIX: results; K2 failed; float64 re-check registered)
measure/t0fix_results.json (frozen analyzer). Run 19:19 to 22:07 UTC.
- K1 efficiency HOLDS (2.8e-17). K2 symmetry FAILS: max relative difference 1.43e-4 against 1e-4 (seed 6002, edges). Under the pre-registered rule S1 is NOT adopted while K2 fails.
- F1 HOLDS: constant control 0 to 0.36% of positive Shapley mass under every value function (M3: 2.6 to 6.7%).
- F2 HOLDS: scrambled 0 to 0.83%. F3 HOLDS: a copy doubles pay, 1.890 to 2.043 (median 1.960).
- F4 HOLDS: TV(use, Shapley) median 0.357. F5 HOLDS: Ingres top in 3 of 4. F6 HOLDS: artist shares move 0.099 to 0.187 (median 0.119) from S0 to S1: Ingres -0.06 to -0.08, Cézanne -0.03 to -0.06, Van Gogh +0.04 to +0.12, Rembrandt and Kollwitz +0.01 to +0.05. Removing the head-count vote moves credit away from the largest groups.
- Visibility of removing one artist under S1: 1.9 to 5.4 levels of 255 (M3: 1.9 to 9.3).
K2 diagnosis (from saved outputs, no rerun): in every seed under both S0 and S1, out(S + du-01) and out(S + duplicate) differ by 2.0e-5 to 3.2e-5: float32 rounding, since identical data sit at different positions in the engine's sums. It is the same size under S0 and S1. K2 fails only where du-01's Shapley value is near zero (seed 6002 edges, -3.6e-4), which inflates a relative difference.
Registered now, after the results (a check of the check, not a prediction): recompute, on the CPU float64 reference path, the 32 coalitions of game B seed 6002 under S1 that K2 depends on (du-01 or the duplicate with every subset of the other four players) plus the full coalition, and recompute phi(du-01) - phi(duplicate) for all four value functions. If the relative difference is below 1e-9 for every value function, K2's float32 failure is attributed to rounding, S1 is adopted, and future protocols state K2 on the float64 path or with an absolute tolerance. If not, there is a bug, and S1 is not adopted until it is found.
2026-09-30 (chaos-floor diagnostic: result; T0FIX frozen and started)
- Not chaos. Perturbing the initial noise by 1e-6 moves the output by 1.5e-12 to 5.9e-12 (pixel MSE): trajectories are smooth. The suspected mechanism was wrong.
- S1 removes the constant's influence almost entirely: leave-one-out effect 4.1e-4 to 6.6e-4 under S0, 2.3e-12 to 1.5e-7 under S1 (at the floor in one seed), 2 to 5 orders below a real sheet's (du-01, 7.9e-6 to 1.1e-4 under S1).
- The scrambled control keeps a real effect under S1 (1.5e-5 to 1.8e-4): its in-range pixels still get posterior weight.
- Both diagnostics disclosed in
measure/T0FIX_PROTOCOL.mdbefore the freeze; no prediction changed. Frozen (measure/t0fix_freeze.json), run started: games A, B, C under S1 on seeds 6000 to 6003, about 3.7 hours.
2026-09-30 (T0FIX registered but NOT frozen; a second diagnostic first)
measure/T0FIX_PROTOCOL.md,measure/t0fix_run.py,measure/t0fix_analyze.pywritten: schedule S1 (drop the t = 1 step; start at t = 0.95, abar 0.0061), games A, B, C on the same seeds and noise as M3 (paired), checks K1 K2, predictions F1 to F6, adoption rule (K1, K2, F1, F2, F3).- Smoke test (seed 1, reduced games, scratchpad) exercised the runner and the analyzer (the paired comparison needed the smoke's own files as S0; with real M3 files the shapes match). It showed, in the reduced game B under S1, the constant control still earning 3 to 12% (pixel 0.090, edges 0.029, blur 0.116, colour 0.074), down from 20 to 37% under S0 in the same reduced game. Reduced games inflate shares (M3's full game cut them about six-fold), but this suggests dropping t = 1 is not sufficient.
- Suspected mechanism: chaotic sensitivity. Late steps have very sharp posteriors, so a source with even a tiny weight at some step can flip a patch choice and the flip cascades. If so, every source ever touched earns removal credit, and no schedule change drives the constant to zero.
- Before spending 3.7 hours on T0FIX, an exploratory diagnostic (
measure/chaos_floor.py): under S0 and S1, the constant's, scrambled's and du-01's absolute removal effects on the full game B corpus, beside a chaos floor (the output change from perturbing the initial noise by 1e-6). T0FIX is frozen and run only if the diagnostic says S1 is the right thing to test; otherwise it is revised first and the revision recorded.
2026-09-30 (t = 1 diagnostic, exploratory: no verdicts)
measure/t0_diagnostic.py, seeds 6000 to 6003 (already used by M3), game B corpus without the duplicate. For each source, three runs: present at every step (full), absent at every step (none), present at step 0 only. Share of the removal effect explained by step 0 = 1 - d(full, step0only) / d(full, none), pixel MSE.
- CONTROL-constant: 99.95 to 100.00% of its effect enters at t = 1. Its posterior mass per step: 5.4e-3 at step 0 (exactly its share of training images, 0.54%: a uniform vote), 7.1e-6 at step 1, 4.6e-12 at step 2, 0 from step 5.
- du-01 (a real Dürer sheet): 50 to 60% of its removal effect also enters at t = 1.
- CONTROL-scrambled: 8 to 65% (varies by seed).
Interpretation. At t = 1 (abar about 3.7e-33) the posterior ignores the noisy picture: the first estimate is the plain average of every patch, and every source votes by head count. The DDIM trajectory then amplifies that shift. So about half of what removal credit pays a real sheet is its head-count vote at t = 1, not its relevance. The fix is not "exclude junk sources" but "remove the blind vote": start sampling below t = 1, where the first step is already relevance-weighted (the constant's weight is 7e-6 at t = 0.95). Registered next, before testing.
2026-09-30 (M3: results under the frozen protocol)
Run 14:47 to about 18:25 UTC, 12 games (A, B, C x seeds 6000 to 6003), all freeze hashes verified at start. measure/m3_results.json (analysis by the frozen measure/m3_analyze.py).
Checks. K1 efficiency: max error 5.6e-17, HOLDS. K2 symmetry (du-01 == its duplicate): max relative difference 9.3e-5 against 1e-4, HOLDS (close to the float32 limit).
| ID | Result | Numbers |
|---|---|---|
| T1 | HOLDS | TV(use, Shapley), pixel: 0.400, 0.346, 0.488, 0.297; median 0.373 (patch ledger at sheet level: 0.254) |
| T1e | HOLDS | edges: 0.363, 0.308, 0.346, 0.323; median 0.335 |
| T2a | FAILS | most substitutable pair: ingres+vangogh, cezanne+ingres, rembrandt+vangogh, cezanne+ingres (2 of 4) |
| T2b | FAILS | LOO below Shapley for both of that pair: 2 of 4 seeds |
| T4 | FAILS | paper fraction of artists' use: 0.297, 0.371, 0.168, 0.434; median 0.334, just below 0.35 |
| T5b | HOLDS | pair / alone: 2.021, 2.003, 2.008, 1.974 (a copy doubles pay) |
| T5c | HOLDS | scrambled: 0% under every value function, except 1.5% under edges in one seed |
| T5d | FAILS (expected, disclosed before the freeze) | constant: pixel 5.2 to 6.4%, edges 2.6 to 4.4%, blur 5.4 to 6.7%, colour 5.1 to 6.6% |
| T6a | HOLDS | top artist: ingres, ingres, vangogh, ingres |
| T6b | HOLDS | rankings differ; kollwitz last in 3 of 4 |
Reported without verdict: at artist level the four value functions agree closely (median TV between them 0.006 to 0.070; the patch ledger's sheet-level disagreement was 0.17 to 0.35).
Post hoc, not predicted (measure/m3_visibility_posthoc.json): removing one artist is nearly invisible. Mean absolute change when one artist is removed, in 0 to 255 levels: Ingres 7.5 to 9.3 (33 to 50% of values change by more than 8 levels), Cézanne 5.6 to 7.2, Dürer 4.4 to 5.1, Kollwitz, Rembrandt, Van Gogh 1.9 to 3.3 (4 to 10%). Removing all six: 27.9 to 38.6 (88 to 98%). The effects are real and measured exactly, but a viewer needs the difference map to see a single artist's; the raw picture barely moves. measure/m3/A_panel.png.
Implications (interpretation).
- The instrument works as a measurement: exact, efficient, symmetric, and it separates use from consequence by a third of the money.
- The constant control shows removal-based credit pays 3 to 7% for a source with no usable content, through the t = 1 average. That must be fixed before any payout is shown (candidate designs: start sampling below t = 1; exclude out-of-range sources; a null-player correction). Registered separately, before testing.
- For the page (O5): show the difference map, not side-by-side pictures; and the commons (344 of 728 images) sets most of the picture, which is why single artists move it so little. Both are design questions, not results.
2026-09-30 (M3: instrument built and tested, protocol frozen, run started)
- Instrument
instrument/removal.py: coalition runs through the engine's member mask, exact Shapley, leave-one-out, use, Shapley interaction index, four value functions (pixel, edges, blur, colour). The edge function is exactly the one registered for O12 (Rec. 709 luminance); the patch-ledger version (Rec. 601 plus epsilon) is deliberately not used, so edge payouts match the criterion that gated the corpus. - Instrument tests
instrument/tests/test_removal.py: 16/16. Exact Shapley equals the average over all 120 orderings (4.4e-16); efficiency, symmetry, null player, additivity; interaction index equals its brute-force definition, zero for additive games, -1 for perfect substitutes, +1 for complements; batched coalitions equal solo runs and physically reduced corpora, bit for bit on CPU float64 and MPS float32; edge function identical to O12's. - Engine change: owners absent from every row of a batch are skipped (their weights are exactly zero). Engine 52/52 and instrument 16/16 still pass. A coalition now costs what it contains: 10.9 s for the commons alone, 22.1 s for all 728 images.
- Protocol
measure/M3_PROTOCOL.md: games A (six artists), B (controls with the duplicate), C (without), seeds 6000 to 6003, checks K1 and K2, predictions T1, T1e, T2a, T2b, T4, T5b, T5c, T5d, T6a, T6b, each with a threshold and confidence. Runnermeasure/m3_run.pyand analyzermeasure/m3_analyze.pywritten before any run. - Smoke test before freezing (seed 1, reduced games, scratchpad only) exercised every code path. It showed the constant control earning 20 to 37% of the positive Shapley mass in the reduced game. Disclosed in the protocol before the freeze with the likely mechanism (the t = 1 step averages every patch, including out-of-range ones, and the shift propagates); T5d kept as written, updated expectation recorded (likely to fail in the full game).
- Frozen 2026-09-30T14:46:50Z (
measure/m3_freeze.json: protocol, runner, analyzer, engine, instrument, loader, manifest, verification, duplicates). Run started in the background; about 50 minutes per seed, about 3.3 hours.
2026-09-30 (demo profile built into the corpus; old measurement pinned)
corpus/build_corpus.pynow builds the demo profilemarks64(64 px source crops, mark-centred, 4 views per sheet) beside the half profile, for sheets and controls, at L = 32 and 64, with per-array hashes in the manifest.corpus/load.pyloadsmarks64by default.- Corpus tests
corpus/tests/test_corpus.py: 10/10 pass. Licences (96 sheets PD/CC0; 100 commons files verified or recorded duplicate), exclusions exactly the declared 14, 602 arrays match their manifest hashes, controls exact, demo corpus 96 sheets + 86 commons with nothing excluded present, marks64 mark fraction 0.514 vs half 0.290, and a full rebuild reproduces the manifest byte for byte. Independence check: the build's marks64 views equal the separately written O12 test builder's (64, marks) views bit for bit on all 96 sheets. - Hazard found and fixed: changing the loader's defaults would have made
measure/paper_credit.pysilently rerun on today's corpus. The loader gainedpaid_artist_exclusion; the paper script now pinsprofile="half", paid_artist_exclusion=Falseand asserts the recorded corpus size (195 owners, 99 commons). Seed 5000 rerun: U_paper, U_mark, R_paper, R_mark and F all bit-identical to the recorded run.
2026-09-30 (O12 confirmation: result)
- PASS on the final corpus (commons 86): Q_edges 1.598, 1.142, 2.391, 2.171 (4 of 4 >= 1), higher than on the old commons (lowest seed 1.065 then). Consistent with removing the artists' own paintings from the pool: more of the outputs' structure now has to come from their drawings. Pixel Q 0.272 to 0.460 (differs from the first test because the corpus changed; the "reproduces" flag in the file is false for that reason, not a determinism failure).
measure/crop_scale_edges_confirm.json.
2026-09-30 (paid-artist works removed from the commons; O12 confirmation registered)
- Decision (Russell, following the recommendation): the commons is disjoint from the paid artists.
corpus/load.pynow excludes any commons painting whose verified Met record names one of the six artists: 13 works (Cézanne 6, Van Gogh 5, Ingres 2), plus the DT872-1 duplicate download: 14 exclusions, each with its reason, returned for every receipt. Demo corpus now: 96 sheets + 86 commons paintings = 182 sources, 728 training images at L = 32. This also removes the commons copy of Cézanne's Mont Sainte-Victoire and the Viaduct (Met 435877), settling the possible cross-group duplicate with msv-b. - The paper measurement and both O12 tests ran on the previous commons (99). They are kept as run; they are not silently relabelled.
- Confirmation registered before it runs: the O12 edge test for the chosen configuration (64 px mark-centred) re-run on the final corpus, same seeds, same rule (pass: Q_edges >= 1 in at least 3 of 4 seeds). Written to
measure/crop_scale_edges_confirm.json; the original result file is untouched. If it fails, the configuration choice is reopened.
2026-09-30 (Met verification complete; a payout problem found)
- Crawl stopped once the only unmatched file was identified as
DT872-1.jpeg, a second local download ofDT872.jpeg.corpus/verify_met.py --offlinenow rebuilds the result from the 6,617 cached records with no network. A file counts as a duplicate download only if the duplicate scan found it near-identical AND its name is the original's plus -N. - Result: 99 of 100 commons files matched by exact image filename, all European Paintings, all public domain; 1 duplicate download (DT872-1 of Met object 435980, Corot, Portrait of a Child, ca. 1835, 29.100.564); 0 unmatched. The commons licence is now verified, file by file (
corpus/met_verification.json). - Payout problem found: 13 commons paintings are by three of the six paid artists (Cézanne 6, Van Gogh 5, Ingres 2; e.g. Van Gogh, Irises, 436528; Cézanne, Dish of Apples, 437989; Ingres, Madame Jacques-Louis Leblanc, 436703). The commons is the unpaid baseline, so (a) credit for these paintings goes to the pool, not the artist, understating the artist's Shapley share; (b) "take the artist out" would remove only their drawings. Decision pending (Russell): remove these 13 from the commons, or move them to their artists. Nothing changed yet.
- Possible cross-group duplicate: commons met-dp-20099-001 (Cézanne, Mont Sainte-Victoire and the Viaduct of the Arc River Valley, 435877) has the same title as msv-b in the Mont Sainte-Victoire series; not flagged by the scan (likely a different photograph or crop). The series is not in the demo corpus; to resolve before it is ever added.
2026-09-30 (O12 second test: result)
Result under the rule registered before it ran: PASS for 64 px mark-centred crops, FAIL for 64 px uniform.
| configuration | Q edges (seeds 5000 to 5003) | Q pixel (reproduces test 1 exactly) | result |
|---|---|---|---|
| 64 marks | 1.462, 1.065, 1.920, 1.891 | 0.253, 0.294, 0.336, 0.418 | pass (4 of 4) |
| 64 uniform | 0.744, 0.882, 0.878, 1.089 | 0.102, 0.170, 0.130, 0.206 | fail (1 of 4) |
- Determinism: the pixel Q of every seed reproduces the first test exactly.
- What the pass does and does not mean. Removing marks changes the outputs' edge structure at least as much as removing paper does, so artists are now credited for structure, not only paper tone. The margin is narrow (lowest seed 1.07). The outputs are still colour mosaics, not drawings; a mark is visible as a line only here and there (
measure/crop_scale_edges.png, row 3). The pass depends on a choice we make: crops centred where the artist drew (probability proportional to the mark mask). That choice is declared in the corpus rules and on every receipt. - Decisions: O12 is rewritten to the edge criterion; the pixel criterion's failure stays recorded. The demo corpus uses 64 px source crops, mark-centred, 4 views per sheet, at L = 32 (to be written into
corpus/build_corpus.pyas a declared option, not a separate code path). Resolution 64 px remains the lever for outputs that look like drawings; it needs M5.
2026-09-30 (O12 crop-scale test: result, and a second test registered before it runs)
Result under the pre-fixed rule: every configuration FAILS O12. Q = R_mark / R_paper per seed:
| crop, placement | Q (seeds 5000 to 5003) | mark share of artists' use |
|---|---|---|
| 256 uniform | 0.086, 0.135, 0.118, 0.176 | 0.21 to 0.37 |
| 256 marks | 0.129, 0.174, 0.167, 0.229 | 0.27 to 0.42 |
| 128 uniform | 0.097, 0.139, 0.115, 0.186 | 0.22 to 0.40 |
| 128 marks | 0.171, 0.223, 0.211, 0.328 | 0.35 to 0.51 |
| 64 uniform | 0.102, 0.170, 0.130, 0.206 | 0.25 to 0.44 |
| 64 marks | 0.253, 0.294, 0.336, 0.418 | 0.45 to 0.59 |
As the rule said: the crop lever fails O12 at 32 px under this criterion. measure/crop_scale.json.
Why, and what is wrong with the criterion (interpretation, written after seeing the result): the 64 px crops resolve strokes several pixels wide (measure/crop_scale_views.png, rows 5 and 6), and the marks' share of use rises monotonically with tighter, mark-centred crops (0.21 to 0.59). Q rises with it but stays below 1 because the criterion compares removing ALL paper with removing ALL marks under pixel MSE, which weights area: even a resolved drawing is mostly paper, and removing paper recolours the ground under most of the picture. So "R_mark >= R_paper in pixel MSE" measures whether marks dominate the area, not whether they are resolved or carry the hand. This is a measurement-design error in O12 as written (the third such in this program's pieces, after margin's stop threshold and pictorial form's selection rule), not evidence that marks cannot matter.
Second test, registered now, before it runs (designed after seeing the first; labelled as such everywhere):
- Configurations: crop 64 marks and crop 64 uniform (the two best by Q). Same corpus build, seeds, engine, conditions.
- Value function: edges, as declared in BRIEF 6.5: squared difference of Sobel gradient magnitude of luminance between outputs, averaged over pixels. Q_edges = R_mark_edges / R_paper_edges.
- Also reported, no verdict: pixel-MSE Q again (should reproduce the first test exactly, a determinism check).
- Pass: Q_edges >= 1 in at least 3 of 4 seeds. If it passes, O12 is rewritten to use the edge criterion and the change is recorded in BRIEF; the pixel criterion's failure stays recorded. If it fails, the next lever is resolution (64 px, after M5 speed work).
- Outputs saved as images for inspection.
2026-09-30 (labbook, Met verification started)
- Labbook
labbook/labbook.html, generated bylabbook/build_labbook.pyfrom the result files (no typed-in numbers): overview, status, engine tests and measurements, benchmark chart, corpus rules and contact sheet, mark detection, every source's IDs and verification status, duplicates, the paper measurement, the crop-scale test, a re-trace table (command, output and script hashes), the source registry, and this log. Served locally with the launch entrytake-it-out-labbook(127.0.0.1:7471). Checked in the browser: no console errors; fits 375 px after letting long hashes wrap. - Met verification (
corpus/verify_met.py): the Met search API does not index image filenames (three test queries returned unrelated objects), so the script lists objects with images in European Paintings (then 21 and 16), fetches each record (cached incorpus/met_cache/, about 12 requests a second, read-only public metadata) and matches our files by exact image basename. Running; 15 of 100 matched after 500 records.
2026-09-30 (O12 crop-scale test, rule fixed BEFORE the run)
Question: at 32 px, can a tighter crop scale make artists' marks matter (O12)?
- Sheet views are rebuilt in memory; everything else as in the M2 paper measurement (commons views unchanged, 99 after dedupe; ELS default schedule; MPS float32; seeds 5000 to 5003; conditions full / paper dropped / marks dropped).
- Configurations: crop side c in {256, 128, 64} source pixels on the 1200-px book image (the M2 baseline is the full short-side square plus half-side crops), each with placement uniform (crop centre uniform over positions where the crop fits inside the sheet crop box) or mark-weighted (centre drawn from mark pixels, probability proportional to the mark mask, restricted to where the crop fits). 4 views per sheet in every configuration, so corpus size and cost are unchanged. Crop positions seeded by crc32(sheet id + configuration name).
- Measure per seed: Q = R_mark / R_paper (removal effect of all mark patches over all paper patches, pixel MSE); mark share of artists' use mass.
- O12 passes for a configuration if Q >= 1 in at least 3 of 4 seeds. Among passing configurations, prefer the largest crop (most context per view) and uniform over mark-weighted at equal crop (less selection by us). If none passes, O12 needs 64 px (M5) and this is recorded as a failure of the crop lever at 32 px.
2026-09-30 (M2: results)
- Corpus built (
corpus/build_corpus.py, 34 s): 96 sheets (six artists, every licence recorded from museum or Commons metadata), 100 Met commons images, 9 Mont Sainte-Victoire paintings, 3 planted controls; views at 32 and 64 px; manifest with file, crop and array hashes; contact sheetcorpus/contact_L64.png. - Failure found and fixed: the first mark rule was wrong. "Darker than the sheet's median" assumed paper is the majority; on dark lithographs and dark reproductions the median is ink, so 10 of 96 sheets read as having no marks (thresholds down to -134). Replaced by Otsu's two-class split with a guard; all 96 sheets now get a real split (mark fraction 0.036 to 0.897, median 0.20). Masks checked by eye on the extremes (
corpus/mask_check.png). - Commons licence is unverified. The 100
DP-/DT-files are Met image IDs with no object record stored locally; the manifest says so per file. Verifying needs Met API lookups (not done without asking). - Duplicate scan (
corpus/scan_duplicates.py): no identical files, no identical pixels, one near-duplicate:DT872.jpegandDT872-1.jpeg, the same painting re-encoded. Different file hashes, and (because views are seeded from the id) different views, so hash and pixel checks both miss it; normalised distance 0.00 against a 0.1th-percentile floor of 0.60 for all other pairs. Rule: dedupe on the source image, keep the first id;met-dt872-1excluded and every receipt will list the exclusion. This is the gaming case of BRIEF 5b, found naturally. - Engine extended with an exact class sub-ledger and class removal (patch classes: paper, mark, painting). Tests N8 to N10; 52/52 pass. Two problems met on the way:
- a real engine bug: when class removal left a chunk with no candidate at some pixel, the weights were exp(-inf - -inf) = NaN and NaN * 0 survived the merge. Fixed by normalising with 0 there (weights exactly 0). The original code could not reach this path.
- my N9 float32 tolerance (1e-6) was tighter than the suite's standard for float32 mass checks (1e-5); aligned and commented. The float64 reference passes at 6e-15.
- N10's first corpus left a border pixel with no candidate after removal; the guard fired correctly. The test corpus now guarantees a candidate of each class everywhere.
- Paper measurement, verdict under the pre-fixed rule: NOT OVER-CREDITED, no pooling policy. F = 0.33, 0.30, 0.30, 0.32 (4 of 4 seeds <= 1). Paper takes 63 to 80% of artists' use mass (draft T4, >= 30%, holds), but removing paper changes the output 5 to 12 times more than removing marks.
measure/paper_credit.json,measure/paper_credit_outputs.png. - The finding behind it (operating window): at 32 px the artists' lines do not exist. A pen or graphite stroke is under one pixel wide; outputs are paper-toned blotches mixed with painting colour; removing all marks leaves the output almost unchanged. At this resolution the instrument would pay Rembrandt and Dürer for the colour of their paper. New requirement added to the brief (O12): the demo resolution and crop scale must resolve marks, measured by the marks' share of artists' removal effect, before anything is shown.
2026-09-30 (M2: paper measurement, rule fixed BEFORE the run)
Question (BRIEF M2 decision a): does use-based credit over-pay blank paper?
- Corpus:
corpus/load.py, L = 32: six artists (96 sheets) + commons (99 after dedupe), 780 images, 195 owners. Patch classes: paper (sheet, mark fraction < 0.5), mark, painting. 71% of sheet pixels are paper. - Engine: ELS, default schedule (20 steps, patch 13 to 3), MPS float32.
- Outputs: 4 unconditional samples, noise seeds 5000 to 5003.
- Conditions per seed: full corpus; paper patches removed (class 0 dropped); mark patches removed (class 1 dropped).
- Measures per seed: U_p, U_m = paper and mark shares of use (class mass averaged over steps and pixels); R_p, R_m = removal effects, mean squared pixel change of the output when the class is dropped (declared value function, pixel MSE). Over-credit factor F = (U_p / U_m) / (R_p / R_m): how much more use credits paper relative to marks than removal does.
- Decision rule: F >= 2 in at least 3 of 4 seeds: use over-credits paper; adopt the policy that paper use mass is paid to a shared "paper" line, not to the sheet's artist (removal-based columns are unchanged, since they already measure consequence). F <= 1 in at least 3 of 4: no policy. Otherwise inconclusive: keep paper with its artist and show both numbers.
- Reported regardless: per-artist fraction of use mass that is paper; U_p as a share of all artist mass (draft prediction T4 said >= 0.30).
2026-09-30 (M1: engine port)
- Originals copied verbatim to
engine/ORIGINAL/(read-only) with SHA-256 inengine/ORIGINAL/PROVENANCE.md. Their own 16 self-tests run untouched: 16/16 pass on MPS. - Extended engine
engine/tio/machine.py. Changes, each tested: 1. Explicit device and dtype per Machine (CPU, CUDA, MPS);available_backends(). 2. Accumulators and traces kept in the Machine dtype. The original allocated them in float32 even at dtype=float64, so it had no real float64 path. Now CPU float64 is a true reference (N1: 6.4e-15 from brute force). 3. Schedule time and abar computed in Python float64 (original rounded both through float32). 4. Empty coalitions raise (N6).abar_from_rectifiedadded for Riley's parameterisation. - Tests
engine/tests/test_engine.py: the 16 original checks on every backend (tightened to 1e-12 on float64) plus N1 to N7. 41/41 pass (17 s). Measurements inengine/tests/last_run.json. - Two failures on the first run, both diagnosed, neither an engine bug:
- T5 on float64 (duplicate vs prior weight 2 differed by 7.4e-9). Cause: the test built log 2 as a float32 constant (off by 1.9e-9). Fixed by building priors in float64; now 5.2e-15. Rule: log-priors are created in float64.
- N5 (port vs original, mass differed by 2.0e-4). Cause: the original rounds the time grid and abar through float32. Given identical schedule arithmetic (runtime patch, file untouched) the port equals the original bit for bit (0 output and 0 mass values differ).
- Finding for receipts (O8): float32 schedule rounding alone moves final ledger mass by up to 2.0e-4 and the output by 2.7e-6. Receipts must pin the exact arithmetic (float64 schedule, recorded version), or replay will not match.
- Measured: exact removal is bit-for-bit on CPU float64 (N2). Same-noise reruns are bitwise identical on CPU float64 and on MPS float32 (N3). MPS float32 vs CPU float64 on a 16x16 case: 0.13% of values differ by > 1e-3, max 2.3e-3 (N4); replay tolerance for MPS must be set from measurements like this, per resolution.
- Riley's weights equal Kamb-Ganguli's after rescaling to 2.6e-15 (N7), so BRIEF 6.2's conversion is verified.
- Benchmark now in-project:
bench/bench_engine.py. MPS float32: 39 to 40 ms per training image per 32 px generation (first measurement 37; about 5% slower, not yet explained; could be run-to-run variation, to recheck with repeated runs). CPU float64 reference: 108 ms per image, about 2.8x MPS, so float64 replay is practical at small scale. - Not done in M1: CUDA path untested (no CUDA on this machine; covered by O9 Colab). Riley's current repository not yet received at the time; M1 stayed open for reconciliation with it (done 2026-10-01).
2026-09-30
- M0:
BRIEF.mdwritten. Sources inventoried and read as listed in its section 11. - Measured baseline (patch-ledger engine unchanged, cached views, M1 Max MPS, 32x32, 20 steps, ledger kept): 64 images 2.30 s, 256 images 8.98 s, 436 images 16.21 s per generation (about 37 ms per training image). Script: session scratchpad
bench.py(not kept in project; to be re-created asbench/bench_engine.pyin M1). - Next: M1, port the engine with provenance and run its 16 self-tests.