RONToTime clamps out-of-range slots (never BADARG) + generator must not emit ms≥1000
A ron60 whose calendar slots overflow (ms≥1000 from a same-second monotonic bump) is a legal 60-bit value/string but NOT a valid time; RONToTime (abc/RON.c:91) returns BADARG, and ron._date — the one caller that HARD-throws — crashes the whole jab status. Two fixes: (A) RONToTime clamps each slot to the nearest valid value so rendering / mtime restore never fail; (B) the ron60 stamp generator (ULOG monotonic max(now,last+1) bump) must not overflow the ms field when >1000 rows land in one second. Repro string: 26702A0RFd (ms=1000). Method Issues.
jab status crash in a store-backed beagle clone:
JS exception: Error: ron._date: bad ron60.
jab get wrote 1349 put wtlog rows in ONE second; the ULOG monotonic
stamp max(RONNow(), last+1) increments the PACKED ron60 integer, so the ms field (low two RON digits, ms = d1*64 + d0, 0–999; abc/RON.c:66) counts 0…999 then rolls to 1000,1001… — legal ron60 ints, illegal times.
26702A0RFc = ms 999 → renders "10:00"; 26702A0RFd =
ms 1000 (0x3e8) → RONToTime BADARG (abc/RON.c:110-111). Row 181 of the clone .be: put dog/test/KEYW.c.
ron._date (js/codec.cpp:164, HARD-THROWS, passes ms=NULL yet still
hits the ms check), dog/HUNK.c:47/:1664 (fall back to now/"?"), abc/FILE.c:421 io.setMtime (falls back to zero timespec). Only the JS date path is fatal.
RONToTime clamps every out-of-range slot to nearest valid (ms→999,
sec/min→59, hour→23, mon→1,12, mday→1,31, year digits→9) and returns OK; never BADARG once t != NULL. The three callers then fail only on ts==0.
_ulog_now, native ULOG /
keeper keep_next_pup_key) carries a same-second overflow into the next SECOND (or widens/serialises sub-ms) so it NEVER emits ms≥1000 — stamps stay round-trippable and monotonic.
abc/RON.c only; repro-first (CLAUDE.md §17) as an abc unit test;
existing RON round-trip tests stay green; ASan clean. RONOfTime input validation stays STRICT (writers must produce valid times).
— (B) is the root cause.
return BADARG in RONToTime with a clamp to the nearest
valid value (overflow→max, underflow→min); keep RONOfTime strict so this is a decode-tolerance change only, not a widening of what writers may emit.
dog/abc/test/RON.c (ms 1000→999time unchanged, mon 14→12, hour 25→23, min/sec 60→59; all return OK).
RONToTime (abc/RON.c:103 slot-by-slot clamp) — landed
abc ffc0624b / beagle pin a4094f7f "out-of-range timestamps do not throw".
(_ulog_now / keep_next_pup_key); never emit ms≥1000; add a >1000-rows-in-one-second repro. follow-up
ffc0624b / beagle pin a4094f7f "RON-001: out-of-range
timestamps do not throw" — RONToTime clamps every slot (abc/RON.c:103), RONOfTime stays strict; clamp cases in dog/abc/test/RON.c.
keep_next_pup_key
(keeper/KEEP.c:152) still bumps the PACKED ron60 (max(now,last+1)), and jab _ulog_now (ulog.hpp JABCulogNow) returns raw RONNow() — nothing prevents ms≥1000 when >1000 stamps land in one second.