agentfootprint 8.7.0 → 8.9.0

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 (245) hide show
  1. package/AGENTS.md +12 -4
  2. package/CLAUDE.md +7 -3
  3. package/ai-instructions/claude-code/SKILL.md +1 -1
  4. package/ai-instructions/setup.sh +0 -0
  5. package/bin/agentfootprint-lint-tools.mjs +0 -0
  6. package/dist/adapters/memory/sqliteVector.js +875 -0
  7. package/dist/adapters/memory/sqliteVector.js.map +1 -0
  8. package/dist/core/Agent.js +6 -0
  9. package/dist/core/Agent.js.map +1 -1
  10. package/dist/core/agent/buildAgentChart.js +12 -1
  11. package/dist/core/agent/buildAgentChart.js.map +1 -1
  12. package/dist/core/agent/buildDynamicAgentChart.js +12 -1
  13. package/dist/core/agent/buildDynamicAgentChart.js.map +1 -1
  14. package/dist/core/agent/memoryRecallInjections.js +100 -10
  15. package/dist/core/agent/memoryRecallInjections.js.map +1 -1
  16. package/dist/core/agent/stages/deliver.js.map +1 -1
  17. package/dist/core/slots/buildSystemPromptSlot.js +10 -0
  18. package/dist/core/slots/buildSystemPromptSlot.js.map +1 -1
  19. package/dist/core/slots/helpers.js +12 -10
  20. package/dist/core/slots/helpers.js.map +1 -1
  21. package/dist/embedders/index.js +11 -0
  22. package/dist/embedders/index.js.map +1 -1
  23. package/dist/esm/adapters/memory/sqliteVector.d.ts +251 -0
  24. package/dist/esm/adapters/memory/sqliteVector.js +869 -0
  25. package/dist/esm/adapters/memory/sqliteVector.js.map +1 -0
  26. package/dist/esm/core/Agent.js +6 -0
  27. package/dist/esm/core/Agent.js.map +1 -1
  28. package/dist/esm/core/agent/buildAgentChart.js +13 -2
  29. package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
  30. package/dist/esm/core/agent/buildDynamicAgentChart.js +13 -2
  31. package/dist/esm/core/agent/buildDynamicAgentChart.js.map +1 -1
  32. package/dist/esm/core/agent/memoryRecallInjections.d.ts +13 -3
  33. package/dist/esm/core/agent/memoryRecallInjections.js +101 -11
  34. package/dist/esm/core/agent/memoryRecallInjections.js.map +1 -1
  35. package/dist/esm/core/agent/stages/deliver.d.ts +6 -3
  36. package/dist/esm/core/agent/stages/deliver.js.map +1 -1
  37. package/dist/esm/core/slots/buildSystemPromptSlot.js +10 -0
  38. package/dist/esm/core/slots/buildSystemPromptSlot.js.map +1 -1
  39. package/dist/esm/core/slots/helpers.d.ts +11 -2
  40. package/dist/esm/core/slots/helpers.js +11 -9
  41. package/dist/esm/core/slots/helpers.js.map +1 -1
  42. package/dist/esm/embedders/index.js +11 -0
  43. package/dist/esm/embedders/index.js.map +1 -1
  44. package/dist/esm/events/payloads.d.ts +63 -0
  45. package/dist/esm/events/registry.d.ts +3 -1
  46. package/dist/esm/events/registry.js +2 -0
  47. package/dist/esm/events/registry.js.map +1 -1
  48. package/dist/esm/hosting/sqliteSessions.d.ts +7 -13
  49. package/dist/esm/hosting/sqliteSessions.js +8 -25
  50. package/dist/esm/hosting/sqliteSessions.js.map +1 -1
  51. package/dist/esm/index.d.ts +2 -1
  52. package/dist/esm/index.js +6 -1
  53. package/dist/esm/index.js.map +1 -1
  54. package/dist/esm/lib/fnv1a.d.ts +16 -0
  55. package/dist/esm/lib/fnv1a.js +24 -0
  56. package/dist/esm/lib/fnv1a.js.map +1 -0
  57. package/dist/esm/lib/injection-engine/types.d.ts +17 -0
  58. package/dist/esm/lib/injection-engine/types.js.map +1 -1
  59. package/dist/esm/lib/rag/defineRAG.d.ts +126 -26
  60. package/dist/esm/lib/rag/defineRAG.js +112 -25
  61. package/dist/esm/lib/rag/defineRAG.js.map +1 -1
  62. package/dist/esm/lib/rag/index.d.ts +1 -1
  63. package/dist/esm/lib/rag/index.js +1 -1
  64. package/dist/esm/lib/rag/index.js.map +1 -1
  65. package/dist/esm/lib/rag/indexDocuments.d.ts +26 -4
  66. package/dist/esm/lib/rag/indexDocuments.js +12 -1
  67. package/dist/esm/lib/rag/indexDocuments.js.map +1 -1
  68. package/dist/esm/lib/sqliteUnavailable.d.ts +55 -0
  69. package/dist/esm/lib/sqliteUnavailable.js +61 -0
  70. package/dist/esm/lib/sqliteUnavailable.js.map +1 -0
  71. package/dist/esm/memory/define.js +38 -2
  72. package/dist/esm/memory/define.js.map +1 -1
  73. package/dist/esm/memory/define.types.d.ts +93 -1
  74. package/dist/esm/memory/define.types.js +18 -0
  75. package/dist/esm/memory/define.types.js.map +1 -1
  76. package/dist/esm/memory/embedding/embedMessages.js +16 -0
  77. package/dist/esm/memory/embedding/embedMessages.js.map +1 -1
  78. package/dist/esm/memory/embedding/emitEmbedding.d.ts +38 -0
  79. package/dist/esm/memory/embedding/emitEmbedding.js +15 -0
  80. package/dist/esm/memory/embedding/emitEmbedding.js.map +1 -0
  81. package/dist/esm/memory/embedding/loadRelevant.d.ts +49 -15
  82. package/dist/esm/memory/embedding/loadRelevant.js +150 -7
  83. package/dist/esm/memory/embedding/loadRelevant.js.map +1 -1
  84. package/dist/esm/memory/embedding/mockEmbedder.js +4 -0
  85. package/dist/esm/memory/embedding/mockEmbedder.js.map +1 -1
  86. package/dist/esm/memory/embedding/types.d.ts +24 -0
  87. package/dist/esm/memory/index.d.ts +2 -1
  88. package/dist/esm/memory/index.js +2 -1
  89. package/dist/esm/memory/index.js.map +1 -1
  90. package/dist/esm/memory/pipeline/semantic.d.ts +15 -0
  91. package/dist/esm/memory/pipeline/semantic.js +3 -1
  92. package/dist/esm/memory/pipeline/semantic.js.map +1 -1
  93. package/dist/esm/memory/retrieval/index.d.ts +10 -0
  94. package/dist/esm/memory/retrieval/index.js +3 -0
  95. package/dist/esm/memory/retrieval/index.js.map +1 -0
  96. package/dist/esm/memory/retrieval/provenance.d.ts +43 -0
  97. package/dist/esm/memory/retrieval/provenance.js +60 -0
  98. package/dist/esm/memory/retrieval/provenance.js.map +1 -0
  99. package/dist/esm/memory/retrieval/topK.d.ts +67 -0
  100. package/dist/esm/memory/retrieval/topK.js +53 -0
  101. package/dist/esm/memory/retrieval/topK.js.map +1 -0
  102. package/dist/esm/memory/retrieval/types.d.ts +189 -0
  103. package/dist/esm/memory/retrieval/types.js +2 -0
  104. package/dist/esm/memory/retrieval/types.js.map +1 -0
  105. package/dist/esm/memory/stages/formatDefault.d.ts +52 -26
  106. package/dist/esm/memory/stages/formatDefault.js +118 -28
  107. package/dist/esm/memory/stages/formatDefault.js.map +1 -1
  108. package/dist/esm/memory/stages/pickByBudget.js +53 -3
  109. package/dist/esm/memory/stages/pickByBudget.js.map +1 -1
  110. package/dist/esm/memory/stages/types.d.ts +15 -0
  111. package/dist/esm/memory/wire/mountMemoryPipeline.d.ts +25 -0
  112. package/dist/esm/memory/wire/mountMemoryPipeline.js +11 -2
  113. package/dist/esm/memory/wire/mountMemoryPipeline.js.map +1 -1
  114. package/dist/esm/memory-providers.d.ts +2 -0
  115. package/dist/esm/memory-providers.js +8 -0
  116. package/dist/esm/memory-providers.js.map +1 -1
  117. package/dist/esm/observe.d.ts +2 -0
  118. package/dist/esm/observe.js +2 -0
  119. package/dist/esm/observe.js.map +1 -1
  120. package/dist/esm/recorders/core/EmbeddingRecorder.d.ts +19 -0
  121. package/dist/esm/recorders/core/EmbeddingRecorder.js +24 -0
  122. package/dist/esm/recorders/core/EmbeddingRecorder.js.map +1 -0
  123. package/dist/events/registry.js +2 -0
  124. package/dist/events/registry.js.map +1 -1
  125. package/dist/hosting/sqliteSessions.js +10 -27
  126. package/dist/hosting/sqliteSessions.js.map +1 -1
  127. package/dist/index.js +8 -1
  128. package/dist/index.js.map +1 -1
  129. package/dist/lib/fnv1a.js +28 -0
  130. package/dist/lib/fnv1a.js.map +1 -0
  131. package/dist/lib/injection-engine/types.js.map +1 -1
  132. package/dist/lib/rag/defineRAG.js +113 -26
  133. package/dist/lib/rag/defineRAG.js.map +1 -1
  134. package/dist/lib/rag/index.js +2 -1
  135. package/dist/lib/rag/index.js.map +1 -1
  136. package/dist/lib/rag/indexDocuments.js +12 -1
  137. package/dist/lib/rag/indexDocuments.js.map +1 -1
  138. package/dist/lib/sqliteUnavailable.js +65 -0
  139. package/dist/lib/sqliteUnavailable.js.map +1 -0
  140. package/dist/memory/define.js +38 -2
  141. package/dist/memory/define.js.map +1 -1
  142. package/dist/memory/define.types.js +21 -1
  143. package/dist/memory/define.types.js.map +1 -1
  144. package/dist/memory/embedding/embedMessages.js +16 -0
  145. package/dist/memory/embedding/embedMessages.js.map +1 -1
  146. package/dist/memory/embedding/emitEmbedding.js +19 -0
  147. package/dist/memory/embedding/emitEmbedding.js.map +1 -0
  148. package/dist/memory/embedding/loadRelevant.js +152 -8
  149. package/dist/memory/embedding/loadRelevant.js.map +1 -1
  150. package/dist/memory/embedding/mockEmbedder.js +4 -0
  151. package/dist/memory/embedding/mockEmbedder.js.map +1 -1
  152. package/dist/memory/index.js +5 -1
  153. package/dist/memory/index.js.map +1 -1
  154. package/dist/memory/pipeline/semantic.js +2 -0
  155. package/dist/memory/pipeline/semantic.js.map +1 -1
  156. package/dist/memory/retrieval/index.js +9 -0
  157. package/dist/memory/retrieval/index.js.map +1 -0
  158. package/dist/memory/retrieval/provenance.js +65 -0
  159. package/dist/memory/retrieval/provenance.js.map +1 -0
  160. package/dist/memory/retrieval/topK.js +57 -0
  161. package/dist/memory/retrieval/topK.js.map +1 -0
  162. package/dist/memory/retrieval/types.js +3 -0
  163. package/dist/memory/retrieval/types.js.map +1 -0
  164. package/dist/memory/stages/formatDefault.js +118 -28
  165. package/dist/memory/stages/formatDefault.js.map +1 -1
  166. package/dist/memory/stages/pickByBudget.js +53 -3
  167. package/dist/memory/stages/pickByBudget.js.map +1 -1
  168. package/dist/memory/wire/mountMemoryPipeline.js +11 -2
  169. package/dist/memory/wire/mountMemoryPipeline.js.map +1 -1
  170. package/dist/memory-providers.js +13 -1
  171. package/dist/memory-providers.js.map +1 -1
  172. package/dist/observe.js +4 -1
  173. package/dist/observe.js.map +1 -1
  174. package/dist/recorders/core/EmbeddingRecorder.js +28 -0
  175. package/dist/recorders/core/EmbeddingRecorder.js.map +1 -0
  176. package/dist/types/adapters/memory/sqliteVector.d.ts +252 -0
  177. package/dist/types/adapters/memory/sqliteVector.d.ts.map +1 -0
  178. package/dist/types/core/Agent.d.ts.map +1 -1
  179. package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
  180. package/dist/types/core/agent/buildDynamicAgentChart.d.ts.map +1 -1
  181. package/dist/types/core/agent/memoryRecallInjections.d.ts +13 -3
  182. package/dist/types/core/agent/memoryRecallInjections.d.ts.map +1 -1
  183. package/dist/types/core/agent/stages/deliver.d.ts +6 -3
  184. package/dist/types/core/agent/stages/deliver.d.ts.map +1 -1
  185. package/dist/types/core/slots/buildSystemPromptSlot.d.ts.map +1 -1
  186. package/dist/types/core/slots/helpers.d.ts +11 -2
  187. package/dist/types/core/slots/helpers.d.ts.map +1 -1
  188. package/dist/types/embedders/index.d.ts.map +1 -1
  189. package/dist/types/events/payloads.d.ts +63 -0
  190. package/dist/types/events/payloads.d.ts.map +1 -1
  191. package/dist/types/events/registry.d.ts +3 -1
  192. package/dist/types/events/registry.d.ts.map +1 -1
  193. package/dist/types/hosting/sqliteSessions.d.ts +7 -13
  194. package/dist/types/hosting/sqliteSessions.d.ts.map +1 -1
  195. package/dist/types/index.d.ts +2 -1
  196. package/dist/types/index.d.ts.map +1 -1
  197. package/dist/types/lib/fnv1a.d.ts +17 -0
  198. package/dist/types/lib/fnv1a.d.ts.map +1 -0
  199. package/dist/types/lib/injection-engine/types.d.ts +17 -0
  200. package/dist/types/lib/injection-engine/types.d.ts.map +1 -1
  201. package/dist/types/lib/rag/defineRAG.d.ts +126 -26
  202. package/dist/types/lib/rag/defineRAG.d.ts.map +1 -1
  203. package/dist/types/lib/rag/index.d.ts +1 -1
  204. package/dist/types/lib/rag/index.d.ts.map +1 -1
  205. package/dist/types/lib/rag/indexDocuments.d.ts +26 -4
  206. package/dist/types/lib/rag/indexDocuments.d.ts.map +1 -1
  207. package/dist/types/lib/sqliteUnavailable.d.ts +56 -0
  208. package/dist/types/lib/sqliteUnavailable.d.ts.map +1 -0
  209. package/dist/types/memory/define.d.ts.map +1 -1
  210. package/dist/types/memory/define.types.d.ts +93 -1
  211. package/dist/types/memory/define.types.d.ts.map +1 -1
  212. package/dist/types/memory/embedding/embedMessages.d.ts.map +1 -1
  213. package/dist/types/memory/embedding/emitEmbedding.d.ts +39 -0
  214. package/dist/types/memory/embedding/emitEmbedding.d.ts.map +1 -0
  215. package/dist/types/memory/embedding/loadRelevant.d.ts +49 -15
  216. package/dist/types/memory/embedding/loadRelevant.d.ts.map +1 -1
  217. package/dist/types/memory/embedding/mockEmbedder.d.ts.map +1 -1
  218. package/dist/types/memory/embedding/types.d.ts +24 -0
  219. package/dist/types/memory/embedding/types.d.ts.map +1 -1
  220. package/dist/types/memory/index.d.ts +2 -1
  221. package/dist/types/memory/index.d.ts.map +1 -1
  222. package/dist/types/memory/pipeline/semantic.d.ts +15 -0
  223. package/dist/types/memory/pipeline/semantic.d.ts.map +1 -1
  224. package/dist/types/memory/retrieval/index.d.ts +11 -0
  225. package/dist/types/memory/retrieval/index.d.ts.map +1 -0
  226. package/dist/types/memory/retrieval/provenance.d.ts +44 -0
  227. package/dist/types/memory/retrieval/provenance.d.ts.map +1 -0
  228. package/dist/types/memory/retrieval/topK.d.ts +68 -0
  229. package/dist/types/memory/retrieval/topK.d.ts.map +1 -0
  230. package/dist/types/memory/retrieval/types.d.ts +190 -0
  231. package/dist/types/memory/retrieval/types.d.ts.map +1 -0
  232. package/dist/types/memory/stages/formatDefault.d.ts +52 -26
  233. package/dist/types/memory/stages/formatDefault.d.ts.map +1 -1
  234. package/dist/types/memory/stages/pickByBudget.d.ts.map +1 -1
  235. package/dist/types/memory/stages/types.d.ts +15 -0
  236. package/dist/types/memory/stages/types.d.ts.map +1 -1
  237. package/dist/types/memory/wire/mountMemoryPipeline.d.ts +25 -0
  238. package/dist/types/memory/wire/mountMemoryPipeline.d.ts.map +1 -1
  239. package/dist/types/memory-providers.d.ts +2 -0
  240. package/dist/types/memory-providers.d.ts.map +1 -1
  241. package/dist/types/observe.d.ts +2 -0
  242. package/dist/types/observe.d.ts.map +1 -1
  243. package/dist/types/recorders/core/EmbeddingRecorder.d.ts +20 -0
  244. package/dist/types/recorders/core/EmbeddingRecorder.d.ts.map +1 -0
  245. package/package.json +1 -1
package/AGENTS.md CHANGED
@@ -137,16 +137,24 @@ const docs = defineRAG({
137
137
  id: 'product-docs',
138
138
  store, embedder,
139
139
  topK: 3,
140
- threshold: 0.7, // STRICT — no fallback when nothing matches
140
+ threshold: 0.7, // STRICT — nothing is injected when nothing matches
141
141
  });
142
- // Retrieved chunks land in the SYSTEM-PROMPT slot, as one system message.
142
+ // Retrieved chunks land in the SYSTEM-PROMPT slot, as one system message
143
+ // of citable `<source id=… doc=… score=…>` blocks.
143
144
  // `asRole` was removed in 7.20.0 — it was never read, and passing it throws.
144
145
 
145
146
  // Wire to agent — `.rag()` is an alias for `.memory()`, same plumbing
146
147
  agent.rag(docs);
148
+
149
+ // No identity argument anywhere: a corpus lives in its own namespace
150
+ // (`corpus`, default `{ conversationId: '_global' }`) — the same one
151
+ // indexDocuments writes to.
152
+ await agent.run({ message: 'How long do refunds take?' });
147
153
  ```
148
154
 
149
- `defineRAG` is sugar over `defineMemory({ type: SEMANTIC, strategy: TOP_K })`. Same plumbing, different intent: RAG = document corpus retrieval; `defineMemory` = conversation/run-state memory.
155
+ `defineRAG` runs on `defineMemory({ type: SEMANTIC, strategy: TOP_K })`. Same machinery, three deliberate differences: a corpus is **read-only** (it never stores the conversation), it reads under its **own namespace** rather than the run's identity, and its chunks render as **citable `<source>` blocks**. For conversation memory alongside a corpus, register both — `.rag(defineRAG(...))` and `.memory(defineMemory(...))`, each with its own store.
156
+
157
+ **Why did the agent read this passage?** `agentfootprint.memory.retrieved` carries every candidate with its score — including the ones that were rejected and why. `agentfootprint.memory.attached` fires per chunk that reached the prompt. `agentfootprint.context.injected` reports `source: 'rag'` with that chunk's `retrievalScore` / `rankPosition` / `threshold`. The whole record is on root state as `retrievalEvidence_<id>`, where a backward slice can reach it.
150
158
 
151
159
  ### Agent (ReAct primitive)
152
160
 
@@ -464,7 +472,7 @@ Resilience decorators live on the `agentfootprint/resilience` subpath
464
472
  (not the main barrel). Each preserves the `LLMProvider` interface and
465
473
  stacks freely.
466
474
 
467
- ### Observability — 71 typed events across 20 domains
475
+ ### Observability — 72 typed events across 20 domains
468
476
 
469
477
  ```typescript
470
478
  agent.on('agentfootprint.context.injected', (e) =>
package/CLAUDE.md CHANGED
@@ -13,11 +13,11 @@ Entry points (package.json exports): `.` core API · `/observe` ALL observabilit
13
13
  | core/slots/ | the 3 context-slot subflow builders + thinking subflow — intentionally NOT exported |
14
14
  | core-flow/ | Sequence/Parallel/Conditional/Loop — RunnerBase subclasses with own charts |
15
15
  | patterns/ | Debate/MapReduce/Reflection/SelfConsistency/Swarm/ToT — pure composition of runners, no new control flow |
16
- | adapters/ | hexagonal ports (types.ts = ALL port interfaces) + vendor impls (llm/, memory/, identity/, observability/) |
16
+ | adapters/ | hexagonal ports (types.ts = ALL port interfaces) + vendor impls (llm/, memory/, identity/, observability/). memory/sqliteVector.ts (8.9.0) = the only FULL MemoryStore we ship with `search` besides InMemoryStore — exact cosine over a resident Float32Array matrix, hydrated per namespace on first search and dropped on any write to it |
17
17
  | recorders/core/ | bridges footprintjs events → typed EventDispatcher (ContextRecorder, EmitBridge, typedEmit) — auto-attached by Agent.createExecutor; most factories also exported via `/observe` for manual wiring (EmitBridge itself stays internal) |
18
18
  | recorders/observability/ | consumer recorders over the typed stream (RunStepRecorder, FlowchartRecorder, Status, Trace replay) + `recordRun` — THE producer of a recording `{snapshot, events, structure}` (the shape lens's `observeRecording` consumes; `structure` = `getSpec().buildTimeStructure`, which no snapshot carries). Anything that saves a run goes through it |
19
19
  | lib/ | first-party sub-libraries: injection-engine/, context-bisect/ (localizeContextBug, toBacktrackTrace + sliceToBacktrackTrace — the atui board serializers), influence-core/, trace-toolpack/ (selfExplain; 6 tools incl. variable-first `backtrack(variable, element?)`), context-ledger/ (which pieces EARNED their tokens — post-run offers/uses/outcomes bookkeeping + demote-never-starve gates `ledgerToolGate`/`ledgerEntryScorer`/`ledgerGated`; grouped-mode folds sf-llm-call inner logs, unmeterable runs → undefined; /observe), mcp/, rag/, tool-lint/ |
20
- | memory/ | store/ (MemoryStore port) + pipeline presets + stages + beats/facts + causal/ (dev-only, TOP_K+search()-only) + wire/mountMemoryPipeline |
20
+ | memory/ | store/ (MemoryStore port) + pipeline presets + stages + beats/facts + causal/ (dev-only, TOP_K+search()-only) + wire/mountMemoryPipeline + retrieval/ (8.8.0: the `RetrievalStrategy` seam + `RetrievalEvidence`, the record a retrieval leaves — `topK()` is what every earlier release did unnamed) |
21
21
  | events/ | EventDispatcher (wildcard subs), registry (EVENT_NAMES, AgentfootprintEventMap), payloads |
22
22
  | conventions.ts | THE builder↔recorder protocol: SUBFLOW_IDS/STAGE_IDS (internal), INJECTION_KEYS/stageRole/milestoneFor (exported, Lens-facing) |
23
23
 
@@ -39,6 +39,8 @@ Traps: `src/observability/` holds the finder IMPLEMENTATIONS (canonical home; `d
39
39
  - **New typed event (3-step)**: payload interface in events/payloads.ts + entry in `AgentfootprintEventMap` (registry.ts:198) + append to `ALL_EVENT_TYPES` (registry.ts:488, count-asserted by tests). New DOMAIN also needs a bridge attach in Agent.createExecutor or emits never reach the dispatcher — AND a hand-edit to `DomainWildcard` (dispatcher.ts:67-82; already missing validation/credential/reliability).
40
40
  - **Strategy (vendor sink)**: shapes in strategies/types.ts (Observability :130, Cost :169, LiveStatus :201, Lens :234); attach via `agent.enable.*` or `registerObservabilityStrategy` (strategies/registry.ts). New vendor = export from observability-providers.ts, NOT a new subpath.
41
41
  - **Memory store**: implement `MemoryStore` (memory/store/types.ts:113; `search?` REQUIRED for causal memory); pass to `defineMemory({store})`. Memory TYPE/STRATEGY unions are CLOSED (define.types.ts:57/74 — new one edits defineMemory dispatch + a pipeline builder).
42
+ - **Durable store** (8.9.0): `sqliteVectorStore` follows `hosting/sqliteSessions` line for line — lazy `node:sqlite`, WAL read-back on `journalMode`, STRICT tables, schema-identity + schema-version refusals, `':memory:'` refused. TWO things it adds that have no precedent there: `putMany`/`putIfVersion`/`forget` wrap in a transaction (sqliteSessions has none), and the EMBEDDER FINGERPRINT (`'<id>@<dims>'`, one per namespace in `af_index_meta`) is refused at write AND query. `SqliteUnavailableError` is now ONE class in `lib/sqliteUnavailable.ts` re-exported by both doors — a second class of that name is a duplicate type the build refuses.
43
+ - **Retrieval rule** (8.8.0): implement `RetrievalStrategy` (memory/retrieval/types.ts) — `select(pool) → verdict[]`, one verdict per candidate, order preserved; it never touches the store and never embeds. Pass as `defineRAG({retrieval})`. `topK()` is the only shipped one; rerank/MMR are named-but-deferred adapters behind the same interface. `TopKStrategy` is a UNION whose arms exclude (`{topK,threshold}` vs `{retrieval}`) — refused in the type AND at runtime, because two spellings of one rule can disagree.
42
44
  - **Injection/skill**: `Injection = {id, flavor, trigger, inject}` (lib/injection-engine/types.ts:161); trigger is a closed 4-variant union (:30 — new kind edits evaluator.ts:40-74 switch). Factories defineSkill etc.; skill graph via `skillGraph()` (skillGraph.ts:392) with pluggable `EntryScorer` (entryScorer.ts:64). `SkillGraphConfig` is a UNION (flat arm `start`/`steps` vs tree arm) — the contradictions it encodes are ALSO refused at build (`.tree()` + `.entry()`/`.route()`, a non-leaf in `skills[]` under a tree, two skills claiming one id, a second `.skillGraph()` on one agent).
43
45
  - **Ports table** (wired via AgentOptions): PermissionChecker (adapters/types.ts:403), PricingTable (:412), CredentialProvider (identity/types.ts:89), CacheStrategy (cache/types.ts:151, registerCacheStrategy), ThinkingHandler (thinking/types.ts:114 — auto-wire scans HARDCODED SHIPPED_THINKING_HANDLERS, registry.ts:26), ReliabilityConfig (reliability/types.ts:183), OutputSchemaParser (core/outputSchema.ts:62, duck-typed).
44
46
  - **Output contract** (7.26): `.outputSchema(parser, opts)` — `retries>0` mounts the THIRD Route branch (`STAGE_IDS.OUTPUT_RETRY`, same `{loopTo}` as tool-calls) + swaps the decider for `buildEnforcingDecider` (stages/route.ts); `strategy:'tool-forced'` builds the synthetic tool (core/agent/outputEnforcement.ts) that callLLM appends at REQUEST assembly and normalizes back into `content` inside `singleProviderCall` — it never touches the tools slot, the registry or the dispatcher. TWO build refusals (agent has tools; no derivable jsonSchema) + ONE run-start refusal (`provider.carriesForcedToolChoice`; ABSENCE = NO, the opposite of carriesInMessages). A new wire capability = adapters/types.ts + 6 adapters + 3 resilience wrappers (withFallback publishes the AND).
@@ -49,8 +51,10 @@ Traps: `src/observability/` holds the finder IMPLEMENTATIONS (canonical home; `d
49
51
  ## Change-impact map
50
52
  - **conventions.ts** (STAGE_IDS/SUBFLOW_IDS/INJECTION_KEYS) → chart builders that mount by id, ContextRecorder slot attribution, localizer loop-head detection (lib/context-bisect/trajectory.ts:17-33), `stageRole`/`milestoneFor` (Lens contract), BoundaryRecorder. Renaming an id is the whole blast radius.
51
53
  - **BoundaryRecorder wiring is THREE connections, all at record time**: `runner.attach` (boundaries), `.subscribe(runner)` (what's inside them), `{getCommitCount}` (where each sits on the commit axis). The third fails SILENTLY — every event stamps `commitIdxBefore: 0`, `boundaryIndex` stays empty by design, and an offline step strip has nothing to place. Unrecoverable after the run (the commit log never records WHEN a boundary was crossed). Wired by `attachFlowchart` (which `enable.flowchart`/`enable.localObservability` both go through) and by `recordRun`; a new entry point must pass all three.
54
+ - **Embedder fingerprint** (8.9.0) → `Embedder.id` (optional; every shipped embedder sets one, and NONE include dims — the store appends `@<dims>` itself, so an id carrying its own size double-stamps) + `indexDocuments` defaulting `embedderId` to it + `SqliteVectorStore.reconcileFingerprint` (the only comparison site). Rule: dimensions ALWAYS decide, model ids decide only when BOTH sides named themselves — refusing on an absent name would block the majority of callers who never pass `embedderId`.
55
+ - **Retrieval record** (8.8.0) → FOUR stages write one object in sequence: `loadRelevant` (candidates+scores+threshold verdicts) → `pickByBudget` (re-marks admitted→over-budget/over-max-entries) → `formatDefault` (`promptFragment` + `promptPosition`) → the read mount's outputMapper lifts it to root as `retrievalEvidence_<id>`. `memoryRecallInjections` then splits ONE recall into one ActiveInjection PER CHUNK — guarded by a byte-equality check (`fragments.join('\n\n') === systemContent`) that falls back to the single injection rather than change the prompt. `rank` (score order) and `promptPosition` (picker order) are DIFFERENT and both load-bearing: joining fragments in rank order reproduces the right bytes in a sequence the model never saw.
52
56
  - **AgentState** → all 8 stages/ files, both builders' mappers, memory-wire STRING-TYPED keys ('runIdentity'/'turnNumber'/… buildAgentChart.ts:177-180 — not refactor-safe), finalizeResult's `reliabilityFail*`/`policyHalt*` reads (rename silently kills the typed errors).
53
- - **events/** → 71 typed events across 20 domains (counts anti-drift-tested against this file — update BOTH when adding events): ALL_EVENT_TYPES exhaustiveness tests, DomainWildcard hand-list, ~42 importers (recorders, strategies, stream, commentary).
57
+ - **events/** → 72 typed events across 20 domains (counts anti-drift-tested against this file — update BOTH when adding events): ALL_EVENT_TYPES exhaustiveness tests, DomainWildcard hand-list, ~42 importers (recorders, strategies, stream, commentary).
54
58
  - **adapters/types.ts LLMMessage/LLMRequest** → 62 importers: tool_use round-trip (toolCalls.ts:115-135), wire assembly (callLLM.ts:150-160), providers, cache strategies, security/extractSequence, reliability loop.
55
59
  - **Cache** → strategy registration is a MODULE SIDE EFFECT (src/index.ts:15-17); an entry point skipping that import silently falls back to NoOp. Resolved once per Agent at construction (Agent.ts:347).
56
60
  - **Injection engine eval semantics** → Evaluate stage cursor keystone (buildInjectionEngineSubflow.ts:214-222), Route stage MIRRORS slot filters (keep in sync with buildSystemPromptSlot), read_skill gate (toolCalls.ts:747). The gate's allowed set is TWO kinds of id (8.4.0): a HOP (`deps.allowedSkillIds` = `graph.reachableSkills(cursor)` — activates AND moves the cursor) ∪ an OPEN skill (`deps.openSkillIds` = `Agent.openSkillIds()`, Agent.ts:1052 — a registered skill whose trigger is `llm-activated` AND that the graph declares no incoming edge to; activates, never moves the cursor). Both clauses are load-bearing: the trigger test is "read_skill can really activate this", the edge test keeps a bare model edge `.route(a,m)` from-gated. **8.5.0** extends the SAME trigger test three ways: a decision `tree()` returns `[]` from `reachableSkills` (leaves compile to `rule` triggers, so a pick could only be accepted then dropped — the gate refuses with a tree-specific message, `deps.skillGraphIsTree`, derived in AgentBuilder from `graph.nodes.some(kind==='predicate')`); `surfaceMode:'tool-only'` is refused at agent build for any skill whose trigger is not `llm-activated` (skillBodyDelivery.ts — the read_skill tool result is the only channel that mode has, and the graph never calls read_skill); and `read_skill`'s DESCRIPTION is rebuilt per iteration from `reachableSkills(cursor) ∪ open` (Agent.readSkillOfferFor → buildToolsSlot's `readSkillFor`). **The read_skill ENUM must stay the full catalog** — `toolArgValidation` defaults to `'enforce'` and runs at toolCalls.ts:570, BEFORE the gate at :765, and sets `error = true` which the gate skips; narrowing the enum silently retires the teaching refusal, `skill.rejected`, routeRecorder's rejection hops and the rejected-cap governor.
@@ -379,7 +379,7 @@ if (isPaused(result)) {
379
379
  }
380
380
  ```
381
381
 
382
- ## Observability — 71 typed events × 20 domains
382
+ ## Observability — 72 typed events × 20 domains
383
383
 
384
384
  ```typescript
385
385
  agent.on('agentfootprint.context.injected', (e) =>
File without changes
File without changes