Salvaged from #117951 by @jonpol01 — same goal, reshaped to the cron
ledgers' in-transaction prune so no second connection, no
counter/interval state, no test clock.
`record_obligation` ran `_prune()` after its own transaction closed, and
`_prune()` opened a second connection + transaction, so every outbound
reply paid two SQLite connections. `_prune_unlocked(conn, now)` runs the
identical retention DELETEs (same age rule, same row cap) on the
recording connection inside the recording transaction, mirroring
cron/delivery_queue._prune_terminal_unlocked and
cron/executions._prune_unlocked. `_prune()` still exists for its
existing callers and delegates to it. A prune failure is still logged
at debug and never costs the recorded obligation.