- gossip: validate push batches (4 MiB / 1000-row caps); reject rows
claiming the local node id (vector-poisoning), empty ids, negative HCLs
- gossip: reconcile derived state after pulls (pulls only append to the
observation log, so entry-count comparison could never trigger it)
- hlc: seek clock from persisted MAX(hcl) at Open so a restart with a
regressed wall clock cannot reissue values (locator/cursor safety)
- db: serialize writers via BEGIN IMMEDIATE DSN, single conn per pool,
and a per-KnoxDB mutex around RecordObservation's dedup
- watch: atomic ticker guards (was a cross-goroutine data race),
trailing-edge per-path debounce, recursive directory watches,
rename re-ingest, remove cancels pending ingests
- mcp: strict argument validation (no silent clamping), thread existence
checks before writes, nil-safe golden-thread tool
- cli: --page 0 no longer panics; query/recent pagination actually pages
- tests: hlc SeekTo monotonicity, concurrent dedup race, push validation,
batch caps, idempotency on observation counts
Refs #1
- /v1/ping now advertises the node's known peers (peer_id, addr, name)
- Run sweeps static KNOX_PEERS + persisted discovered peers, enqueueing
newly-learned addresses for direct sweeps (membership-only relay; no
observation relay)
- db: ShareablePeers, SwarmPeerAddrs, MergePeer (cursor-preserving
discovery upsert), MaxHCLForNode
- integration test: a node configured with a single seed discovers and
pulls from other swarm members without direct configuration