jobs.json can store everyMs/atMs and next/last run timestamps as strings.
Loading left them as str, so _compute_next_run compared str to int and raised TypeError.
Coerce with an optional-int helper at from_store_dict, matching runHistory int() paths.
save_config truncated config.json in place on crash mid-write.
Route through _write_text_atomic like the pairing store so a failed write leaves the prior file intact.
jobs.json hand-edits and asdict-style snake_case for schedule intervals and
runHistory crashed or silently disabled cron. Deserialize via Cron* from_store_dict
and shared get_camel_snake (also used by local triggers).
When max_len is 0 or negative the cut pointer never advances, so the loop hangs. Return the content unsplit, matching truncate_text_to_tokens for non-positive budgets.