docs: record the three noise-rejection controls and their invariants

README gains the three controls where each lives -- the trigger's `band`/`reject`, the
measurement's `noise`/`hf`, and the math channel's `de-noise` node -- each with its unit, what
"off" is, and what it costs, plus the two deliberate deviations from the design spec next to the
features they belong to: the band applies to `edge` and `window` only (a pulse's width is measured
from a crossing to its return, so a band there changes the measured width rather than rejecting
noise; a dropout is an absence with no level to compare), and the band is verified through
`BufferSearch` hit counts rather than `[condition-probe]` latch times, because probe-readings.md
states that a `t0` is not an assertion.

The invariant docs gain the rules a later change must not break: `EventCondition`'s two new fields
and the once-per-packet `configure(dt)` that must not reset; the crossing rule that a change is
between two *decided* sides; the measurement path's exception to "a readout quotes a stored
sample", why the band moves the edge decision only, why `measure_accumulate` loops samples outer,
and why a filtered window disables both bucket fast paths; that `MathOp` is append-only (the index
*is* the serialisation), that the median window is pooled in the runtime rather than held per node,
why the pole reuses `b0`/`z1`, and that median-then-pole is the design; the session's named
`noise`/`hf` keys and its thirteen-field node string that still reads twelve; and the two GTK
traps -- positionally brace-initialised dialogs, and a control that cannot apply being hidden
rather than disabled.
This commit is contained in:
Martino Ferrari committed 2026-10-13 16:05:28 +02:00
1 parent c38630643d
commit 749b34a2cb
7 files changed
+114 -1

No files matched your search

@@ -23,6 +23,13 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
was parsed into the last calibration record and the enable state was lost without a word.
`mkdirs()` used to create only components with a trailing slash, so `~/.config/udpscope` was never
made and the *first* save failed silently -- worth knowing when a layout change "does not stick".
- **Measurement options persist under *named* keys -- `noise` and `hf` -- so a file written before them
loads at the defaults**, which are exactly the behaviour it was written against: `noise = 10` is the
hysteresis band the app has always counted with, and `hf = 0` is no filter.
- **The math node string is thirteen pipe fields, and the reader accepts twelve *or* thirteen.** `med_n` is
the thirteenth, after `y`; a twelve-field node is a file written before the de-noise node existed, and its
`med_n` stays at the struct's default -- which is what such a file meant. Field 0 is the op as a
`math_op_at()` index, which is why `MathOp` may only be *appended* to.
- **The export is collected at click time, not in the file-dialog callback.** The live
view keeps scrolling while the chooser is up, so a late collection would write a
window the user never saw. The writer is picked by the chosen path's extension.