Module: SwarmMemory::Core::StorageReadTracker

Defined in:
lib/swarm_memory/core/storage_read_tracker.rb

Overview

StorageReadTracker manages read-entry tracking for all agents with content digest verification

This module maintains a global registry of which memory entries each agent has read during their conversation along with SHA256 digests of the content. This enables enforcement of the "read-before-edit" rule that ensures agents have context before modifying entries, AND prevents editing entries that have changed externally since being read.

Each agent maintains an independent map of read entries to content digests.

Class Method Summary collapse

Class Method Details

.clear(agent_id) ⇒ void

This method returns an undefined value.

Clear read history for an agent (useful for testing)

Parameters:

  • agent_id (Symbol)

    The agent identifier



83
84
85
86
87
# File 'lib/swarm_memory/core/storage_read_tracker.rb', line 83

def clear(agent_id)
  @mutex.synchronize do
    @read_entries.delete(agent_id)
  end
end

.clear_allvoid

This method returns an undefined value.

Clear all read history (useful for testing)



92
93
94
95
96
# File 'lib/swarm_memory/core/storage_read_tracker.rb', line 92

def clear_all
  @mutex.synchronize do
    @read_entries.clear
  end
end

.entry_read?(agent_id, entry_path, storage) ⇒ Boolean

Check if an agent has read an entry AND content hasn't changed

Parameters:

  • agent_id (Symbol)

    The agent identifier

  • entry_path (String)

    The storage entry path

  • storage (Storage)

    Storage instance to read current content

Returns:

  • (Boolean)

    true if agent read entry and content matches



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/swarm_memory/core/storage_read_tracker.rb', line 40

def entry_read?(agent_id, entry_path, storage)
  @mutex.synchronize do
    return false unless @read_entries[agent_id]

    stored_digest = @read_entries[agent_id][entry_path]
    return false unless stored_digest

    # Check if entry still matches stored digest
    begin
      current_content = storage.read(file_path: entry_path)
      current_digest = Digest::SHA256.hexdigest(current_content)
      current_digest == stored_digest
    rescue StandardError
      false # Entry deleted or inaccessible
    end
  end
end

.get_read_entries(agent_id) ⇒ Hash

Get all read entries with digests for snapshot

Parameters:

  • agent_id (Symbol)

    The agent identifier

Returns:

  • (Hash)

    { entry_path => digest }



62
63
64
65
66
# File 'lib/swarm_memory/core/storage_read_tracker.rb', line 62

def get_read_entries(agent_id)
  @mutex.synchronize do
    @read_entries[agent_id]&.dup || {}
  end
end

.register_read(agent_id, entry_path, content) ⇒ String

Register that an agent has read a storage entry with content digest

Parameters:

  • agent_id (Symbol)

    The agent identifier

  • entry_path (String)

    The storage entry path

  • content (String)

    Entry content (for digest calculation)

Returns:

  • (String)

    The calculated SHA256 digest



25
26
27
28
29
30
31
32
# File 'lib/swarm_memory/core/storage_read_tracker.rb', line 25

def register_read(agent_id, entry_path, content)
  @mutex.synchronize do
    @read_entries[agent_id] ||= {}
    digest = Digest::SHA256.hexdigest(content)
    @read_entries[agent_id][entry_path] = digest
    digest
  end
end

.restore_read_entries(agent_id, entries_with_digests) ⇒ void

This method returns an undefined value.

Restore read entries with digests from snapshot

Parameters:

  • agent_id (Symbol)

    The agent identifier

  • entries_with_digests (Hash)

    { entry_path => digest }



73
74
75
76
77
# File 'lib/swarm_memory/core/storage_read_tracker.rb', line 73

def restore_read_entries(agent_id, entries_with_digests)
  @mutex.synchronize do
    @read_entries[agent_id] = entries_with_digests.dup
  end
end