"""Regression test: repeated `pull()` against an unchanged fleet emits zero events. The bug: when the same session UUID is visible from multiple hosts (mac-sync's shared `~/.claude/projects/` makes plum's local sessions also visible from apricot), the projection alternated host on each pull, emitting a spurious `SessionObserved` every time. The fix: dedup incoming session rows by UUID before diffing against the projection — one canonical observation per pull. """ from __future__ import annotations from uuid import UUID from claire.pull import pull from claire.rclaude import SessionRow, TriageRow class _FakeRclaude: """Deterministic rclaude stand-in returning the same rows every call.""" def __init__(self, sessions: list[SessionRow], triage: list[TriageRow] | None = None): self._sessions = sessions self._triage = triage or [] def list_sessions(self) -> list[SessionRow]: return list(self._sessions) def list_tmux(self) -> list: return [] # no live panes in this idempotency test def triage(self) -> list[TriageRow]: return list(self._triage) def test_pull_is_idempotent_across_macsync_hosts(conn, gen) -> None: """Same UUID reported by `local` + `apricot` must not oscillate.""" shared_uuid = UUID("11111111-1111-1111-1111-111111111111") mtime = 1_700_000_000 # arbitrary fixed epoch cwd = "/Users/natalie/Code/@projects/@claire" rows = [ SessionRow(host="local", uuid=shared_uuid, snippet="hi", cwd=cwd, mtime_epoch=mtime), SessionRow(host="apricot", uuid=shared_uuid, snippet="hi", cwd=cwd, mtime_epoch=mtime), ] fake = _FakeRclaude(sessions=rows) first = pull(conn, gen, rclaude=fake) assert first.sessions_observed >= 1, "first pull must observe the session" assert first.errors == [] second = pull(conn, gen, rclaude=fake) assert second.sessions_observed == 0, ( f"second pull should be a no-op, got {second.sessions_observed} observations" ) assert second.errors == [] # And a third pull also stays quiet — confirming we don't oscillate. third = pull(conn, gen, rclaude=fake) assert third.sessions_observed == 0 def test_pull_dedup_picks_highest_mtime(conn, gen) -> None: """When the same UUID has different mtimes per host, take the freshest.""" shared_uuid = UUID("22222222-2222-2222-2222-222222222222") older = 1_700_000_000 newer = 1_700_000_500 cwd = "/tmp/work" rows_v1 = [ SessionRow(host="apricot", uuid=shared_uuid, snippet="a", cwd=cwd, mtime_epoch=older), SessionRow(host="local", uuid=shared_uuid, snippet="a", cwd=cwd, mtime_epoch=newer), ] fake = _FakeRclaude(sessions=rows_v1) first = pull(conn, gen, rclaude=fake) assert first.sessions_observed == 1 # Re-pull with the same data — must be idempotent. second = pull(conn, gen, rclaude=fake) assert second.sessions_observed == 0 # Projection should reflect the row with the newer mtime (host=local). row = conn.execute( "SELECT host, last_seen_mtime FROM sessions WHERE uuid = ?", (str(shared_uuid),), ).fetchone() assert row["host"] == "local"