THE BOUNDS WERE NOT SUFFICIENT AND THE TEST COULD NOT SEE IT.
`ConfigKind::Number` validates finiteness and bounds and nothing else,
and `on_change` listeners are notified after a value is stored — they
cannot veto. So 0.015 is a perfectly settable step and nothing in the
registry can refuse it.
Used raw it breaks the framed guarantee, because each operation rounds
independently and 16.015 and 16.005 round in OPPOSITE directions:
step 0.015: 16.00 -> 16.02 -> 16.01 broken
step 0.37 : 16.00 -> 16.37 -> 16.00 holds
The existing round-trip test used 0.37 — centi-pixel representable — so
it passed against the defect. Bitten now: with the raw value the new
case lands on 16.01, while the 0.37 case still passes, which is exactly
why it needed to be its own witness.
QUANTIZED WHERE USED, not at `set`. Sizes live in integer hundredths
end to end and `validate_font_size` already range-checks the original
and then rounds to the nearest hundredth; rounding the step is that
same operation one level up. A step of 0.015 is not a finer step in
this domain, it is 0.02 written imprecisely.
Enforcing at set time was considered and rejected: the registry cannot
express a precision constraint, and a validating wrapper is bypassed by
a direct `pmacs.config.set` — the seam `autosave` already documents
about its own interval_ms wrapper. Quantizing at the point of use
cannot be bypassed. Both descriptions say "quantized to hundredths", so
`describe-setting` shows it.
The framing header also still said "proposed, awaiting approval" while
the lane and this PR recorded it approved and implemented. Revision 5,
with §3.2 recording the gap and why quantization rather than rejection
closes it.
Verified: fmt, clippy, diff-check, --lib 1900/0, gui_zoom 15/15.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>