Fox 2026-04-29: "part of the gossip protocol should be some default
delay that allows a user to catch and burn kindergarteners before
they are synced." Currently `mesh sync` enumerates the most-recent
N items with no age filter — a doc ingested 30 seconds ago goes
out on the next sync, & if a peer ingests it before the operator
notices a problem, burn no longer suffices (peer has its own copy).
Adds a sender-side kindergarten window:
--kindergarten-seconds N default 3600 (1 hour)
Records younger than `now - N` are held back from broadcast. Both
ANNOUNCE_ROOT (filtered on documents.ingest_ts) & ANNOUNCE_FALSIFICATION
(filtered on falsifications.at). N=0 = broadcast everything (cron-
friendly opt-out for operators preferring immediate propagation).
Result JSON now reports the held counts so the operator can see
what the window protected:
kindergarten_seconds: 3600
announced_roots: 12
kindergarten_held_roots: 3
announced_falsifications: 0
kindergarten_held_falsifications: 1
Sender-side discipline only — the receiver has no view into when
the sender created the record, so it can't enforce. Adding a
created_at on the envelope would let receivers reject too-fresh
gossip, but that's a future protocol bump (envelopes today don't
carry sender wall-clock; ts is the send time).
Tests:
- existing tests now pass `--kindergarten-seconds 0` so freshly-
ingested fixtures broadcast immediately for the test
- new test_sync_kindergarten_holds_fresh_records: a 30-second-old
doc is held; an artificially-aged doc broadcasts. announced=1,
held>=1.
- new test_sync_kindergarten_zero_broadcasts_everything: explicit
opt-out works.
342 passed, 1 skipped.