lex-agentic-memory 0.1.35 → 0.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb940d62021d4a86ed5de171d6b275c9287a9ca727efadd3c60c3a87ca0f921e
4
- data.tar.gz: b02842d4a5939e436d7ae4f72cca295839061f5fa4cdbf9b47736f37e462e76e
3
+ metadata.gz: f135722a81c15e36374e61e6348db1f421db9b4fc5257bc2915d8526a9b7a145
4
+ data.tar.gz: 86dfb884036c9d7d8617a3a785b6b35c6cc0db413b60a9866aad04ad3e899d59
5
5
  SHA512:
6
- metadata.gz: e28e286f59952562c8c00ad37cb06f84914f2b93af864cb95a1d9904c218dc72d28bb09a4df049c418f5a66df752a199171c0e553e684c234ae888ab73be24a8
7
- data.tar.gz: 12febef87343cde5c4ca8f372c62a6f7d5b053a47ad5362710ee54224be60ceb899f7f0f32eeb65cc9474ebe5b47535731e2f6a3e83a89f3d315c6780774ea77
6
+ metadata.gz: bd080984039d516a8980ed88723a34f6f8738439f55a921e572cbba852f73af3c48010cffc9fec5b134305f2e7d0f7d774d032bf8a41e88003b9f7cef8cba34a
7
+ data.tar.gz: 5e2fbe8775082a3e64533acce43937923b0e5f6c97cc7bcb623fc4a42f9bc21be513f824fef9ea80f13afb392da5e30648b68fd6e9a9fbadd1e1eeed985259b5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.36] - 2026-05-17
4
+ ### Fixed
5
+ - `PostgresStore#db_ready?` now checks `Legion::Data.can_write?(:memory_traces)` before attempting writes, preventing `PG::InsufficientPrivilege` errors when connected with a read-only role.
6
+ - `Trace.postgres_available?` also checks INSERT privilege so `create_store` correctly falls back to a local store instead of selecting PostgresStore and failing at runtime.
7
+
3
8
  ## [0.1.34] - 2026-05-08
4
9
  ### Fixed
5
10
  - Deferred GAIA heartbeat maintenance no longer initializes the shared trace store just to return a deferred summary, avoiding idle local trace table scans.
@@ -264,12 +264,14 @@ module Legion
264
264
  # No-op — this store is write-through; nothing to flush.
265
265
  def flush; end
266
266
 
267
- # Returns true when both required tables exist in the connected DB.
267
+ # Returns true when both required tables exist and the user has INSERT privilege on both.
268
268
  def db_ready?
269
269
  defined?(Legion::Data) &&
270
270
  Legion::Data.respond_to?(:connection) &&
271
271
  Legion::Data.connection&.table_exists?(TRACES_TABLE) &&
272
- Legion::Data.connection.table_exists?(ASSOCIATIONS_TABLE)
272
+ Legion::Data.connection.table_exists?(ASSOCIATIONS_TABLE) &&
273
+ Legion::Data.can_write?(TRACES_TABLE) &&
274
+ Legion::Data.can_write?(ASSOCIATIONS_TABLE)
273
275
  rescue StandardError => e
274
276
  log.error "[trace_persistence] db_ready?: #{e.message}"
275
277
  false
@@ -79,7 +79,9 @@ module Legion
79
79
  Legion::Data.connection &&
80
80
  %i[postgres mysql2].include?(Legion::Data.connection.adapter_scheme) &&
81
81
  Legion::Data.connection.table_exists?(:memory_traces) &&
82
- Legion::Data.connection.table_exists?(:memory_associations)
82
+ Legion::Data.connection.table_exists?(:memory_associations) &&
83
+ Legion::Data.can_write?(:memory_traces) &&
84
+ Legion::Data.can_write?(:memory_associations)
83
85
  rescue StandardError => _e
84
86
  false
85
87
  end
@@ -4,7 +4,7 @@ module Legion
4
4
  module Extensions
5
5
  module Agentic
6
6
  module Memory
7
- VERSION = '0.1.35'
7
+ VERSION = '0.1.36'
8
8
  end
9
9
  end
10
10
  end
@@ -65,6 +65,9 @@ RSpec.describe Legion::Extensions::Agentic::Memory::Hologram::Helpers::HologramE
65
65
  let(:fragments) { engine.fragment_hologram(hologram_id: hologram.id, count: 4) }
66
66
 
67
67
  it 'returns success: true when sufficient fragments are used' do
68
+ # Enhance all fragments to guarantee they exceed the reconstruction threshold
69
+ # regardless of the random completeness assigned during fragmentation.
70
+ fragments.each { |f| f.enhance!(0.5) }
68
71
  ids = fragments.select(&:sufficient?).map(&:id)
69
72
  result = engine.reconstruct_from_fragments(hologram_id: hologram.id, fragment_ids: ids)
70
73
  expect(result[:success]).to be true
@@ -81,8 +81,11 @@ RSpec.describe Legion::Extensions::Agentic::Memory::Trace::Helpers::PostgresStor
81
81
  end
82
82
 
83
83
  before do
84
+ allow(Legion::Data).to receive(:respond_to?).and_call_original
84
85
  allow(Legion::Data).to receive(:respond_to?).with(:connection).and_return(true)
85
86
  allow(Legion::Data).to receive(:connection).and_return(db)
87
+ allow(Legion::Data).to receive(:can_write?).with(:memory_traces).and_return(true)
88
+ allow(Legion::Data).to receive(:can_write?).with(:memory_associations).and_return(true)
86
89
  # SQLite adapter_scheme is :sqlite — postgres_available? checks for :postgres/:mysql2,
87
90
  # but PostgresStore itself only calls db_ready? which just needs the tables to exist.
88
91
  allow(db).to receive(:adapter_scheme).and_return(:sqlite)
@@ -109,6 +112,27 @@ RSpec.describe Legion::Extensions::Agentic::Memory::Trace::Helpers::PostgresStor
109
112
  allow(Legion::Data).to receive(:connection).and_raise(StandardError, 'no db')
110
113
  expect(store.db_ready?).to be false
111
114
  end
115
+
116
+ it 'returns false when user lacks INSERT privilege on memory_traces' do
117
+ allow(Legion::Data).to receive(:can_write?).with(:memory_traces).and_return(false)
118
+ expect(store.db_ready?).to be false
119
+ end
120
+
121
+ it 'returns true when user has INSERT privilege on memory_traces' do
122
+ allow(Legion::Data).to receive(:can_write?).with(:memory_traces).and_return(true)
123
+ expect(store.db_ready?).to be true
124
+ end
125
+
126
+ it 'returns false when user lacks INSERT privilege on memory_associations' do
127
+ allow(Legion::Data).to receive(:can_write?).with(:memory_associations).and_return(false)
128
+ expect(store.db_ready?).to be false
129
+ end
130
+
131
+ it 'returns true when user has INSERT privilege on both tables' do
132
+ allow(Legion::Data).to receive(:can_write?).with(:memory_traces).and_return(true)
133
+ allow(Legion::Data).to receive(:can_write?).with(:memory_associations).and_return(true)
134
+ expect(store.db_ready?).to be true
135
+ end
112
136
  end
113
137
 
114
138
  # --- store insert_conflict syntax ---
@@ -34,5 +34,43 @@ RSpec.describe Legion::Extensions::Agentic::Memory::Trace do
34
34
 
35
35
  expect(described_class.shared_store).to eq(:shared_store)
36
36
  end
37
+
38
+ it 'falls back from Postgres when user lacks INSERT privilege on memory_traces' do
39
+ allow(described_class).to receive(:local_store_available?).and_return(false)
40
+ allow(described_class).to receive(:configured_trace_store).and_return(nil)
41
+ allow(described_class).to receive(:resolve_agent_id).and_return('agent-1')
42
+
43
+ conn = double('connection', adapter_scheme: :postgres)
44
+ allow(conn).to receive(:table_exists?).and_return(true)
45
+ allow(Legion::Data).to receive(:respond_to?).and_call_original
46
+ allow(Legion::Data).to receive(:respond_to?).with(:connection).and_return(true)
47
+ allow(Legion::Data).to receive(:connection).and_return(conn)
48
+ allow(Legion::Data).to receive(:can_write?).with(:memory_traces).and_return(false)
49
+ allow(Legion::Data).to receive(:can_write?).with(:memory_associations).and_return(true)
50
+
51
+ allow(Legion::Cache).to receive(:respond_to?).with(:connected?).and_return(false)
52
+ allow(described_class::Helpers::Store).to receive(:new).with(partition_id: 'agent-1').and_return(:fallback_store)
53
+
54
+ expect(described_class.shared_store).to eq(:fallback_store)
55
+ end
56
+
57
+ it 'falls back from Postgres when user lacks INSERT privilege on memory_associations' do
58
+ allow(described_class).to receive(:local_store_available?).and_return(false)
59
+ allow(described_class).to receive(:configured_trace_store).and_return(nil)
60
+ allow(described_class).to receive(:resolve_agent_id).and_return('agent-1')
61
+
62
+ conn = double('connection', adapter_scheme: :postgres)
63
+ allow(conn).to receive(:table_exists?).and_return(true)
64
+ allow(Legion::Data).to receive(:respond_to?).and_call_original
65
+ allow(Legion::Data).to receive(:respond_to?).with(:connection).and_return(true)
66
+ allow(Legion::Data).to receive(:connection).and_return(conn)
67
+ allow(Legion::Data).to receive(:can_write?).with(:memory_traces).and_return(true)
68
+ allow(Legion::Data).to receive(:can_write?).with(:memory_associations).and_return(false)
69
+
70
+ allow(Legion::Cache).to receive(:respond_to?).with(:connected?).and_return(false)
71
+ allow(described_class::Helpers::Store).to receive(:new).with(partition_id: 'agent-1').and_return(:fallback_store)
72
+
73
+ expect(described_class.shared_store).to eq(:fallback_store)
74
+ end
37
75
  end
38
76
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-agentic-memory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.35
4
+ version: 0.1.36
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity