Windowsill Lab · Field Explainer · The Machine As Instrument

The detector that
was never plugged in

This rung measured nothing, and that is the whole of it. The runner had synthetic frames on hand and refused to use them.

no cameradevice exposed
0real frames
nullreceipt returned
I01

An instrument that will not invent its input

If you cap a camera so that no light can reach it and take a stack of exposures anyway, what is left in the frames — and can a machine tell a broken pixel from a particle that passed straight through the sensor?

AI-painted illustration: a bare camera module on a dark windowsill with a machined brass cap seated over its lens, its ribbon cable trailing away and ending unplugged on the sill
Illustration (AI-painted) — the lens capped, the cable unplugged

A camera sensor is a grid of several million tiny charge wells. Cap the lens so no light reaches it, expose it anyway, and the frames are not empty. Some of what remains is electrical noise. Some of it is hot pixels — wells that leak, and therefore read bright in every single frame, always in the same place. And a small residue is something else entirely: a charged particle from a cosmic-ray shower passing through the silicon, dumping energy along its path and leaving a short bright streak in one frame and never again. Amateur detectors built on exactly this principle have been run for years on ordinary phones. The separation — always-on versus once-only, blob versus streak — is the whole calibration.

This rung tried to do that on the machine the lab runs on, and could not.

the receipt, in full CMOS calibration not run: no real dark-frame stack available
reports/2026-07-14-i01.json, the run's own headline

The machine exposed no camera device, and no real capped-sensor dark-frame stack was configured. So the runner returned a hardware-unavailable null and stopped.

That is the entire content of this milestone, and it is deliberate. The lab has synthetic dark frames — it uses them to test the classifier's logic in its own test suite — and it would have been trivial to point the pipeline at them and produce a report full of plausible-looking numbers. The runner refuses to. Synthetic frames never enter a report, and the receipt says hardware unavailable rather than reporting a measurement the machine did not make. An instrument that will fabricate an input when the real one is missing cannot be trusted on the runs where the input is real.

The panel below is therefore not this experiment. It is the classifier — the part that was built and does work — running on frames generated in your browser, clearly labelled as such. It shows you what the separation looks like. It is not a measurement, and the banner across it says so.

The classifier only · frames generated in your browser SYNTHETIC INPUT — NOT A MEASUREMENT
frame 0
σread = 3.00 ADU pevent = 0.22 / frame
SYNTHETIC INPUT — NOT A MEASUREMENT

left · the current synthetic frame — hot pixels ringed brass and held between frames, transient blobs moss, track-like streaks ember · right · what the classifier has counted so far, against the number of events actually injected (slate) · below · the most recent track-like candidate, magnified, with its fitted principal axes.

Raise the read-noise slider and something counterintuitive happens: the detector finds fewer events, not more. The six-sigma gate is measured relative to the frame's own noise, so a noisier sensor raises its own bar. The slate line keeps climbing at every setting — events are still being injected at the same rate — but past roughly σ = 5 the ember line falls away from it, and by σ = 8 it is flat. That is the one piece of real instrument physics this panel can teach, and it is why dark-frame calibration is done before anything else.

no camerathe hardware null MEASURED (AS A NULL)
≥ 6 σthreshold a transient must clear, once real frames exist
SHA-256provenance every accepted dark frame would carry
0physics numbers on this rung

The design the null was protecting is on disk regardless. Persistent bright pixels are estimated and removed by a temporal median before any transient component is classified. Accepted inputs are an .npy/.npz stack, a directory of 2-D .npy frames, or a live capture — and camera acquisition runs in a disposable child process, so a wedged camera backend cannot wedge the lab. Every accepted frame carries a per-file SHA-256 into the receipt. None of that ran here, which is why none of it appears as a number.

There are no measured physics numbers on this rung. The strip above says no camera / 0 frames / null receipt because that is what the run produced. A row of impressive-looking thresholds that were never exercised on real data would be the failure this page is about.

Nothing was measured here. The machine exposed no camera, so the runner returned an explicit hardware-unavailable null rather than substituting the synthetic frames it already had on hand — synthetic fixtures test the classifier only and never enter a report. Even a future pass would calibrate dark noise and event separation; it would not identify cosmic rays, which needs exposure metadata, controls, and a sustained study of rate and zenith-angle geometry. The panel above is that classifier running on frames generated in your browser, and it is labelled synthetic because it is.