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,496 @@
1
+ # ADR-006: Context Assembly Strategies
2
+
3
+ **Status**: Accepted
4
+
5
+ **Date**: 2025-10-25
6
+
7
+ **Decision Makers**: Dewayne VanHoozer, Claude (Anthropic)
8
+
9
+ ---
10
+
11
+ ## Quick Summary
12
+
13
+ HTM implements **three context assembly strategies**: recent (newest first), important (highest priority first), and balanced (importance weighted by time decay). Users choose the strategy based on their use case when preparing context for LLMs.
14
+
15
+ **Why**: Different tasks need different context. Chat needs recency, strategic planning needs importance, and general assistance benefits from a balanced approach.
16
+
17
+ **Impact**: Flexible context assembly with predictable behavior and user control, at the cost of strategy selection responsibility.
18
+
19
+ ---
20
+
21
+ ## Context
22
+
23
+ When preparing context for an LLM, working memory may contain more information than can fit within token limits. HTM needs to intelligently select which memories to include in the assembled context string.
24
+
25
+ ### Challenges in Context Assembly
26
+
27
+ - **Token limits**: LLMs have finite context windows (even with 128K working memory)
28
+ - **Relevance**: Not all memories are equally important for current task
29
+ - **Recency bias**: Recent context often more relevant, but not always
30
+ - **Priority conflicts**: Important old memories vs. less important recent ones
31
+ - **Performance**: Context assembly should be fast (< 10ms)
32
+
33
+ ### Alternative Approaches
34
+
35
+ 1. **FIFO (First-In-First-Out)**: Always include oldest memories
36
+ 2. **LIFO (Last-In-First-Out)**: Always include newest memories
37
+ 3. **Importance-only**: Sort by importance score
38
+ 4. **Recency-only**: Sort by access time
39
+ 5. **Balanced (hybrid)**: Combine importance and recency with decay function
40
+
41
+ ---
42
+
43
+ ## Decision
44
+
45
+ We will implement **three context assembly strategies**: recent, important, and balanced, allowing users to choose based on their use case.
46
+
47
+ ### Strategy Definitions
48
+
49
+ **1. Recent (`:recent`)**
50
+
51
+ - Sort by access order, most recently accessed first
52
+ - Best for: Conversational continuity, following current discussion thread
53
+ - Use case: Chat interfaces, debugging sessions, iterative development
54
+
55
+ **2. Important (`:important`)**
56
+
57
+ - Sort by importance score, highest first
58
+ - Best for: Critical information, architectural decisions, key facts
59
+ - Use case: Decision-making, strategic planning, summarization
60
+
61
+ **3. Balanced (`:balanced`)** - **Recommended Default**
62
+
63
+ - Hybrid scoring: `importance * (1.0 / (1 + recency_hours))`
64
+ - Importance weighted by time decay (1-hour half-life)
65
+ - Best for: General-purpose context assembly
66
+ - Use case: Most LLM interactions, mixed conversational + strategic context
67
+
68
+ ---
69
+
70
+ ## Rationale
71
+
72
+ ### Why Multiple Strategies?
73
+
74
+ **Different tasks need different context**:
75
+
76
+ - Chat conversation: Recent context critical for coherence
77
+ - Strategic planning: Important decisions matter more than recency
78
+ - General assistance: Balance of both
79
+
80
+ **User control over LLM context**:
81
+
82
+ - Explicit strategy selection gives predictable behavior
83
+ - No hidden heuristics or magic
84
+ - Easy to debug context issues
85
+
86
+ **Performance and simplicity**:
87
+
88
+ - All strategies are simple sorts (O(n log n))
89
+ - No ML models or complex algorithms
90
+ - Fast context assembly (< 10ms for typical working memory)
91
+
92
+ ### Decay Function Analysis
93
+
94
+ The balanced strategy uses a **1-hour half-life decay**:
95
+
96
+ ```
97
+ score = importance * (1.0 / (1 + hours))
98
+
99
+ Examples:
100
+ - Just added (0 hours): importance * 1.0 (full weight)
101
+ - 1 hour old: importance * 0.5 (half weight)
102
+ - 3 hours old: importance * 0.25 (quarter weight)
103
+ - 24 hours old: importance * 0.04 (4% weight)
104
+ ```
105
+
106
+ This means:
107
+
108
+ - Recent memories get full importance weight
109
+ - Importance decays quickly in first few hours
110
+ - Very old memories need high importance to compete
111
+
112
+ ---
113
+
114
+ ## Implementation Details
115
+
116
+ ### Context Assembly Function
117
+
118
+ ```ruby
119
+ def assemble_context(strategy:, max_tokens: nil)
120
+ max = max_tokens || @max_tokens
121
+
122
+ nodes = case strategy
123
+ when :recent
124
+ # Most recently accessed first
125
+ @access_order.reverse.map { |k| @nodes[k] }
126
+
127
+ when :important
128
+ # Highest importance first
129
+ @nodes.sort_by { |k, v| -v[:importance] }.map(&:last)
130
+
131
+ when :balanced
132
+ # Importance * recency decay (1-hour half-life)
133
+ @nodes.sort_by { |k, v|
134
+ recency_hours = (Time.now - v[:added_at]) / 3600.0
135
+ score = v[:importance] * (1.0 / (1 + recency_hours))
136
+ -score # Negate for descending sort
137
+ }.map(&:last)
138
+
139
+ else
140
+ raise ArgumentError, "Unknown strategy: #{strategy}"
141
+ end
142
+
143
+ # Build context up to token limit
144
+ context_parts = []
145
+ current_tokens = 0
146
+
147
+ nodes.each do |node|
148
+ break if current_tokens + node[:token_count] > max
149
+ context_parts << node[:value]
150
+ current_tokens += node[:token_count]
151
+ end
152
+
153
+ context_parts.join("\n\n")
154
+ end
155
+ ```
156
+
157
+ ### User API
158
+
159
+ ```ruby
160
+ # Use balanced strategy (recommended default)
161
+ context = htm.create_context(strategy: :balanced)
162
+
163
+ # Use recent for conversational continuity
164
+ context = htm.create_context(strategy: :recent, max_tokens: 4000)
165
+
166
+ # Use important for strategic decisions
167
+ context = htm.create_context(strategy: :important)
168
+ ```
169
+
170
+ ---
171
+
172
+ ## Consequences
173
+
174
+ ### Positive
175
+
176
+ - Flexible: Choose strategy based on use case
177
+ - Predictable: Clear sorting behavior, no hidden heuristics
178
+ - Fast: Simple sorting algorithms, < 10ms
179
+ - Debuggable: Easy to understand why context contains certain memories
180
+ - User control: Explicit strategy selection
181
+ - Sensible default: Balanced strategy works well for most cases
182
+ - Token-aware: Respects max_tokens limit in all strategies
183
+
184
+ ### Negative
185
+
186
+ - Strategy selection burden: User must understand differences
187
+ - No automatic optimization: Doesn't learn optimal strategy
188
+ - Decay tuning: 1-hour half-life may not suit all use cases
189
+ - No semantic clustering: Doesn't group related memories together
190
+ - Position bias: Earlier context may have more LLM influence
191
+
192
+ ### Neutral
193
+
194
+ - Importance scoring: Requires user to assign meaningful importance
195
+ - Access tracking: Recent strategy depends on access order
196
+ - Token estimation: Accuracy depends on token counting precision
197
+
198
+ ---
199
+
200
+ ## Use Cases
201
+
202
+ ### Use Case 1: Conversational Chat
203
+
204
+ ```ruby
205
+ # User having back-and-forth conversation with LLM
206
+ # Recent context is critical for coherence
207
+
208
+ context = htm.create_context(strategy: :recent, max_tokens: 8000)
209
+
210
+ # Example memories in working memory:
211
+ # - "User prefers debug_me over puts" (importance: 9, 5 days old)
212
+ # - "What is the capital of France?" (importance: 1, 2 minutes ago)
213
+ # - "Paris is the capital" (importance: 1, 1 minute ago)
214
+
215
+ # Result: Recent conversation about Paris included first,
216
+ # even though user preference is more important
217
+ ```
218
+
219
+ ### Use Case 2: Strategic Planning
220
+
221
+ ```ruby
222
+ # LLM helping with architectural decisions
223
+ # Important decisions matter more than recent chat
224
+
225
+ context = htm.create_context(strategy: :important)
226
+
227
+ # Example memories:
228
+ # - "We decided to use PostgreSQL" (importance: 10, 3 days ago)
229
+ # - "What time is it?" (importance: 1, 1 minute ago)
230
+ # - "TimescaleDB chosen for time-series" (importance: 9, 2 days ago)
231
+
232
+ # Result: Architectural decisions included first,
233
+ # time check ignored if space limited
234
+ ```
235
+
236
+ ### Use Case 3: General Assistance (Balanced)
237
+
238
+ ```ruby
239
+ # LLM helping with mixed tasks
240
+ # Balance recent context + important knowledge
241
+
242
+ context = htm.create_context(strategy: :balanced)
243
+
244
+ # Example memories:
245
+ # - "User prefers debug_me" (importance: 9, 5 days ago) → score: 0.007
246
+ # - "PostgreSQL decision" (importance: 10, 3 days ago) → score: 0.014
247
+ # - "Current debugging issue" (importance: 5, 10 minutes ago) → score: 3.0
248
+ # - "Error: foreign key violation" (importance: 7, 2 minutes ago) → score: 21.0
249
+
250
+ # Result: Recent debugging context ranked highest,
251
+ # but important decisions still included if space permits
252
+ ```
253
+
254
+ ### Use Case 4: Custom Token Limit
255
+
256
+ ```ruby
257
+ # Generate short summary for preview
258
+ short_context = htm.create_context(strategy: :important, max_tokens: 500)
259
+
260
+ # Generate full context for LLM
261
+ full_context = htm.create_context(strategy: :balanced, max_tokens: 128_000)
262
+ ```
263
+
264
+ ---
265
+
266
+ ## Performance Characteristics
267
+
268
+ ### Complexity
269
+
270
+ - **Recent**: O(n) - reverse access order array
271
+ - **Important**: O(n log n) - sort by importance
272
+ - **Balanced**: O(n log n) - sort by computed score
273
+
274
+ ### Typical Performance
275
+
276
+ - **Working memory size**: 50-200 nodes
277
+ - **Sorting time**: < 5ms (all strategies)
278
+ - **String assembly**: < 5ms
279
+ - **Total**: < 10ms for context assembly
280
+
281
+ ### Memory Usage
282
+
283
+ - **No duplication**: Nodes stored once, sorted references
284
+ - **Temporary arrays**: O(n) for sorted node references
285
+ - **Output string**: O(total_tokens) for assembled context
286
+
287
+ ---
288
+
289
+ ## Design Decisions
290
+
291
+ ### Decision: Three Strategies Instead of One
292
+
293
+ **Rationale**: Different use cases benefit from different strategies. Flexibility > simplicity.
294
+
295
+ **Alternative**: Single balanced strategy for all use cases
296
+
297
+ **Rejected**: Forces one-size-fits-all approach, limits user control
298
+
299
+ ### Decision: Balanced as Default
300
+
301
+ **Rationale**: Best general-purpose behavior, balances competing priorities
302
+
303
+ **Alternative**: Recent as default
304
+
305
+ **Rejected**: Important long-term knowledge gets lost in conversations
306
+
307
+ ### Decision: 1-Hour Decay Half-Life
308
+
309
+ **Rationale**:
310
+
311
+ - 1 hour matches typical development session length
312
+ - Quick decay prevents stale context from dominating
313
+ - Long enough to preserve within-session continuity
314
+
315
+ **Alternative**: Configurable decay parameter
316
+
317
+ **Deferred**: Can add if real-world usage shows need for tuning
318
+
319
+ ### Decision: Linear Decay (1 / (1 + hours))
320
+
321
+ **Rationale**: Simple, predictable, computationally cheap
322
+
323
+ **Alternative**: Exponential decay `exp(-λ * hours)`
324
+
325
+ **Rejected**: More complex, harder to reason about, minimal practical difference
326
+
327
+ ### Decision: Token Limit Enforced Strictly
328
+
329
+ **Rationale**: Never exceed LLM context window, prevent truncation errors
330
+
331
+ **Alternative**: Soft limit with warnings
332
+
333
+ **Rejected**: Hard limits prevent surprising behavior
334
+
335
+ ---
336
+
337
+ ## Risks and Mitigations
338
+
339
+ ### Risk: Suboptimal Decay Parameter
340
+
341
+ !!! info "Risk"
342
+ 1-hour half-life doesn't match real usage patterns
343
+
344
+ **Likelihood**: Medium (usage patterns vary)
345
+
346
+ **Impact**: Low (balanced strategy still works reasonably)
347
+
348
+ **Mitigation**:
349
+
350
+ - Monitor real-world usage patterns
351
+ - Make decay configurable if needed
352
+ - Document decay behavior clearly
353
+
354
+ ### Risk: Strategy Confusion
355
+
356
+ !!! warning "Risk"
357
+ Users don't understand which strategy to use
358
+
359
+ **Likelihood**: Medium (three choices require understanding)
360
+
361
+ **Impact**: Low (balanced default works well)
362
+
363
+ **Mitigation**:
364
+
365
+ - Clear documentation with use cases
366
+ - Examples in API docs
367
+ - Sensible default (balanced)
368
+
369
+ ### Risk: Position Bias in LLM
370
+
371
+ !!! info "Risk"
372
+ LLM pays more attention to early context
373
+
374
+ **Likelihood**: High (known LLM behavior)
375
+
376
+ **Impact**: Medium (affects which memories have most influence)
377
+
378
+ **Mitigation**:
379
+
380
+ - Document bias in user guide
381
+ - Consider reverse ordering for some LLMs (future)
382
+ - Let users experiment with strategies
383
+
384
+ ### Risk: Importance Scoring Inconsistency
385
+
386
+ !!! warning "Risk"
387
+ Users assign arbitrary importance scores
388
+
389
+ **Likelihood**: High (subjective scoring)
390
+
391
+ **Impact**: Medium (affects balanced and important strategies)
392
+
393
+ **Mitigation**:
394
+
395
+ - Document importance scoring guidelines
396
+ - Provide default importance (1.0) for most memories
397
+ - Consider learned importance in future
398
+
399
+ ---
400
+
401
+ ## Future Enhancements
402
+
403
+ ### Automatic Strategy Selection
404
+
405
+ ```ruby
406
+ # Detect conversation vs planning context
407
+ context = htm.create_context_smart()
408
+
409
+ # Uses recent for conversational turns
410
+ # Uses important for strategic questions
411
+ # Uses balanced for mixed contexts
412
+ ```
413
+
414
+ ### Configurable Decay
415
+
416
+ ```ruby
417
+ # Adjust decay half-life
418
+ context = htm.create_context(
419
+ strategy: :balanced,
420
+ decay_hours: 0.5 # Faster decay
421
+ )
422
+ ```
423
+
424
+ ### Semantic Clustering
425
+
426
+ ```ruby
427
+ # Group related memories together
428
+ context = htm.create_context(
429
+ strategy: :clustered,
430
+ cluster_by: :embedding # Group semantically related nodes
431
+ )
432
+ ```
433
+
434
+ ### LLM-Optimized Ordering
435
+
436
+ ```ruby
437
+ # Reverse ordering for LLMs with recency bias
438
+ context = htm.create_context(
439
+ strategy: :balanced,
440
+ order: :reverse # Most important last (closer to query)
441
+ )
442
+ ```
443
+
444
+ ### Multi-Factor Scoring
445
+
446
+ ```ruby
447
+ # Custom scoring function
448
+ context = htm.create_context(
449
+ strategy: :custom,
450
+ score_fn: ->(node) {
451
+ recency = Time.now - node[:added_at]
452
+ importance = node[:importance]
453
+ access_count = node[:access_count]
454
+
455
+ importance * (1.0 / (1 + recency / 3600)) * Math.log(1 + access_count)
456
+ }
457
+ )
458
+ ```
459
+
460
+ ---
461
+
462
+ ## Alternatives Comparison
463
+
464
+ | Approach | Pros | Cons | Decision |
465
+ |----------|------|------|----------|
466
+ | **Three Strategies** | **Flexible, user control** | **Selection burden** | **ACCEPTED** |
467
+ | Always Include Everything | No selection logic | Exceeds token limits | Rejected |
468
+ | LLM-Powered Selection | Most intelligent | Too slow, expensive | Rejected |
469
+ | Learned Importance | Automatic optimization | Complex, non-deterministic | Deferred |
470
+ | Semantic Similarity | Most relevant | Slower, breaks generality | Deferred |
471
+
472
+ ---
473
+
474
+ ## References
475
+
476
+ - [LLM Context Window Management](https://arxiv.org/abs/2307.03172)
477
+ - [Attention Mechanisms in LLMs](https://arxiv.org/abs/1706.03762)
478
+ - [Position Bias in Language Models](https://arxiv.org/abs/2302.00093)
479
+ - [Working Memory in Cognitive Science](https://en.wikipedia.org/wiki/Working_memory)
480
+ - [ADR-002: Two-Tier Memory](002-two-tier-memory.md)
481
+ - [ADR-007: Eviction Strategy](007-eviction-strategy.md)
482
+ - [Context Assembly Guide](../../guides/context-assembly.md)
483
+
484
+ ---
485
+
486
+ ## Review Notes
487
+
488
+ **AI Engineer**: Three strategies cover common use cases well. Balanced default is smart. Consider position bias documentation.
489
+
490
+ **Performance Specialist**: O(n log n) sorting is fast enough for typical working memory sizes. No concerns.
491
+
492
+ **Ruby Expert**: Clean API design. Consider default parameter: `create_context(strategy: :balanced)` → `create_context(strategy = :balanced)`.
493
+
494
+ **Domain Expert**: Decay function is intuitive. 1-hour half-life matches development session rhythm.
495
+
496
+ **Systems Architect**: Strategy pattern is appropriate. Document decision matrix for users.