Commit Graph

5 Commits

Author SHA1 Message Date
david 6845975b7b fix: harden gossip, HLC restarts, watcher races, MCP args, pagination
- 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
2026-09-17 01:52:06 -07:00
david 25a7112d8a feat: swarm membership discovery via peer-list gossip
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
2026-08-29 05:41:52 -07:00
david aa0dec68c1 feat: M2 composite locator + idle reconcile
Refs #1

- observations: hcl backfilled from local rowid; (node_id, hcl) UNIQUE
  locator index becomes the gossip merge key
- threads: cluster_key column + partial UNIQUE index; CreateThreadCluster
  is idempotent, threader folds into exact cluster_key before heuristic
- AutoLinkThreadObservations dedup re-expressed on hcl DESC
- new `knox reconcile [--dry-run]` rebuilds entries from the observation
  log and re-links threads idempotently (entry count, thread cluster_key
  verified bit-identical from log-only DB)
2026-08-29 04:47:15 -07:00
david 2c0f8fa257 feat: M1 determinism fixes for gossip
Refs #1

- F1: canonical fingerprints (git identity by remote URL, log by
  basename, obsidian by relative vault path) so identical facts get
  identical ids across machines
- F2: node_id (persisted in settings) + Hybrid Logical Clock in all
  observation "when" columns; removed time.Now() fact-time fallbacks
- F3: stable TF-IDF tie-break sort (score desc, term asc)
- F4: observations carry (node_id, hcl) locator; dedup ordered by hcl
2026-08-29 03:51:02 -07:00
david 8eecde18b4 Initial commit: knox knowledge index 2026-08-29 02:52:32 -07:00