htm 0.0.1

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.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/.architecture/decisions/adrs/001-use-postgresql-timescaledb-storage.md +227 -0
  3. data/.architecture/decisions/adrs/002-two-tier-memory-architecture.md +322 -0
  4. data/.architecture/decisions/adrs/003-ollama-default-embedding-provider.md +339 -0
  5. data/.architecture/decisions/adrs/004-multi-robot-shared-memory-hive-mind.md +374 -0
  6. data/.architecture/decisions/adrs/005-rag-based-retrieval-with-hybrid-search.md +443 -0
  7. data/.architecture/decisions/adrs/006-context-assembly-strategies.md +444 -0
  8. data/.architecture/decisions/adrs/007-working-memory-eviction-strategy.md +461 -0
  9. data/.architecture/decisions/adrs/008-robot-identification-system.md +550 -0
  10. data/.architecture/decisions/adrs/009-never-forget-explicit-deletion-only.md +570 -0
  11. data/.architecture/decisions/adrs/010-redis-working-memory-rejected.md +323 -0
  12. data/.architecture/decisions/adrs/011-database-side-embedding-generation-with-pgai.md +585 -0
  13. data/.architecture/decisions/adrs/012-llm-driven-ontology-topic-extraction.md +583 -0
  14. data/.architecture/decisions/adrs/013-activerecord-orm-and-many-to-many-tagging.md +299 -0
  15. data/.architecture/decisions/adrs/014-client-side-embedding-generation-workflow.md +569 -0
  16. data/.architecture/decisions/adrs/015-hierarchical-tag-ontology-and-llm-extraction.md +701 -0
  17. data/.architecture/decisions/adrs/016-async-embedding-and-tag-generation.md +694 -0
  18. data/.architecture/members.yml +144 -0
  19. data/.architecture/reviews/2025-10-29-llm-configuration-and-async-processing-review.md +1137 -0
  20. data/.architecture/reviews/initial-system-analysis.md +330 -0
  21. data/.envrc +32 -0
  22. data/.irbrc +145 -0
  23. data/CHANGELOG.md +150 -0
  24. data/COMMITS.md +196 -0
  25. data/LICENSE +21 -0
  26. data/README.md +1347 -0
  27. data/Rakefile +51 -0
  28. data/SETUP.md +268 -0
  29. data/config/database.yml +67 -0
  30. data/db/migrate/20250101000001_enable_extensions.rb +14 -0
  31. data/db/migrate/20250101000002_create_robots.rb +14 -0
  32. data/db/migrate/20250101000003_create_nodes.rb +42 -0
  33. data/db/migrate/20250101000005_create_tags.rb +38 -0
  34. data/db/migrate/20250101000007_add_node_vector_indexes.rb +30 -0
  35. data/db/schema.sql +473 -0
  36. data/db/seed_data/README.md +100 -0
  37. data/db/seed_data/presidents.md +136 -0
  38. data/db/seed_data/states.md +151 -0
  39. data/db/seeds.rb +208 -0
  40. data/dbdoc/README.md +173 -0
  41. data/dbdoc/public.node_stats.md +48 -0
  42. data/dbdoc/public.node_stats.svg +41 -0
  43. data/dbdoc/public.node_tags.md +40 -0
  44. data/dbdoc/public.node_tags.svg +112 -0
  45. data/dbdoc/public.nodes.md +54 -0
  46. data/dbdoc/public.nodes.svg +118 -0
  47. data/dbdoc/public.nodes_tags.md +39 -0
  48. data/dbdoc/public.nodes_tags.svg +112 -0
  49. data/dbdoc/public.ontology_structure.md +48 -0
  50. data/dbdoc/public.ontology_structure.svg +38 -0
  51. data/dbdoc/public.operations_log.md +42 -0
  52. data/dbdoc/public.operations_log.svg +130 -0
  53. data/dbdoc/public.relationships.md +39 -0
  54. data/dbdoc/public.relationships.svg +41 -0
  55. data/dbdoc/public.robot_activity.md +46 -0
  56. data/dbdoc/public.robot_activity.svg +35 -0
  57. data/dbdoc/public.robots.md +35 -0
  58. data/dbdoc/public.robots.svg +90 -0
  59. data/dbdoc/public.schema_migrations.md +29 -0
  60. data/dbdoc/public.schema_migrations.svg +26 -0
  61. data/dbdoc/public.tags.md +35 -0
  62. data/dbdoc/public.tags.svg +60 -0
  63. data/dbdoc/public.topic_relationships.md +45 -0
  64. data/dbdoc/public.topic_relationships.svg +32 -0
  65. data/dbdoc/schema.json +1437 -0
  66. data/dbdoc/schema.svg +154 -0
  67. data/docs/api/database.md +806 -0
  68. data/docs/api/embedding-service.md +532 -0
  69. data/docs/api/htm.md +797 -0
  70. data/docs/api/index.md +259 -0
  71. data/docs/api/long-term-memory.md +1096 -0
  72. data/docs/api/working-memory.md +665 -0
  73. data/docs/architecture/adrs/001-postgresql-timescaledb.md +314 -0
  74. data/docs/architecture/adrs/002-two-tier-memory.md +411 -0
  75. data/docs/architecture/adrs/003-ollama-embeddings.md +421 -0
  76. data/docs/architecture/adrs/004-hive-mind.md +437 -0
  77. data/docs/architecture/adrs/005-rag-retrieval.md +531 -0
  78. data/docs/architecture/adrs/006-context-assembly.md +496 -0
  79. data/docs/architecture/adrs/007-eviction-strategy.md +645 -0
  80. data/docs/architecture/adrs/008-robot-identification.md +625 -0
  81. data/docs/architecture/adrs/009-never-forget.md +648 -0
  82. data/docs/architecture/adrs/010-redis-working-memory-rejected.md +323 -0
  83. data/docs/architecture/adrs/011-pgai-integration.md +494 -0
  84. data/docs/architecture/adrs/index.md +215 -0
  85. data/docs/architecture/hive-mind.md +736 -0
  86. data/docs/architecture/index.md +351 -0
  87. data/docs/architecture/overview.md +538 -0
  88. data/docs/architecture/two-tier-memory.md +873 -0
  89. data/docs/assets/css/custom.css +83 -0
  90. data/docs/assets/images/htm-core-components.svg +63 -0
  91. data/docs/assets/images/htm-database-schema.svg +93 -0
  92. data/docs/assets/images/htm-hive-mind-architecture.svg +125 -0
  93. data/docs/assets/images/htm-importance-scoring-framework.svg +83 -0
  94. data/docs/assets/images/htm-layered-architecture.svg +71 -0
  95. data/docs/assets/images/htm-long-term-memory-architecture.svg +115 -0
  96. data/docs/assets/images/htm-working-memory-architecture.svg +120 -0
  97. data/docs/assets/images/htm.jpg +0 -0
  98. data/docs/assets/images/htm_demo.gif +0 -0
  99. data/docs/assets/js/mathjax.js +18 -0
  100. data/docs/assets/videos/htm_video.mp4 +0 -0
  101. data/docs/database_rake_tasks.md +322 -0
  102. data/docs/development/contributing.md +787 -0
  103. data/docs/development/index.md +336 -0
  104. data/docs/development/schema.md +596 -0
  105. data/docs/development/setup.md +719 -0
  106. data/docs/development/testing.md +819 -0
  107. data/docs/guides/adding-memories.md +824 -0
  108. data/docs/guides/context-assembly.md +1009 -0
  109. data/docs/guides/getting-started.md +577 -0
  110. data/docs/guides/index.md +118 -0
  111. data/docs/guides/long-term-memory.md +941 -0
  112. data/docs/guides/multi-robot.md +866 -0
  113. data/docs/guides/recalling-memories.md +927 -0
  114. data/docs/guides/search-strategies.md +953 -0
  115. data/docs/guides/working-memory.md +717 -0
  116. data/docs/index.md +214 -0
  117. data/docs/installation.md +477 -0
  118. data/docs/multi_framework_support.md +519 -0
  119. data/docs/quick-start.md +655 -0
  120. data/docs/setup_local_database.md +302 -0
  121. data/docs/using_rake_tasks_in_your_app.md +383 -0
  122. data/examples/basic_usage.rb +93 -0
  123. data/examples/cli_app/README.md +317 -0
  124. data/examples/cli_app/htm_cli.rb +270 -0
  125. data/examples/custom_llm_configuration.rb +183 -0
  126. data/examples/example_app/Rakefile +71 -0
  127. data/examples/example_app/app.rb +206 -0
  128. data/examples/sinatra_app/Gemfile +21 -0
  129. data/examples/sinatra_app/app.rb +335 -0
  130. data/lib/htm/active_record_config.rb +113 -0
  131. data/lib/htm/configuration.rb +342 -0
  132. data/lib/htm/database.rb +594 -0
  133. data/lib/htm/embedding_service.rb +115 -0
  134. data/lib/htm/errors.rb +34 -0
  135. data/lib/htm/job_adapter.rb +154 -0
  136. data/lib/htm/jobs/generate_embedding_job.rb +65 -0
  137. data/lib/htm/jobs/generate_tags_job.rb +82 -0
  138. data/lib/htm/long_term_memory.rb +965 -0
  139. data/lib/htm/models/node.rb +109 -0
  140. data/lib/htm/models/node_tag.rb +33 -0
  141. data/lib/htm/models/robot.rb +52 -0
  142. data/lib/htm/models/tag.rb +76 -0
  143. data/lib/htm/railtie.rb +76 -0
  144. data/lib/htm/sinatra.rb +157 -0
  145. data/lib/htm/tag_service.rb +135 -0
  146. data/lib/htm/tasks.rb +38 -0
  147. data/lib/htm/version.rb +5 -0
  148. data/lib/htm/working_memory.rb +182 -0
  149. data/lib/htm.rb +400 -0
  150. data/lib/tasks/db.rake +19 -0
  151. data/lib/tasks/htm.rake +147 -0
  152. data/lib/tasks/jobs.rake +312 -0
  153. data/mkdocs.yml +190 -0
  154. data/scripts/install_local_database.sh +309 -0
  155. metadata +341 -0
@@ -0,0 +1,323 @@
1
+ # ADR-010: Redis-Based Working Memory (Rejected)
2
+
3
+ **Status**: Rejected
4
+
5
+ **Date**: 2025-10-25
6
+
7
+ **Decision Makers**: Dewayne VanHoozer, Claude (Anthropic)
8
+
9
+ ---
10
+
11
+ ## Quick Summary
12
+
13
+ **Proposal**: Add Redis as a persistent storage layer for working memory, creating a three-tier architecture (Working Memory in Redis, Long-term Memory in PostgreSQL, with in-process caching).
14
+
15
+ **Decision**: **REJECTED** - Keep the current two-tier architecture with in-memory working memory.
16
+
17
+ **Why Rejected**: Redis adds complexity, cost, and failure modes without solving a proven problem. PostgreSQL already provides durability, and working memory's ephemeral nature is a feature, not a bug.
18
+
19
+ **Impact**: Avoiding unnecessary complexity while maintaining simplicity, performance, and reliability.
20
+
21
+ ---
22
+
23
+ ## Context
24
+
25
+ ### Motivation for Consideration
26
+
27
+ During architectural review, we identified that working memory is currently volatile (in-process Ruby hash) and loses state on process restart. This raised the question:
28
+
29
+ > "Should working memory persist across restarts using Redis?"
30
+
31
+ ### Current Architecture (Two-Tier)
32
+
33
+ ```
34
+ ┌─────────────────┐
35
+ │ HTM Instance │
36
+ │ │
37
+ │ ┌───────────┐ │ ┌──────────────┐
38
+ │ │ Working │ │────>│ PostgreSQL │
39
+ │ │ Memory │ │ │ (Long-Term) │
40
+ │ │ (Hash) │ │ │ │
41
+ │ └───────────┘ │ └──────────────┘
42
+ │ volatile │ persistent
43
+ └─────────────────┘
44
+ ```
45
+
46
+ **How it works**:
47
+ 1. `add_node()` saves **immediately** to PostgreSQL
48
+ 2. Node is **also** added to working memory (cache)
49
+ 3. Working memory evicts old nodes when full
50
+ 4. Eviction **only removes from cache** - data remains in PostgreSQL
51
+
52
+ **Key insight**: Working memory is a **write-through cache**, not the source of truth.
53
+
54
+ ### Proposed Architecture (Three-Tier)
55
+
56
+ ```
57
+ ┌─────────────────┐
58
+ │ HTM Instance │
59
+ │ │
60
+ │ ││ │
61
+ │ ││ │
62
+ │ ▼▼ │
63
+ │ ┌───────────┐ │ ┌──────────────┐
64
+ │ │ Redis │ │────>│ PostgreSQL │
65
+ │ │ (Working) │ │ │ (Long-Term) │
66
+ │ │ │ │ │ │
67
+ │ └───────────┘ │ └──────────────┘
68
+ │ persistent │ persistent
69
+ └─────────────────┘
70
+ ```
71
+
72
+ **Proposed changes**:
73
+ - Store working memory in Redis (shared across processes)
74
+ - Persist working memory state across restarts
75
+ - Allow multi-process working memory sharing
76
+ - Optional flush strategies (on-demand, auto-exit, periodic)
77
+
78
+ ---
79
+
80
+ ## Analysis
81
+
82
+ ### Perceived Benefits (Why We Considered It)
83
+
84
+ 1. **Persistence Across Restarts**
85
+ - Working memory survives process crashes
86
+ - Can resume conversations exactly where left off
87
+
88
+ 2. **Multi-Process Sharing**
89
+ - Multiple HTM instances can share hot context
90
+ - "Hive mind" working memory across robots
91
+
92
+ 3. **Larger Capacity**
93
+ - Not limited by process memory (~2GB)
94
+ - Could scale to 10s-100s of GB in Redis
95
+
96
+ 4. **External Observability**
97
+ - Inspect working memory via `redis-cli`
98
+ - Monitor access patterns externally
99
+
100
+ ### Actual Drawbacks (Why We Rejected It)
101
+
102
+ #### 1. **Adds Complexity Without Clear Benefit**
103
+
104
+ | Aspect | Current | With Redis |
105
+ |--------|---------|------------|
106
+ | Dependencies | PostgreSQL only | PostgreSQL + Redis |
107
+ | Failure Modes | 1 database | 2 databases |
108
+ | Deployment | Single service | Multiple services |
109
+ | Configuration | Simple | Complex (URLs, pools, namespaces) |
110
+ | Debugging | Straightforward | More moving parts |
111
+
112
+ #### 2. **PostgreSQL Already Solves the Problem**
113
+
114
+ **Restart recovery is trivial**:
115
+ ```ruby
116
+ # On restart, rebuild working memory from PostgreSQL
117
+ htm = HTM.new(robot_name: "Assistant")
118
+
119
+ recent_memories = htm.recall(
120
+ timeframe: "last 10 minutes",
121
+ topic: "",
122
+ limit: 50
123
+ )
124
+ # ↑ Automatically added to working memory
125
+ ```
126
+
127
+ **Multi-process sharing already works**:
128
+ ```ruby
129
+ # Process A
130
+ htm_a.add_node("decision", "Use PostgreSQL")
131
+ # → Saved to PostgreSQL
132
+
133
+ # Process B (different process)
134
+ memories = htm_b.recall(timeframe: "last minute", topic: "PostgreSQL")
135
+ # → Retrieved from PostgreSQL, added to Process B's working memory
136
+ ```
137
+
138
+ The "hive mind" already exists via shared PostgreSQL!
139
+
140
+ #### 3. **Performance Penalty**
141
+
142
+ | Operation | In-Memory | Redis (Local) | Redis (Network) |
143
+ |-----------|-----------|---------------|-----------------|
144
+ | `add()` | ~0.001ms | ~0.5ms | ~5ms |
145
+ | `get()` | ~0.001ms | ~0.5ms | ~5ms |
146
+ | Network overhead | None | TCP localhost | TCP network |
147
+
148
+ **100-500x slower** for working memory operations, even locally.
149
+
150
+ #### 4. **Working Memory is *Supposed* to be Ephemeral**
151
+
152
+ The whole design philosophy:
153
+ - **Token-limited** (128k) for LLM context windows
154
+ - **Fast access** for immediate context
155
+ - **Disposable** - it's a performance optimization
156
+
157
+ Making it persistent contradicts its purpose!
158
+
159
+ #### 5. **Operational Burden**
160
+
161
+ **Additional costs**:
162
+ - Redis server hosting/management
163
+ - Memory allocation for Redis
164
+ - Monitoring Redis health
165
+ - Backup/recovery for Redis
166
+ - Network configuration
167
+ - Connection pool tuning
168
+
169
+ **Additional failure scenarios**:
170
+ - Redis connection failures
171
+ - Redis out of memory
172
+ - Redis network partitions
173
+ - Redis data corruption
174
+ - Synchronization issues between Redis and PostgreSQL
175
+
176
+ #### 6. **YAGNI (You Aren't Gonna Need It)**
177
+
178
+ No proven requirement for:
179
+ - Sub-millisecond working memory access across processes
180
+ - Exact working memory state preservation across crashes
181
+ - Real-time synchronization of working memory between instances
182
+
183
+ This is **premature optimization** solving a hypothetical problem.
184
+
185
+ ---
186
+
187
+ ## Decision
188
+
189
+ **We will NOT implement Redis-based working memory.**
190
+
191
+ We will **maintain the current two-tier architecture**:
192
+ - **Working Memory**: In-memory Ruby hash (volatile)
193
+ - **Long-term Memory**: PostgreSQL (durable)
194
+
195
+ ---
196
+
197
+ ## Rationale
198
+
199
+ ### Why the Current Design is Sufficient
200
+
201
+ 1. **Data is Already Safe**
202
+ - All nodes are immediately persisted to PostgreSQL
203
+ - Working memory is just a cache
204
+ - Nothing is lost on restart except cache state
205
+
206
+ 2. **Restart Recovery is Fast**
207
+ - Rebuild working memory via `recall()`
208
+ - Takes milliseconds to query recent context
209
+ - No need for persistent cache state
210
+
211
+ 3. **Multi-Process Works Today**
212
+ - Processes share via PostgreSQL
213
+ - No real-time synchronization needed
214
+ - Each process maintains its own hot cache
215
+
216
+ 4. **Simplicity Wins**
217
+ - One database (PostgreSQL)
218
+ - One failure mode
219
+ - Easy to understand and debug
220
+ - Lower operational cost
221
+
222
+ 5. **Performance is Excellent**
223
+ - In-memory hash: <1ms operations
224
+ - PostgreSQL: 10-50ms queries (acceptable)
225
+ - No need for Redis middle layer
226
+
227
+ ### When Redis *Might* Make Sense (Future)
228
+
229
+ We'll reconsider if we encounter:
230
+ - **Proven requirement** for cross-process hot memory sharing
231
+ - **Measured performance problem** with PostgreSQL recall
232
+ - **Specific use case** needing persistent working memory state
233
+ - **User demand** for this feature
234
+
235
+ Until then: **YAGNI**.
236
+
237
+ ---
238
+
239
+ ## Consequences
240
+
241
+ ### Positive
242
+
243
+ ✅ **Simplicity maintained**
244
+ - Single database dependency
245
+ - Straightforward architecture
246
+ - Easy to understand and debug
247
+
248
+ ✅ **Lower operational cost**
249
+ - No Redis hosting
250
+ - No Redis management
251
+ - Fewer failure modes
252
+
253
+ ✅ **Better performance**
254
+ - In-memory working memory is fastest possible
255
+ - No network overhead
256
+
257
+ ✅ **Sufficient for use cases**
258
+ - All data persisted in PostgreSQL
259
+ - Multi-process sharing via PostgreSQL
260
+ - Fast restart recovery
261
+
262
+ ### Negative (Accepted Trade-offs)
263
+
264
+ ❌ **Working memory lost on crash**
265
+ - **Mitigation**: Rebuild via `recall()` in <1 second
266
+ - **Impact**: Minimal - data is safe in PostgreSQL
267
+
268
+ ❌ **No real-time cross-process working memory**
269
+ - **Mitigation**: Processes share via PostgreSQL
270
+ - **Impact**: Acceptable - no proven requirement
271
+
272
+ ❌ **Limited by process memory**
273
+ - **Mitigation**: 128k token limit is sufficient for LLM context
274
+ - **Impact**: None - this is by design
275
+
276
+ ---
277
+
278
+ ## Alternatives Considered
279
+
280
+ ### Alternative 1: Hybrid L1/L2 Caching
281
+ - L1: In-memory (hot data)
282
+ - L2: Redis (warm data)
283
+ - **Rejected**: Even more complexity for minimal gain
284
+
285
+ ### Alternative 2: PostgreSQL UNLOGGED Tables
286
+ - Use unlogged PostgreSQL tables for working memory
287
+ - Faster writes, but not crash-safe
288
+ - **Rejected**: Still slower than in-memory, adds DB complexity
289
+
290
+ ### Alternative 3: Shared Memory (IPC)
291
+ - Use OS shared memory for cross-process working memory
292
+ - **Rejected**: Platform-specific, complex, limited use case
293
+
294
+ ---
295
+
296
+ ## References
297
+
298
+ - **Discussion**: `/tmp/redis_working_memory_architecture.md`
299
+ - **Related ADR**: ADR-002 (Two-Tier Memory Architecture)
300
+ - **Architecture Review**: `ARCHITECTURE_REVIEW.md`
301
+ - **GitHub Issues**: #1-#10 (focus on proven improvements)
302
+
303
+ ---
304
+
305
+ ## Lessons Learned
306
+
307
+ 1. **Question assumptions**: "Working memory is volatile" seemed like a problem, but it's actually by design
308
+ 2. **PostgreSQL is powerful**: Already provides durability, querying, and sharing
309
+ 3. **Simplicity has value**: Adding Redis would double complexity for minimal real benefit
310
+ 4. **YAGNI applies**: Solve proven problems, not hypothetical ones
311
+ 5. **Architecture reviews are valuable**: Thoroughly analyzing alternatives leads to better decisions (even when the decision is "no")
312
+
313
+ ---
314
+
315
+ ## Future Review
316
+
317
+ This decision should be revisited if:
318
+ - User requests for persistent working memory
319
+ - Measured performance problems with PostgreSQL recall
320
+ - Multi-process real-time sharing becomes a requirement
321
+ - Benchmarks show significant benefit to Redis caching
322
+
323
+ Until then, this decision stands: **Keep it simple. Trust PostgreSQL.**