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,736 @@
1
+ # Hive Mind Architecture: Multi-Robot Shared Memory
2
+
3
+ HTM implements a "hive mind" architecture where multiple robots (AI agents) share a global memory database. This enables cross-robot learning, context continuity across sessions, and collaborative knowledge building without requiring users to repeat information.
4
+
5
+ ## Overview
6
+
7
+ In the hive mind model, all robots access a single shared long-term memory database while maintaining independent working memory for process isolation. This design provides the best of both worlds: global knowledge sharing with local performance optimization.
8
+
9
+ <svg viewBox="0 0 900 600" xmlns="http://www.w3.org/2000/svg" style="background: transparent;">
10
+ <!-- Title -->
11
+ <text x="450" y="30" text-anchor="middle" fill="#E0E0E0" font-size="18" font-weight="bold">Hive Mind: Shared Long-Term Memory</text>
12
+
13
+ <!-- Central Database -->
14
+ <ellipse cx="450" cy="300" rx="180" ry="120" fill="rgba(156, 39, 176, 0.2)" stroke="#9C27B0" stroke-width="3"/>
15
+ <text x="450" y="280" text-anchor="middle" fill="#E0E0E0" font-size="16" font-weight="bold">Long-Term Memory</text>
16
+ <text x="450" y="305" text-anchor="middle" fill="#B0B0B0" font-size="12">PostgreSQL</text>
17
+ <text x="450" y="325" text-anchor="middle" fill="#B0B0B0" font-size="12">Shared Global Database</text>
18
+ <text x="450" y="345" text-anchor="middle" fill="#4CAF50" font-size="13" font-weight="bold">All Robots Access Here</text>
19
+
20
+ <!-- Robot 1: Code Helper -->
21
+ <rect x="50" y="80" width="200" height="100" fill="rgba(33, 150, 243, 0.2)" stroke="#2196F3" stroke-width="2" rx="5"/>
22
+ <text x="150" y="110" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 1: Code Helper</text>
23
+ <text x="150" y="135" text-anchor="middle" fill="#B0B0B0" font-size="11">ID: robot-abc123</text>
24
+ <text x="150" y="155" text-anchor="middle" fill="#B0B0B0" font-size="11">Own Working Memory</text>
25
+
26
+ <!-- Robot 2: Research Assistant -->
27
+ <rect x="650" y="80" width="200" height="100" fill="rgba(76, 175, 80, 0.2)" stroke="#4CAF50" stroke-width="2" rx="5"/>
28
+ <text x="750" y="110" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 2: Research Bot</text>
29
+ <text x="750" y="135" text-anchor="middle" fill="#B0B0B0" font-size="11">ID: robot-xyz789</text>
30
+ <text x="750" y="155" text-anchor="middle" fill="#B0B0B0" font-size="11">Own Working Memory</text>
31
+
32
+ <!-- Robot 3: Chat Companion -->
33
+ <rect x="50" y="450" width="200" height="100" fill="rgba(255, 152, 0, 0.2)" stroke="#FF9800" stroke-width="2" rx="5"/>
34
+ <text x="150" y="480" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 3: Chat Bot</text>
35
+ <text x="150" y="505" text-anchor="middle" fill="#B0B0B0" font-size="11">ID: robot-def456</text>
36
+ <text x="150" y="525" text-anchor="middle" fill="#B0B0B0" font-size="11">Own Working Memory</text>
37
+
38
+ <!-- Robot 4: Design Assistant -->
39
+ <rect x="650" y="450" width="200" height="100" fill="rgba(244, 67, 54, 0.2)" stroke="#F44336" stroke-width="2" rx="5"/>
40
+ <text x="750" y="480" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 4: Designer</text>
41
+ <text x="750" y="505" text-anchor="middle" fill="#B0B0B0" font-size="11">ID: robot-ghi012</text>
42
+ <text x="750" y="525" text-anchor="middle" fill="#B0B0B0" font-size="11">Own Working Memory</text>
43
+
44
+ <!-- Connections to central database -->
45
+ <line x1="150" y1="180" x2="320" y2="240" stroke="#2196F3" stroke-width="3"/>
46
+ <line x1="750" y1="180" x2="580" y2="240" stroke="#4CAF50" stroke-width="3"/>
47
+ <line x1="150" y1="450" x2="320" y2="360" stroke="#FF9800" stroke-width="3"/>
48
+ <line x1="750" y1="450" x2="580" y2="360" stroke="#F44336" stroke-width="3"/>
49
+
50
+ <!-- Labels on connections -->
51
+ <text x="235" y="210" fill="#2196F3" font-size="10">read/write</text>
52
+ <text x="650" y="210" fill="#4CAF50" font-size="10">read/write</text>
53
+ <text x="235" y="410" fill="#FF9800" font-size="10">read/write</text>
54
+ <text x="650" y="410" fill="#F44336" font-size="10">read/write</text>
55
+
56
+ <!-- Key benefit -->
57
+ <rect x="300" y="520" width="300" height="60" fill="rgba(76, 175, 80, 0.1)" stroke="#4CAF50" stroke-width="2" rx="5"/>
58
+ <text x="450" y="545" text-anchor="middle" fill="#4CAF50" font-size="13" font-weight="bold">Knowledge Sharing:</text>
59
+ <text x="450" y="565" text-anchor="middle" fill="#B0B0B0" font-size="11">All robots see all memories</text>
60
+ </svg>
61
+
62
+ !!! info "Related ADR"
63
+ See [ADR-004: Multi-Robot Shared Memory (Hive Mind)](adrs/004-hive-mind.md) for the complete architectural decision record.
64
+
65
+ ## Why Hive Mind?
66
+
67
+ ### Problems with Isolated Memory
68
+
69
+ When each robot has independent memory:
70
+
71
+ - Users repeat information across robots
72
+ - Context lost when switching robots
73
+ - No cross-robot learning
74
+ - Fragmented conversation history
75
+ - Architectural decisions made by one robot unknown to others
76
+
77
+ ### Benefits of Shared Memory
78
+
79
+ With the hive mind architecture:
80
+
81
+ - **Context continuity**: User never repeats themselves
82
+ - **Cross-robot learning**: Knowledge compounds across agents
83
+ - **Seamless switching**: Switch robots without losing context
84
+ - **Unified knowledge base**: Single source of truth
85
+ - **Collaborative development**: Robots build on each other's work
86
+
87
+ !!! success "User Experience"
88
+ With shared memory, users can switch from a code helper to a research assistant without explaining the project context again. The research assistant already knows what the code helper learned.
89
+
90
+ ## Architecture Design
91
+
92
+ ### Memory Topology
93
+
94
+ HTM uses a hybrid memory topology:
95
+
96
+ - **Long-Term Memory**: Shared globally across all robots
97
+ - **Working Memory**: Per-robot, process-local
98
+
99
+ <svg viewBox="0 0 800 500" xmlns="http://www.w3.org/2000/svg" style="background: transparent;">
100
+ <!-- Title -->
101
+ <text x="400" y="30" text-anchor="middle" fill="#E0E0E0" font-size="16" font-weight="bold">Memory Topology: Shared LTM + Local WM</text>
102
+
103
+ <!-- Legend -->
104
+ <rect x="50" y="50" width="20" height="20" fill="rgba(156, 39, 176, 0.3)" stroke="#9C27B0"/>
105
+ <text x="80" y="65" fill="#B0B0B0" font-size="12">Shared (Global)</text>
106
+ <rect x="200" y="50" width="20" height="20" fill="rgba(33, 150, 243, 0.3)" stroke="#2196F3"/>
107
+ <text x="230" y="65" fill="#B0B0B0" font-size="12">Per-Robot (Local)</text>
108
+
109
+ <!-- Robot 1 -->
110
+ <g transform="translate(0, 100)">
111
+ <text x="150" y="0" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 1 (Process 1)</text>
112
+ <rect x="50" y="20" width="200" height="80" fill="rgba(33, 150, 243, 0.2)" stroke="#2196F3" stroke-width="2" rx="5"/>
113
+ <text x="150" y="50" text-anchor="middle" fill="#E0E0E0" font-size="12">Working Memory</text>
114
+ <text x="150" y="70" text-anchor="middle" fill="#B0B0B0" font-size="10">In-memory, token-limited</text>
115
+ <text x="150" y="85" text-anchor="middle" fill="#B0B0B0" font-size="10">Independent</text>
116
+ </g>
117
+
118
+ <!-- Robot 2 -->
119
+ <g transform="translate(300, 100)">
120
+ <text x="150" y="0" text-anchor="middle" fill="#E0E0E0" font-size="14" font-weight="bold">Robot 2 (Process 2)</text>
121
+ <rect x="50" y="20" width="200" height="80" fill="rgba(33, 150, 243, 0.2)" stroke="#2196F3" stroke-width="2" rx="5"/>
122
+ <text x="150" y="50" text-anchor="middle" fill="#E0E0E0" font-size="12">Working Memory</text>
123
+ <text x="150" y="70" text-anchor="middle" fill="#B0B0B0" font-size="10">In-memory, token-limited</text>
124
+ <text x="150" y="85" text-anchor="middle" fill="#B0B0B0" font-size="10">Independent</text>
125
+ </g>
126
+
127
+ <!-- Shared Long-Term Memory -->
128
+ <rect x="150" y="280" width="500" height="150" fill="rgba(156, 39, 176, 0.2)" stroke="#9C27B0" stroke-width="3" rx="5"/>
129
+ <text x="400" y="310" text-anchor="middle" fill="#E0E0E0" font-size="16" font-weight="bold">Long-Term Memory (Shared)</text>
130
+ <text x="400" y="340" text-anchor="middle" fill="#B0B0B0" font-size="12">PostgreSQL</text>
131
+ <text x="400" y="365" text-anchor="middle" fill="#B0B0B0" font-size="12">All robots read/write here</text>
132
+ <text x="400" y="390" text-anchor="middle" fill="#B0B0B0" font-size="12">Memories attributed with robot_id</text>
133
+ <text x="400" y="410" text-anchor="middle" fill="#4CAF50" font-size="12" font-weight="bold">Single Source of Truth</text>
134
+
135
+ <!-- Connections -->
136
+ <line x1="150" y1="200" x2="300" y2="280" stroke="#9C27B0" stroke-width="2" marker-end="url(#arrow-purple)"/>
137
+ <line x1="450" y1="200" x2="400" y2="280" stroke="#9C27B0" stroke-width="2" marker-end="url(#arrow-purple)"/>
138
+
139
+ <text x="225" y="240" fill="#9C27B0" font-size="10">read/write</text>
140
+ <text x="425" y="240" fill="#9C27B0" font-size="10">read/write</text>
141
+
142
+ <defs>
143
+ <marker id="arrow-purple" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
144
+ <polygon points="0 0, 10 3, 0 6" fill="#9C27B0"/>
145
+ </marker>
146
+ </defs>
147
+
148
+ <!-- Key Point -->
149
+ <rect x="100" y="460" width="600" height="30" fill="rgba(76, 175, 80, 0.1)" stroke="#4CAF50" stroke-width="1" rx="3"/>
150
+ <text x="400" y="480" text-anchor="middle" fill="#4CAF50" font-size="12">Each robot has fast local cache (WM) + access to global knowledge (LTM)</text>
151
+ </svg>
152
+
153
+ ### Why This Design?
154
+
155
+ **Shared Long-Term Memory:**
156
+
157
+ - Global knowledge base accessible to all robots
158
+ - Cross-robot context continuity
159
+ - Simplified architecture (single database)
160
+ - Unified search across all conversations
161
+
162
+ **Per-Robot Working Memory:**
163
+
164
+ - Fast O(1) local access without network overhead
165
+ - Process isolation (no distributed state synchronization)
166
+ - Independent token budgets per robot
167
+ - Simple implementation (Ruby Hash, no Redis needed)
168
+
169
+ !!! warning "Design Trade-off"
170
+ This architecture optimizes for **single-user, multi-robot** scenarios. For multi-tenant deployments, add row-level security or database sharding by tenant_id.
171
+
172
+ ## Robot Identification System
173
+
174
+ Every robot in the hive mind has a unique identity for attribution tracking and activity monitoring.
175
+
176
+ ### Dual Identifier System
177
+
178
+ HTM uses two identifiers for each robot:
179
+
180
+ #### 1. Robot ID (`robot_id`)
181
+
182
+ - **Type**: UUID v4 (RFC 4122)
183
+ - **Format**: `"f47ac10b-58cc-4372-a567-0e02b2c3d479"`
184
+ - **Generation**: `SecureRandom.uuid` if not provided
185
+ - **Purpose**: Primary key, foreign key references, attribution
186
+ - **Uniqueness**: Guaranteed (collision probability: ~10^-36)
187
+
188
+ #### 2. Robot Name (`robot_name`)
189
+
190
+ - **Type**: String (human-readable)
191
+ - **Format**: Any descriptive string (e.g., "Code Helper", "Research Assistant")
192
+ - **Generation**: `"robot_#{robot_id[0..7]}"` if not provided
193
+ - **Purpose**: Display, debugging, logging
194
+ - **Uniqueness**: Not enforced (names can collide)
195
+
196
+ ### Robot Initialization
197
+
198
+ ```ruby
199
+ # Option 1: Auto-generated identity (ephemeral robot)
200
+ htm = HTM.new(robot_name: "Code Helper")
201
+ # robot_id: auto-generated UUID (new each session)
202
+ # robot_name: "Code Helper"
203
+
204
+ # Option 2: Persistent identity (stable robot)
205
+ ROBOT_ID = ENV['ROBOT_ID'] || "f47ac10b-58cc-4372-a567-0e02b2c3d479"
206
+ htm = HTM.new(
207
+ robot_id: ROBOT_ID,
208
+ robot_name: "Code Helper"
209
+ )
210
+ # robot_id: same across sessions
211
+ # robot_name: "Code Helper"
212
+
213
+ # Option 3: Minimal (auto-generate everything)
214
+ htm = HTM.new
215
+ # robot_id: auto-generated UUID
216
+ # robot_name: "robot_f47ac10b" (derived from UUID)
217
+ ```
218
+
219
+ !!! tip "Persistent vs Ephemeral Robots"
220
+ - **Ephemeral**: New UUID every session. Useful for testing or one-off tasks.
221
+ - **Persistent**: Store robot_id in config/environment. Recommended for production robots with stable identities.
222
+
223
+ ### Robot Registry
224
+
225
+ All robots are registered in the `robots` table on first initialization:
226
+
227
+ ```sql
228
+ CREATE TABLE robots (
229
+ id TEXT PRIMARY KEY, -- robot_id (UUID)
230
+ name TEXT, -- robot_name (human-readable)
231
+ created_at TIMESTAMP DEFAULT NOW(),
232
+ last_active TIMESTAMP DEFAULT NOW(),
233
+ metadata JSONB -- future extensibility
234
+ );
235
+ ```
236
+
237
+ **Registration flow:**
238
+
239
+ ```ruby
240
+ def register_robot
241
+ @long_term_memory.register_robot(@robot_id, @robot_name)
242
+ end
243
+
244
+ # SQL: UPSERT semantics
245
+ # INSERT INTO robots (id, name) VALUES ($1, $2)
246
+ # ON CONFLICT (id) DO UPDATE
247
+ # SET name = $2, last_active = CURRENT_TIMESTAMP
248
+ ```
249
+
250
+ !!! info "Related ADR"
251
+ See [ADR-008: Robot Identification System](adrs/008-robot-identification.md) for detailed design decisions.
252
+
253
+ ## Memory Attribution
254
+
255
+ Every memory node stores the `robot_id` of the robot that created it, enabling attribution tracking and analysis.
256
+
257
+ ### Attribution Schema
258
+
259
+ ```sql
260
+ CREATE TABLE nodes (
261
+ id BIGSERIAL PRIMARY KEY,
262
+ key TEXT UNIQUE NOT NULL,
263
+ value TEXT NOT NULL,
264
+ robot_id TEXT NOT NULL REFERENCES robots(id), -- Attribution!
265
+ ...
266
+ );
267
+
268
+ -- Index for robot-specific queries
269
+ CREATE INDEX idx_nodes_robot_id ON nodes(robot_id);
270
+ ```
271
+
272
+ ### Attribution Tracking
273
+
274
+ When a robot adds a memory:
275
+
276
+ ```ruby
277
+ def add_node(key, value, ...)
278
+ # Store with attribution
279
+ node_id = @long_term_memory.add(
280
+ key: key,
281
+ value: value,
282
+ robot_id: @robot_id, # Attribution
283
+ ...
284
+ )
285
+ end
286
+ ```
287
+
288
+ ### Attribution Queries
289
+
290
+ #### Which robot said this?
291
+
292
+ ```ruby
293
+ def which_robot_said(topic, limit: 100)
294
+ results = @long_term_memory.search_fulltext(
295
+ timeframe: (Time.at(0)..Time.now),
296
+ query: topic,
297
+ limit: limit
298
+ )
299
+
300
+ results.group_by { |n| n['robot_id'] }
301
+ .transform_values(&:count)
302
+ end
303
+
304
+ # Example usage
305
+ breakdown = htm.which_robot_said("PostgreSQL")
306
+ # => { "robot-abc123" => 15, "robot-xyz789" => 8 }
307
+
308
+ # Get robot names
309
+ breakdown.map do |robot_id, count|
310
+ robot = db.query("SELECT name FROM robots WHERE id = $1", [robot_id]).first
311
+ "#{robot['name']}: #{count} mentions"
312
+ end
313
+ # => ["Code Helper: 15 mentions", "Research Bot: 8 mentions"]
314
+ ```
315
+
316
+ #### Conversation timeline
317
+
318
+ ```ruby
319
+ def conversation_timeline(topic, limit: 50)
320
+ results = @long_term_memory.search_fulltext(
321
+ timeframe: (Time.at(0)..Time.now),
322
+ query: topic,
323
+ limit: limit
324
+ )
325
+
326
+ results.sort_by { |n| n['created_at'] }
327
+ .map { |n| {
328
+ timestamp: n['created_at'],
329
+ robot: n['robot_id'],
330
+ content: n['value'],
331
+ type: n['type']
332
+ }}
333
+ end
334
+
335
+ # Example usage
336
+ timeline = htm.conversation_timeline("HTM design", limit: 20)
337
+ # => [
338
+ # { timestamp: "2025-10-20 10:00:00", robot: "robot-abc123", content: "Let's use PostgreSQL", ... },
339
+ # { timestamp: "2025-10-20 10:15:00", robot: "robot-xyz789", content: "I agree, TimescaleDB is perfect", ... },
340
+ # ...
341
+ # ]
342
+ ```
343
+
344
+ #### Robot activity
345
+
346
+ ```sql
347
+ -- Which robots have been active?
348
+ SELECT id, name, last_active
349
+ FROM robots
350
+ ORDER BY last_active DESC;
351
+
352
+ -- Which robot contributed most memories?
353
+ SELECT r.name, COUNT(n.id) as memory_count
354
+ FROM robots r
355
+ LEFT JOIN nodes n ON n.robot_id = r.id
356
+ GROUP BY r.id, r.name
357
+ ORDER BY memory_count DESC;
358
+
359
+ -- What has a specific robot been doing?
360
+ SELECT operation, created_at, details
361
+ FROM operations_log
362
+ WHERE robot_id = 'robot-abc123'
363
+ ORDER BY created_at DESC
364
+ LIMIT 50;
365
+ ```
366
+
367
+ ## Cross-Robot Knowledge Sharing
368
+
369
+ The power of the hive mind lies in automatic knowledge sharing across robots.
370
+
371
+ ### Use Case 1: Cross-Session Context
372
+
373
+ A user works with Robot A in one session, then Robot B in another session. Robot B automatically knows what Robot A learned.
374
+
375
+ ```ruby
376
+ # Session 1 - Robot A (Code Helper)
377
+ htm_a = HTM.new(robot_id: "robot-abc123", robot_name: "Code Helper A")
378
+ htm_a.add_node(
379
+ "user_pref_001",
380
+ "User prefers debug_me over puts for debugging",
381
+ type: :preference,
382
+ importance: 9.0
383
+ )
384
+ # Stored in long-term memory with robot_id: "robot-abc123"
385
+
386
+ # === User logs out, logs in next day ===
387
+
388
+ # Session 2 - Robot B (different process, same or different machine)
389
+ htm_b = HTM.new(robot_id: "robot-xyz789", robot_name: "Code Helper B")
390
+
391
+ # Robot B recalls preferences
392
+ memories = htm_b.recall(timeframe: "last week", topic: "debugging preference")
393
+ # => Finds preference from Robot A!
394
+ # => [{ "key" => "user_pref_001", "robot_id" => "robot-abc123", ... }]
395
+
396
+ # Robot B knows user preference without being told
397
+ ```
398
+
399
+ ### Use Case 2: Collaborative Development
400
+
401
+ Different robots working on different aspects of a project can build on each other's knowledge.
402
+
403
+ ```ruby
404
+ # Robot A (Architecture discussion)
405
+ htm_a = HTM.new(robot_name: "Architect Bot")
406
+ htm_a.add_node(
407
+ "decision_001",
408
+ "We decided to use PostgreSQL with TimescaleDB for HTM storage",
409
+ type: :decision,
410
+ importance: 10.0,
411
+ tags: ["architecture", "database"]
412
+ )
413
+
414
+ # Robot B (Implementation)
415
+ htm_b = HTM.new(robot_name: "Code Bot")
416
+ memories = htm_b.recall(timeframe: "today", topic: "database decision")
417
+ # => Finds architectural decision from Robot A
418
+
419
+ # Robot B implements based on Robot A's decision
420
+ htm_b.add_node(
421
+ "implementation_001",
422
+ "Implemented Database class with ConnectionPool for PostgreSQL",
423
+ type: :code,
424
+ importance: 7.0,
425
+ related_to: ["decision_001"], # Link to Robot A's decision
426
+ tags: ["implementation", "database"]
427
+ )
428
+ ```
429
+
430
+ ### Use Case 3: Multi-Robot Conversation Analysis
431
+
432
+ Analyze contributions from different robots across a conversation:
433
+
434
+ ```ruby
435
+ # Get all mentions of "TimescaleDB"
436
+ breakdown = htm.which_robot_said("TimescaleDB", limit: 100)
437
+ # => {
438
+ # "robot-abc123" => 25, # Architect Bot
439
+ # "robot-xyz789" => 12, # Code Bot
440
+ # "robot-def456" => 8 # Research Bot
441
+ # }
442
+
443
+ # Get chronological conversation
444
+ timeline = htm.conversation_timeline("TimescaleDB design", limit: 50)
445
+ # => [
446
+ # { timestamp: "2025-10-20 10:00", robot: "robot-abc123", content: "Let's explore TimescaleDB" },
447
+ # { timestamp: "2025-10-20 10:15", robot: "robot-xyz789", content: "I'll implement the connection" },
448
+ # { timestamp: "2025-10-20 10:30", robot: "robot-def456", content: "Here's the research on compression" },
449
+ # ...
450
+ # ]
451
+ ```
452
+
453
+ ## Robot Activity Tracking
454
+
455
+ HTM automatically tracks robot activity through:
456
+
457
+ ### 1. Robot Registry Updates
458
+
459
+ Every HTM operation updates the robot's `last_active` timestamp:
460
+
461
+ ```ruby
462
+ def update_robot_activity
463
+ @long_term_memory.update_robot_activity(@robot_id)
464
+ end
465
+
466
+ # SQL
467
+ # UPDATE robots
468
+ # SET last_active = CURRENT_TIMESTAMP
469
+ # WHERE id = $1
470
+ ```
471
+
472
+ ### 2. Operations Log
473
+
474
+ Every operation is logged with robot attribution:
475
+
476
+ ```ruby
477
+ def add_node(key, value, ...)
478
+ # ... add node ...
479
+
480
+ # Log operation
481
+ @long_term_memory.log_operation(
482
+ operation: 'add',
483
+ node_id: node_id,
484
+ robot_id: @robot_id,
485
+ details: { key: key, type: type }
486
+ )
487
+ end
488
+ ```
489
+
490
+ ```sql
491
+ CREATE TABLE operations_log (
492
+ id BIGSERIAL PRIMARY KEY,
493
+ timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
494
+ operation TEXT NOT NULL, -- add, retrieve, recall, forget, evict
495
+ node_id BIGINT REFERENCES nodes(id),
496
+ robot_id TEXT NOT NULL REFERENCES robots(id),
497
+ details JSONB
498
+ );
499
+ ```
500
+
501
+ ### 3. Activity Queries
502
+
503
+ ```sql
504
+ -- Active robots in last 24 hours
505
+ SELECT id, name, last_active
506
+ FROM robots
507
+ WHERE last_active > NOW() - INTERVAL '24 hours'
508
+ ORDER BY last_active DESC;
509
+
510
+ -- Operations by robot
511
+ SELECT r.name, COUNT(ol.id) as operation_count
512
+ FROM robots r
513
+ JOIN operations_log ol ON ol.robot_id = r.id
514
+ WHERE ol.timestamp > NOW() - INTERVAL '7 days'
515
+ GROUP BY r.name
516
+ ORDER BY operation_count DESC;
517
+
518
+ -- Most active robots by memory contributions
519
+ SELECT r.name, COUNT(n.id) as memory_count
520
+ FROM robots r
521
+ JOIN nodes n ON n.robot_id = r.id
522
+ WHERE n.created_at > NOW() - INTERVAL '30 days'
523
+ GROUP BY r.name
524
+ ORDER BY memory_count DESC;
525
+ ```
526
+
527
+ ## Privacy Considerations
528
+
529
+ The hive mind architecture has important privacy implications:
530
+
531
+ ### Current Design: Single-User Assumption
532
+
533
+ HTM v1 assumes a **single-user scenario** where all robots work for the same user:
534
+
535
+ - All robots see all memories
536
+ - No isolation between robots
537
+ - No access control or permissions
538
+ - Simple, performant, easy to use
539
+
540
+ !!! warning "Privacy Warning"
541
+ In the current design, **all robots can access all memories**. This is intentional for single-user scenarios but unsuitable for multi-user or multi-tenant deployments without additional security layers.
542
+
543
+ ### Future: Multi-Tenancy Support
544
+
545
+ For multi-user scenarios, consider these privacy enhancements:
546
+
547
+ #### 1. Row-Level Security (RLS)
548
+
549
+ PostgreSQL's RLS can enforce tenant isolation:
550
+
551
+ ```sql
552
+ -- Enable RLS on nodes table
553
+ ALTER TABLE nodes ENABLE ROW LEVEL SECURITY;
554
+
555
+ -- Policy: Users can only see their own tenant's nodes
556
+ CREATE POLICY tenant_isolation ON nodes
557
+ FOR ALL
558
+ TO PUBLIC
559
+ USING (tenant_id = current_setting('app.tenant_id')::TEXT);
560
+
561
+ -- Set tenant context per connection
562
+ SET app.tenant_id = 'user-123';
563
+ ```
564
+
565
+ #### 2. Robot Visibility Levels
566
+
567
+ Add visibility controls to nodes:
568
+
569
+ ```sql
570
+ ALTER TABLE nodes ADD COLUMN visibility TEXT DEFAULT 'shared';
571
+ -- Values: 'private' (robot-only), 'shared' (all robots), 'team' (robot group)
572
+
573
+ -- Private memory (only this robot)
574
+ htm.add_node("private_key", "sensitive data", visibility: :private)
575
+
576
+ -- Shared with specific robots
577
+ htm.add_node("team_key", "team data", visibility: { team: ['robot-a', 'robot-b'] })
578
+ ```
579
+
580
+ #### 3. Robot Groups/Teams
581
+
582
+ Organize robots into teams with shared memory:
583
+
584
+ ```sql
585
+ CREATE TABLE robot_teams (
586
+ id BIGSERIAL PRIMARY KEY,
587
+ name TEXT NOT NULL,
588
+ created_at TIMESTAMP DEFAULT NOW()
589
+ );
590
+
591
+ CREATE TABLE robot_team_members (
592
+ robot_id TEXT REFERENCES robots(id),
593
+ team_id BIGINT REFERENCES robot_teams(id),
594
+ PRIMARY KEY (robot_id, team_id)
595
+ );
596
+
597
+ -- Query memories by team
598
+ SELECT n.*
599
+ FROM nodes n
600
+ JOIN robot_team_members rtm ON rtm.robot_id = n.robot_id
601
+ WHERE rtm.team_id = $1;
602
+ ```
603
+
604
+ ## Performance Characteristics
605
+
606
+ ### Shared Long-Term Memory
607
+
608
+ | Aspect | Performance | Notes |
609
+ |--------|------------|-------|
610
+ | **Concurrent reads** | Excellent | PostgreSQL read scaling |
611
+ | **Concurrent writes** | Good | MVCC handles concurrent inserts |
612
+ | **Attribution queries** | Fast | Indexed on `robot_id` |
613
+ | **Cross-robot search** | Fast | Same as single-robot search |
614
+ | **Registry updates** | Minimal overhead | Simple UPDATE per operation |
615
+
616
+ ### Per-Robot Working Memory
617
+
618
+ | Aspect | Performance | Notes |
619
+ |--------|------------|-------|
620
+ | **Memory isolation** | O(1) | No synchronization needed |
621
+ | **Process independence** | Excellent | No shared state |
622
+ | **Eviction** | O(n log n) | Per-robot, doesn't affect others |
623
+ | **Context assembly** | O(n log n) | Per-robot, fast |
624
+
625
+ ### Scalability
626
+
627
+ #### Vertical Scaling
628
+
629
+ - **Database connections**: Use connection pooling (default)
630
+ - **Robot count**: Limited by database connections (~100-200 concurrent)
631
+ - **Memory size**: Each robot process uses ~1-2GB RAM for working memory
632
+
633
+ #### Horizontal Scaling
634
+
635
+ - **Multi-process**: Each robot process is independent
636
+ - **Multi-host**: All hosts share PostgreSQL database
637
+ - **Read replicas**: Route reads to replicas, writes to primary
638
+ - **Sharding**: Partition by `robot_id` or `tenant_id` for massive scale
639
+
640
+ ## Code Examples
641
+
642
+ ### Example 1: Persistent Robot with Stable Identity
643
+
644
+ ```ruby
645
+ # Store robot ID in config or environment
646
+ ROBOT_ID = ENV.fetch('ROBOT_ID', 'code-helper-001')
647
+
648
+ # Initialize with persistent identity
649
+ htm = HTM.new(
650
+ robot_id: ROBOT_ID,
651
+ robot_name: "Code Helper",
652
+ working_memory_size: 128_000
653
+ )
654
+
655
+ # Add memories (attributed to this robot)
656
+ htm.add_node("arch_decision", "Use PostgreSQL", importance: 10.0)
657
+
658
+ # All memories from this robot_id across sessions
659
+ ```
660
+
661
+ ### Example 2: Multi-Robot Collaboration
662
+
663
+ ```ruby
664
+ # Robot A: Architecture discussion
665
+ robot_a = HTM.new(robot_id: "arch-001", robot_name: "Architect")
666
+ robot_a.add_node(
667
+ "db_choice",
668
+ "PostgreSQL chosen for ACID guarantees and pgvector support",
669
+ type: :decision,
670
+ importance: 10.0
671
+ )
672
+
673
+ # Robot B: Implementation (different process, accesses same LTM)
674
+ robot_b = HTM.new(robot_id: "code-001", robot_name: "Coder")
675
+ decisions = robot_b.recall(timeframe: "today", topic: "database")
676
+ # => Finds Robot A's decision automatically
677
+
678
+ robot_b.add_node(
679
+ "db_impl",
680
+ "Implemented Database class with connection pooling",
681
+ type: :code,
682
+ related_to: ["db_choice"] # Link to Robot A's decision
683
+ )
684
+ ```
685
+
686
+ ### Example 3: Robot Activity Dashboard
687
+
688
+ ```ruby
689
+ # Get all robots and their activity
690
+ stats = {}
691
+
692
+ robots = db.query("SELECT * FROM robots ORDER BY last_active DESC")
693
+
694
+ robots.each do |robot|
695
+ # Count memories
696
+ memory_count = db.query(<<~SQL, [robot['id']]).first['count'].to_i
697
+ SELECT COUNT(*) FROM nodes WHERE robot_id = $1
698
+ SQL
699
+
700
+ # Recent operations
701
+ recent_ops = db.query(<<~SQL, [robot['id']]).to_a
702
+ SELECT operation, COUNT(*) as count
703
+ FROM operations_log
704
+ WHERE robot_id = $1 AND timestamp > NOW() - INTERVAL '7 days'
705
+ GROUP BY operation
706
+ SQL
707
+
708
+ stats[robot['name']] = {
709
+ id: robot['id'],
710
+ last_active: robot['last_active'],
711
+ total_memories: memory_count,
712
+ recent_operations: recent_ops
713
+ }
714
+ end
715
+
716
+ # Display dashboard
717
+ stats.each do |name, data|
718
+ puts "#{name} (#{data[:id]})"
719
+ puts " Last active: #{data[:last_active]}"
720
+ puts " Total memories: #{data[:total_memories]}"
721
+ puts " Recent operations:"
722
+ data[:recent_operations].each do |op|
723
+ puts " #{op['operation']}: #{op['count']}"
724
+ end
725
+ puts
726
+ end
727
+ ```
728
+
729
+ ## Related Documentation
730
+
731
+ - [Architecture Index](index.md) - System overview and component summary
732
+ - [Architecture Overview](overview.md) - Detailed architecture and data flows
733
+ - [Two-Tier Memory System](two-tier-memory.md) - Working memory and long-term memory design
734
+ - [ADR-004: Multi-Robot Shared Memory (Hive Mind)](adrs/004-hive-mind.md)
735
+ - [ADR-008: Robot Identification System](adrs/008-robot-identification.md)
736
+ - [API Reference](../api/htm.md) - Complete API documentation