Skip to content

The second edition: the vessel compiled, and the repository as a checked instrument - #18

Merged
MaxFreedomPollard merged 9 commits into
mainfrom
second-edition
Sep 6, 2026
Merged

The second edition: the vessel compiled, and the repository as a checked instrument#18
MaxFreedomPollard merged 9 commits into
mainfrom
second-edition

Conversation

@MaxFreedomPollard

Copy link
Copy Markdown
Owner

What this adds

The vessel, compiled. Open Problem 4 asked for the compiler of theory Section 11 to be run on the Green's function a real geometry gives, instead of on the toy fabric. ampoule/compile.py runs it on the 64 × 64 matrix that ampoule/ measured, with the digital twin's instance restricted to the vessel's own lattice of eight rings of eight sites. The fabric turns out to be geometry: every coupling is the solid angle a 2 mm cell subtends at its neighbour times a 3 percent interaction probability, and CsI takes the receiver to its ceiling. Way B places the 120 intended bonds exactly by apertures, and the 60 couplings each site receives without an aperture sum to 7.9× the instance in weight units and bury it; the collar can subtract their mean and not their fluctuation, which is 3.1× the intended drive. The 64 site sampler is checked against an exact transfer matrix over the 256 ring states and needs 3.3 sweeps per independent sample, the 8 site cost unchanged. Then the timing closure: a weight in a rate coded machine is a photon current, a nearest neighbour bond carries 16.3 photons per second with CsI cells, reading a site's fan in to 4 bits takes 0.88 s, and the vessel as built draws 0.34 independent samples per second against the 38,462 the machine note priced on proposals alone. The currents are ceilings, so the rates are too. Two measured levers and two catalogue levers carry the figure back within reach.

The README gains the section and figure 18, Open Problem 4 is marked done with what it asks for next, theory Sections 3.1 and 11.5 carry the synapse term, and the machine note, the build note, the ENIAC ledger and the ampoule, simulator and transistor documents are amended where the numbers say so.

The repository as an instrument. reproduce.py runs every step in the CI's order and, with --check, fails unless every number, table and vector figure comes back byte for byte; build.yml runs the same gate, the compile step and the tests on every push. tests/ holds 48 tests: the documents' headline numbers read back from the files that compute them (the class of drift the 1.0.1 erratum corrected), every internal link resolved, the house style enforced, the instruments checked against things that are not themselves, the reproduce script and the CI kept in step, and the committed inputs matched against data-manifest.sha256. requirements.txt is pinned, and under the pin every output reproduces on macOS and Linux. A Dockerfile carries the OpenMC 0.16.0 environment the neutron README referred to; DATA.md names every input and its source; GLOSSARY.md indexes the terms the work coins; CHANGELOG.md records the releases; CITATION.cff carries the version, 1.1.0.

What it corrects

Regenerating the tree on a second machine found four outputs that did not come back the same: figures 2 to 14 had been drawn by an older matplotlib, the pair table carried a gzip timestamp, the adjoint check's digits depended on the BLAS, and two figures differed between operating systems (a cancellation in the Siegert integrand, an embedded raster in the ampoule figure). All are fixed; the raster PNGs remain platform specific and are the one output not compared. The two neutron tally files named the directory of the machine that ran OpenMC as their cross section provenance and now name the library. Hyphenated isotope designations in the transport documents are written as superscripts, as the rest of the work does.

Checks

python reproduce.py --check passes on macOS in 45 s; the same gate and the 48 tests pass on the committed tree in a Linux container under the pinned requirements.

… byte for byte, on macOS and Linux

Regenerating the tree on a second machine found four things that did
not come back the same. Figures 2 to 14 had been drawn by matplotlib
3.9.4 and every one of them differs under the current release; the
pair table photon/pairs.csv.gz carried the gzip timestamp of the run
that wrote it, so it differed by eight header bytes on every run with
identical content; the finite difference check of the adjoint compiler
used a step of 10^-6, where rounding rather than truncation sets the
residual, and read 9.1e-07 on one BLAS and 7.8e-07 on another; and two
figures differed between operating systems, the Siegert curve because
1 + erf(u) cancels catastrophically for large negative u and the two
libms round it differently, and the ampoule figure because its heat map
was an embedded raster whose PNG encoding is not portable.

requirements.txt now pins numpy, matplotlib and markdown, and every
figure is redrawn under the pin. The two compressed tables are written
with a zero mtime (levels.json.gz rewritten once with identical
content). The finite difference step is 10^-4, where the check is
truncation limited and reads 1e-08 everywhere; the theory supplement
and the transport README quote the new figure. The Siegert integrand
uses erfc(-u), and the ampoule's Green's function and its colour bar
are drawn as vector cells. Under the pin every results file, table and
SVG figure now reproduces byte for byte on macOS and on Linux; the
raster PNGs still differ by a few pixels between platforms and are the
one output not compared.

The neutron documents and the generated candidate table also write
their isotopes as superscripts (252Cf, 137Cs, 99Mo) as the rest of the
work does.
…, the exact law at 64 sites, and the timing closure

Open Problem 4 asked for the transport level Green's function of a real
geometry and for the compiler of theory Section 11 to be run on it.
/ampoule measured the 64 x 64 matrix; ampoule/compile.py now takes it as
the fabric and does what a compiler does with the digital twin's instance
restricted to the vessel's own lattice, eight rings of eight sites.

The fabric is geometry: every measured coupling is the solid angle a
2 mm cell subtends at its neighbour times a 3 percent chance of
interacting in 2 mm of plastic, the same probability for the ring, axial
and diagonal classes; CsI cells take the receiver to its ceiling by the
measured 31x. Way B places the 120 intended bonds exactly by apertures,
and the 60 diagonal and far couplings each site receives, which pass no
aperture, sum to 7.9x the instance in weight units and bury it: the
sampled law saturates. The compiler's last pass, subtracting the
predictable mean of the crosstalk from every bias through the collar,
leaves a fluctuation 3.1x the intended drive. A diffusive shell cannot
carry a nearest neighbour instance; the sight lines of the build note's
channel plates are the synapse and the next transport must include
them. The lattice's topology makes its exact Boltzmann law a transfer
matrix over 256 ring states, and the 64 site twin reproduces it to
counting noise at 3.3 sweeps per independent sample, the 8 site cost
unchanged.

Then the timing closure. A weight in a rate coded machine is a photon
current, I_kj = G_kj r_j, and the precision law prices its read: a
nearest neighbour bond carries 16.3 photons per second with CsI cells,
a site's fan in 291, a 4 bit loop takes 881 ms, and the vessel as built
draws 0.34 independent samples per second against the 38,462 the
machine note priced on its proposal budget alone. The proposal budget
and the synapse budget are different budgets, and the second binds by
five orders of magnitude. Two measured levers (CsI at both ends, 964x
in current) and two catalogue levers (cells packed face to face, 148x
in solid angle; a terabecquerel core, 1,000x) reach 51,143 per second
at 4 bits, 1.3x the priced figure, with no new physics.

The README gains a section and figure 18, Open Problem 4 is marked done
with what it asks for next, theory Sections 3.1 and 11.5 carry the
synapse term, and the machine note, the build note, the ENIAC ledger,
the ampoule and simulator READMEs and the transistor note are amended
where the numbers say so. The same documents write 252Cf as a
superscript and quote the adjoint check at its new step.
…entity gate in CI, the Dockerfile, the manifest, the glossary, the changelog

reproduce.py runs every step in the order build.yml does and, with
--check, fails unless every tracked file other than a PNG came back
the same; build.yml runs the compile step, the tests, and the same gate
on every push, so the claim that everything regenerates byte for byte
is now enforced rather than stated.

tests/ (48 tests, two seconds): the headline numbers the documents
quote are read back from the files that compute them, which is the
class of drift the 1.0.1 erratum corrected; every relative link and
image resolves and every figure shown is drawn by a script; the house
style holds (no dashes in prose, isotopes as superscripts, no edition
notes inside the documents, the licence header on every script); the
instruments are checked against things that are not themselves (the
beta spectra against ICRP 107, the transfer matrix against brute force
enumeration, the sampler against its exact law, the degree checker
against the theorem, the adjoint Jacobian against finite differences,
the committed fission matrix against the committed eigenvalue, the
measured synapse against the solid angle ceiling); the reproduce script
and the CI run the same steps; the requirements are pinned; the SVGs
carry no raster and no date; the compressed tables carry no timestamp;
and the committed inputs match data-manifest.sha256.

The Dockerfile is the OpenMC 0.16.0 environment the neutron README
referred to, on the x86-64 platform conda-forge builds it for. DATA.md
names every input and its source. GLOSSARY.md indexes the terms the
work coins to the places they are defined. CHANGELOG.md records the
three releases, and CITATION.cff carries the version, 1.1.0.
…ame on every platform

Regenerating the committed tree in a Linux container found one file
still moving: the finite difference check of the adjoint Jacobian read
9.6e-09 on macOS and 2.8e-09 on Linux. The residual at a step of 10^-4
is a few parts in 10^9, and its digits are set by which BLAS inverted
the 144 by 144 transport matrix. The check now reports the bound the
residual satisfies, below 10^-7, which is the claim the theory makes
(machine precision) and which every platform agrees on; the supplement,
the transport README and the changelog say so.
…con Mac

Verifying the recipe on this Mac: the conda solve and install succeed
under x86-64 emulation, openmc --version reports 0.16.0 inside the
image, and numpy imports once the emulated OpenBLAS is pinned to one
thread; without the pin the import spins. The header now says so, and
leaves the threads alone on a real x86-64 host, where OpenMC uses them.
…rom them

The currents of the timing closure take one photon out per interaction
as the most a site can send, which is a ceiling; the scatter share of
the cell material sits below one. The sample rates in the table and the
top rung of the ladder are therefore ceilings as well, and the section,
the README, the machine note and the build note now say so: the priced
figure is within reach of the catalogue levers rather than reached.
…d it

The two neutron tally files recorded the cross_sections.xml path of the
machine that ran OpenMC. The field now names the library itself, the
official ENDF/B-VIII.0 distribution that neutron/data.py fetches and
verifies, which is the provenance that matters; the manifest follows.
When the tree does not come back the same, the CI step and reproduce.py
now print the diff of the text outputs that changed, so a number that
moved on one platform can be read off the log instead of guessed at.
G_fab times G*/G_fab is G* up to rounding, which is exactly zero on one
architecture and a few parts in 10^16 on another; the CI gate on x86-64
caught the difference. The line now reports the bound the identity
satisfies, below 10^-15, which reads the same everywhere.
@MaxFreedomPollard
MaxFreedomPollard merged commit 7c1c183 into main Sep 6, 2026
3 checks passed
@MaxFreedomPollard
MaxFreedomPollard deleted the second-edition branch September 6, 2026 03:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant