agent-recall-core 3.4.30 → 3.4.35

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 (251) hide show
  1. package/README.md +121 -441
  2. package/dist/digest/store.d.ts.map +1 -1
  3. package/dist/digest/store.js +4 -3
  4. package/dist/digest/store.js.map +1 -1
  5. package/dist/display/board-render.d.ts +61 -0
  6. package/dist/display/board-render.d.ts.map +1 -0
  7. package/dist/display/board-render.js +223 -0
  8. package/dist/display/board-render.js.map +1 -0
  9. package/dist/helpers/alignment-patterns.d.ts +10 -0
  10. package/dist/helpers/alignment-patterns.d.ts.map +1 -1
  11. package/dist/helpers/alignment-patterns.js +5 -1
  12. package/dist/helpers/alignment-patterns.js.map +1 -1
  13. package/dist/helpers/blind-spots.d.ts +86 -0
  14. package/dist/helpers/blind-spots.d.ts.map +1 -0
  15. package/dist/helpers/blind-spots.js +205 -0
  16. package/dist/helpers/blind-spots.js.map +1 -0
  17. package/dist/helpers/conflict-scan.d.ts +10 -0
  18. package/dist/helpers/conflict-scan.d.ts.map +1 -1
  19. package/dist/helpers/conflict-scan.js +3 -3
  20. package/dist/helpers/conflict-scan.js.map +1 -1
  21. package/dist/helpers/semantic-match.d.ts +82 -0
  22. package/dist/helpers/semantic-match.d.ts.map +1 -0
  23. package/dist/helpers/semantic-match.js +229 -0
  24. package/dist/helpers/semantic-match.js.map +1 -0
  25. package/dist/index.d.ts +52 -11
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +48 -9
  28. package/dist/index.js.map +1 -1
  29. package/dist/palace/awareness.d.ts +30 -0
  30. package/dist/palace/awareness.d.ts.map +1 -1
  31. package/dist/palace/awareness.js +65 -2
  32. package/dist/palace/awareness.js.map +1 -1
  33. package/dist/palace/consolidate.d.ts.map +1 -1
  34. package/dist/palace/consolidate.js +17 -0
  35. package/dist/palace/consolidate.js.map +1 -1
  36. package/dist/palace/decay-pass.d.ts +46 -0
  37. package/dist/palace/decay-pass.d.ts.map +1 -0
  38. package/dist/palace/decay-pass.js +87 -0
  39. package/dist/palace/decay-pass.js.map +1 -0
  40. package/dist/palace/insights-index.d.ts.map +1 -1
  41. package/dist/palace/insights-index.js +4 -2
  42. package/dist/palace/insights-index.js.map +1 -1
  43. package/dist/palace/skills.d.ts +41 -2
  44. package/dist/palace/skills.d.ts.map +1 -1
  45. package/dist/palace/skills.js +106 -4
  46. package/dist/palace/skills.js.map +1 -1
  47. package/dist/prompts/consolidation-prompt.d.ts +25 -0
  48. package/dist/prompts/consolidation-prompt.d.ts.map +1 -0
  49. package/dist/prompts/consolidation-prompt.js +91 -0
  50. package/dist/prompts/consolidation-prompt.js.map +1 -0
  51. package/dist/storage/archive-prune.d.ts +56 -0
  52. package/dist/storage/archive-prune.d.ts.map +1 -0
  53. package/dist/storage/archive-prune.js +118 -0
  54. package/dist/storage/archive-prune.js.map +1 -0
  55. package/dist/storage/archive-write.d.ts +38 -0
  56. package/dist/storage/archive-write.d.ts.map +1 -0
  57. package/dist/storage/archive-write.js +98 -0
  58. package/dist/storage/archive-write.js.map +1 -0
  59. package/dist/storage/blind-spots-store.d.ts +30 -0
  60. package/dist/storage/blind-spots-store.d.ts.map +1 -0
  61. package/dist/storage/blind-spots-store.js +91 -0
  62. package/dist/storage/blind-spots-store.js.map +1 -0
  63. package/dist/storage/capture-router.d.ts +60 -0
  64. package/dist/storage/capture-router.d.ts.map +1 -0
  65. package/dist/storage/capture-router.js +133 -0
  66. package/dist/storage/capture-router.js.map +1 -0
  67. package/dist/storage/classification.d.ts +32 -0
  68. package/dist/storage/classification.d.ts.map +1 -0
  69. package/dist/storage/classification.js +74 -0
  70. package/dist/storage/classification.js.map +1 -0
  71. package/dist/storage/consolidation-queue.d.ts +39 -0
  72. package/dist/storage/consolidation-queue.d.ts.map +1 -0
  73. package/dist/storage/consolidation-queue.js +120 -0
  74. package/dist/storage/consolidation-queue.js.map +1 -0
  75. package/dist/storage/content-guard.d.ts +74 -0
  76. package/dist/storage/content-guard.d.ts.map +1 -0
  77. package/dist/storage/content-guard.js +179 -0
  78. package/dist/storage/content-guard.js.map +1 -0
  79. package/dist/storage/corrections.d.ts +246 -21
  80. package/dist/storage/corrections.d.ts.map +1 -1
  81. package/dist/storage/corrections.js +605 -56
  82. package/dist/storage/corrections.js.map +1 -1
  83. package/dist/storage/durable-intent.d.ts +49 -0
  84. package/dist/storage/durable-intent.d.ts.map +1 -0
  85. package/dist/storage/durable-intent.js +124 -0
  86. package/dist/storage/durable-intent.js.map +1 -0
  87. package/dist/storage/filelock.d.ts +6 -0
  88. package/dist/storage/filelock.d.ts.map +1 -1
  89. package/dist/storage/filelock.js +6 -1
  90. package/dist/storage/filelock.js.map +1 -1
  91. package/dist/storage/memory-protocol.d.ts +19 -0
  92. package/dist/storage/memory-protocol.d.ts.map +1 -0
  93. package/dist/storage/memory-protocol.js +101 -0
  94. package/dist/storage/memory-protocol.js.map +1 -0
  95. package/dist/storage/paths.d.ts +23 -0
  96. package/dist/storage/paths.d.ts.map +1 -1
  97. package/dist/storage/paths.js +39 -0
  98. package/dist/storage/paths.js.map +1 -1
  99. package/dist/storage/retention.d.ts +23 -0
  100. package/dist/storage/retention.d.ts.map +1 -0
  101. package/dist/storage/retention.js +48 -0
  102. package/dist/storage/retention.js.map +1 -0
  103. package/dist/storage/session.d.ts +2 -2
  104. package/dist/storage/session.d.ts.map +1 -1
  105. package/dist/storage/session.js +11 -1
  106. package/dist/storage/session.js.map +1 -1
  107. package/dist/supabase/config.d.ts +8 -0
  108. package/dist/supabase/config.d.ts.map +1 -1
  109. package/dist/supabase/config.js +5 -0
  110. package/dist/supabase/config.js.map +1 -1
  111. package/dist/supabase/recall-backend.d.ts +1 -0
  112. package/dist/supabase/recall-backend.d.ts.map +1 -1
  113. package/dist/supabase/recall-backend.js +13 -13
  114. package/dist/supabase/recall-backend.js.map +1 -1
  115. package/dist/supabase/sync.d.ts.map +1 -1
  116. package/dist/supabase/sync.js +30 -3
  117. package/dist/supabase/sync.js.map +1 -1
  118. package/dist/tools-logic/bootstrap.d.ts +15 -0
  119. package/dist/tools-logic/bootstrap.d.ts.map +1 -1
  120. package/dist/tools-logic/bootstrap.js +238 -47
  121. package/dist/tools-logic/bootstrap.js.map +1 -1
  122. package/dist/tools-logic/brief.d.ts +84 -0
  123. package/dist/tools-logic/brief.d.ts.map +1 -0
  124. package/dist/tools-logic/brief.js +193 -0
  125. package/dist/tools-logic/brief.js.map +1 -0
  126. package/dist/tools-logic/check-action.d.ts +9 -0
  127. package/dist/tools-logic/check-action.d.ts.map +1 -1
  128. package/dist/tools-logic/check-action.js +31 -2
  129. package/dist/tools-logic/check-action.js.map +1 -1
  130. package/dist/tools-logic/check.d.ts +7 -0
  131. package/dist/tools-logic/check.d.ts.map +1 -1
  132. package/dist/tools-logic/check.js +24 -2
  133. package/dist/tools-logic/check.js.map +1 -1
  134. package/dist/tools-logic/confidence.d.ts +50 -0
  135. package/dist/tools-logic/confidence.d.ts.map +1 -0
  136. package/dist/tools-logic/confidence.js +70 -0
  137. package/dist/tools-logic/confidence.js.map +1 -0
  138. package/dist/tools-logic/drill-down.d.ts +37 -0
  139. package/dist/tools-logic/drill-down.d.ts.map +1 -0
  140. package/dist/tools-logic/drill-down.js +63 -0
  141. package/dist/tools-logic/drill-down.js.map +1 -0
  142. package/dist/tools-logic/export-corrections.d.ts +63 -0
  143. package/dist/tools-logic/export-corrections.d.ts.map +1 -0
  144. package/dist/tools-logic/export-corrections.js +124 -0
  145. package/dist/tools-logic/export-corrections.js.map +1 -0
  146. package/dist/tools-logic/journal-capture.d.ts.map +1 -1
  147. package/dist/tools-logic/journal-capture.js +4 -1
  148. package/dist/tools-logic/journal-capture.js.map +1 -1
  149. package/dist/tools-logic/journal-write.d.ts.map +1 -1
  150. package/dist/tools-logic/journal-write.js +3 -2
  151. package/dist/tools-logic/journal-write.js.map +1 -1
  152. package/dist/tools-logic/memory-query.d.ts +10 -3
  153. package/dist/tools-logic/memory-query.d.ts.map +1 -1
  154. package/dist/tools-logic/memory-query.js +31 -7
  155. package/dist/tools-logic/memory-query.js.map +1 -1
  156. package/dist/tools-logic/mirror-builder.d.ts +115 -0
  157. package/dist/tools-logic/mirror-builder.d.ts.map +1 -0
  158. package/dist/tools-logic/mirror-builder.js +348 -0
  159. package/dist/tools-logic/mirror-builder.js.map +1 -0
  160. package/dist/tools-logic/palace-write.d.ts.map +1 -1
  161. package/dist/tools-logic/palace-write.js +3 -2
  162. package/dist/tools-logic/palace-write.js.map +1 -1
  163. package/dist/tools-logic/pipeline-close.d.ts.map +1 -1
  164. package/dist/tools-logic/pipeline-close.js +2 -1
  165. package/dist/tools-logic/pipeline-close.js.map +1 -1
  166. package/dist/tools-logic/pipeline-open.d.ts.map +1 -1
  167. package/dist/tools-logic/pipeline-open.js +2 -1
  168. package/dist/tools-logic/pipeline-open.js.map +1 -1
  169. package/dist/tools-logic/predict-correction.d.ts +47 -0
  170. package/dist/tools-logic/predict-correction.d.ts.map +1 -0
  171. package/dist/tools-logic/predict-correction.js +137 -0
  172. package/dist/tools-logic/predict-correction.js.map +1 -0
  173. package/dist/tools-logic/prior-builder.d.ts +27 -0
  174. package/dist/tools-logic/prior-builder.d.ts.map +1 -0
  175. package/dist/tools-logic/prior-builder.js +57 -0
  176. package/dist/tools-logic/prior-builder.js.map +1 -0
  177. package/dist/tools-logic/recognition-builder.d.ts +116 -0
  178. package/dist/tools-logic/recognition-builder.d.ts.map +1 -0
  179. package/dist/tools-logic/recognition-builder.js +289 -0
  180. package/dist/tools-logic/recognition-builder.js.map +1 -0
  181. package/dist/tools-logic/safety-consolidation.d.ts +104 -0
  182. package/dist/tools-logic/safety-consolidation.d.ts.map +1 -0
  183. package/dist/tools-logic/safety-consolidation.js +256 -0
  184. package/dist/tools-logic/safety-consolidation.js.map +1 -0
  185. package/dist/tools-logic/session-end-reflect.d.ts +18 -0
  186. package/dist/tools-logic/session-end-reflect.d.ts.map +1 -1
  187. package/dist/tools-logic/session-end-reflect.js +68 -29
  188. package/dist/tools-logic/session-end-reflect.js.map +1 -1
  189. package/dist/tools-logic/session-end.d.ts +9 -0
  190. package/dist/tools-logic/session-end.d.ts.map +1 -1
  191. package/dist/tools-logic/session-end.js +111 -13
  192. package/dist/tools-logic/session-end.js.map +1 -1
  193. package/dist/tools-logic/session-start-lite.d.ts +2 -0
  194. package/dist/tools-logic/session-start-lite.d.ts.map +1 -1
  195. package/dist/tools-logic/session-start-lite.js +10 -0
  196. package/dist/tools-logic/session-start-lite.js.map +1 -1
  197. package/dist/tools-logic/session-start.d.ts +46 -0
  198. package/dist/tools-logic/session-start.d.ts.map +1 -1
  199. package/dist/tools-logic/session-start.js +96 -3
  200. package/dist/tools-logic/session-start.js.map +1 -1
  201. package/dist/tools-logic/skill-propose.d.ts +27 -0
  202. package/dist/tools-logic/skill-propose.d.ts.map +1 -0
  203. package/dist/tools-logic/skill-propose.js +66 -0
  204. package/dist/tools-logic/skill-propose.js.map +1 -0
  205. package/dist/tools-logic/skill-recall.d.ts +5 -0
  206. package/dist/tools-logic/skill-recall.d.ts.map +1 -1
  207. package/dist/tools-logic/skill-recall.js +14 -1
  208. package/dist/tools-logic/skill-recall.js.map +1 -1
  209. package/dist/tools-logic/smart-recall.d.ts +17 -0
  210. package/dist/tools-logic/smart-recall.d.ts.map +1 -1
  211. package/dist/tools-logic/smart-recall.js +51 -16
  212. package/dist/tools-logic/smart-recall.js.map +1 -1
  213. package/dist/tools-logic/store-doctor.d.ts +71 -0
  214. package/dist/tools-logic/store-doctor.d.ts.map +1 -0
  215. package/dist/tools-logic/store-doctor.js +387 -0
  216. package/dist/tools-logic/store-doctor.js.map +1 -0
  217. package/dist/tools-logic/store-repair.d.ts +64 -0
  218. package/dist/tools-logic/store-repair.d.ts.map +1 -0
  219. package/dist/tools-logic/store-repair.js +243 -0
  220. package/dist/tools-logic/store-repair.js.map +1 -0
  221. package/dist/tools-logic/supersession.d.ts +34 -0
  222. package/dist/tools-logic/supersession.d.ts.map +1 -0
  223. package/dist/tools-logic/supersession.js +103 -0
  224. package/dist/tools-logic/supersession.js.map +1 -0
  225. package/dist/types.d.ts +7 -1
  226. package/dist/types.d.ts.map +1 -1
  227. package/dist/types.js +1 -1
  228. package/dist/vector/local-vector-backend.d.ts.map +1 -1
  229. package/dist/vector/local-vector-backend.js +14 -17
  230. package/dist/vector/local-vector-backend.js.map +1 -1
  231. package/package.json +9 -1
  232. package/dist/relevance/injector.d.ts +0 -51
  233. package/dist/relevance/injector.d.ts.map +0 -1
  234. package/dist/relevance/injector.js +0 -121
  235. package/dist/relevance/injector.js.map +0 -1
  236. package/dist/relevance/precision.d.ts +0 -109
  237. package/dist/relevance/precision.d.ts.map +0 -1
  238. package/dist/relevance/precision.js +0 -279
  239. package/dist/relevance/precision.js.map +0 -1
  240. package/dist/relevance/promoter.d.ts +0 -60
  241. package/dist/relevance/promoter.d.ts.map +0 -1
  242. package/dist/relevance/promoter.js +0 -336
  243. package/dist/relevance/promoter.js.map +0 -1
  244. package/dist/relevance/stager.d.ts +0 -61
  245. package/dist/relevance/stager.d.ts.map +0 -1
  246. package/dist/relevance/stager.js +0 -251
  247. package/dist/relevance/stager.js.map +0 -1
  248. package/dist/relevance/surfacer.d.ts +0 -34
  249. package/dist/relevance/surfacer.d.ts.map +0 -1
  250. package/dist/relevance/surfacer.js +0 -333
  251. package/dist/relevance/surfacer.js.map +0 -1
@@ -0,0 +1,179 @@
1
+ /**
2
+ * content-guard.ts — pre-sync content scrubbing for opt-in cloud users.
3
+ *
4
+ * Applied BEFORE any journalWrite → syncToSupabase call so that secrets and
5
+ * prompt-injection attempts do not reach Supabase or the embedding API.
6
+ *
7
+ * Two-layer scrub:
8
+ * 1. scrubPromptInjection — strip XML system-marker tags, bidi overrides,
9
+ * null bytes, and explicit injection phrases. Extracted from bootstrap.ts
10
+ * and re-exported here so journal-write/palace-write can import from a
11
+ * single source of truth.
12
+ * 2. scrubSecretContent — redact known secret token prefixes (AKIA…, ghp_…,
13
+ * gho_…, ghs_…, sk-…, xoxb-…, PEM markers). Operates on content, not
14
+ * filenames (bootstrap.ts isSecretFile() handles filename-level rejection).
15
+ *
16
+ * scrubForCloud(content) = scrubSecretContent(scrubPromptInjection(content))
17
+ *
18
+ * Design guarantees:
19
+ * - Never throws — any failure returns the original content unchanged.
20
+ * - Pure function, no I/O, no Supabase imports.
21
+ * - Returns a SecretScanResult so callers can log/block if desired.
22
+ *
23
+ * Usage: call scrubForCloud(content) in journal-write.ts and palace-write.ts
24
+ * before passing content to syncToSupabase.
25
+ */
26
+ // ---------------------------------------------------------------------------
27
+ // Layer 1 — prompt-injection scrub (re-export from bootstrap logic)
28
+ // ---------------------------------------------------------------------------
29
+ /**
30
+ * Strip prompt-injection patterns from content before it leaves the machine.
31
+ * Same logic as bootstrap.ts:scrubPromptInjection but exported here for
32
+ * journal-write and palace-write to use at sync time.
33
+ */
34
+ export function scrubPromptInjection(s) {
35
+ try {
36
+ return s
37
+ .replace(/<\/?\s*(system[-_]?(reminder|prompt|message|instruction)|important|critical)\b[^>]*>/gi, "[stripped tag]")
38
+ .replace(/<\|im_(start|end)\|>/gi, "[stripped]")
39
+ .replace(/\b(ignore|disregard|forget)\s+(all\s+)?(previous|prior|above)\s+(instructions?|prompts?|messages?)/gi, "[stripped injection attempt]")
40
+ .replace(/[‪-‮⁦-⁩]/g, "") // bidi override chars
41
+ .replace(/\0/g, ""); // null bytes
42
+ }
43
+ catch {
44
+ return s;
45
+ }
46
+ }
47
+ // ---------------------------------------------------------------------------
48
+ // Layer 2 — content-level secret scan
49
+ // ---------------------------------------------------------------------------
50
+ /**
51
+ * Patterns that match known secret token prefixes / PEM markers in CONTENT.
52
+ * Complements isSecretFile() in bootstrap.ts which tests filenames only.
53
+ *
54
+ * Prefix list (grounding: packages/core/src/supabase/sync.ts risk analysis):
55
+ * AKIA… — AWS access key
56
+ * ghp_… — GitHub personal access token
57
+ * gho_… — GitHub OAuth token
58
+ * ghs_… — GitHub app installation token
59
+ * sk-… — OpenAI / Anthropic secret key (≥20 chars to avoid false-positives)
60
+ * xoxb-… — Slack bot token
61
+ * xoxp-… — Slack user token
62
+ * -----BEGIN … KEY/CERTIFICATE— PEM markers
63
+ */
64
+ // NOTE: generic `Authorization: Bearer <jwt>` is intentionally NOT scanned here.
65
+ // JWTs are short-lived and the pattern has a very high false-positive rate on
66
+ // normal journal content. This is a documented scope decision, not a silent gap.
67
+ const SECRET_CONTENT_PATTERNS = [
68
+ { re: /\bAKIA[0-9A-Z]{16,}\b/g, label: "AWS access key" },
69
+ { re: /\bghp_[A-Za-z0-9_]{20,}\b/g, label: "GitHub PAT (ghp_)" },
70
+ { re: /\bgho_[A-Za-z0-9_]{20,}\b/g, label: "GitHub OAuth token (gho_)" },
71
+ { re: /\bghs_[A-Za-z0-9_]{20,}\b/g, label: "GitHub app token (ghs_)" },
72
+ { re: /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g, label: "GitHub fine-grained PAT (github_pat_)" },
73
+ { re: /\bghr_[A-Za-z0-9]{20,}\b/g, label: "GitHub refresh token (ghr_)" },
74
+ { re: /\bsk-[A-Za-z0-9\-_]{20,}\b/g, label: "OpenAI/Anthropic secret key (sk-)" },
75
+ { re: /\bxoxb-[A-Za-z0-9\-]{20,}\b/g, label: "Slack bot token (xoxb-)" },
76
+ { re: /\bxoxp-[A-Za-z0-9\-]{20,}\b/g, label: "Slack user token (xoxp-)" },
77
+ { re: /\bnpm_[A-Za-z0-9]{20,}\b/g, label: "npm registry token" },
78
+ { re: /_authToken=[^\s"'\r\n]{8,}/g, label: "npm _authToken (.npmrc)" },
79
+ {
80
+ re: /-----BEGIN\s+(?:RSA |EC |DSA |OPENSSH |ENCRYPTED )?(?:PRIVATE KEY|CERTIFICATE)-----[\s\S]*?-----END\s+(?:RSA |EC |DSA |OPENSSH |ENCRYPTED )?(?:PRIVATE KEY|CERTIFICATE)-----/g,
81
+ label: "PEM private key/certificate block",
82
+ },
83
+ ];
84
+ const REDACTED_PLACEHOLDER = "[REDACTED-SECRET]";
85
+ /**
86
+ * Scan content for known secret token patterns and redact them in-place.
87
+ * Returns the redacted content and a count of how many matches were replaced.
88
+ */
89
+ export function scrubSecretContent(content) {
90
+ try {
91
+ let result = content;
92
+ let redactedCount = 0;
93
+ const labels = [];
94
+ for (const { re, label } of SECRET_CONTENT_PATTERNS) {
95
+ // Reset lastIndex for global regexes (they carry state across calls if reused).
96
+ re.lastIndex = 0;
97
+ const matches = result.match(re);
98
+ if (matches && matches.length > 0) {
99
+ re.lastIndex = 0;
100
+ result = result.replace(re, REDACTED_PLACEHOLDER);
101
+ redactedCount += matches.length;
102
+ labels.push(label);
103
+ }
104
+ }
105
+ return { content: result, redactedCount, labels };
106
+ }
107
+ catch {
108
+ // Never throw — return original content on error.
109
+ return { content, redactedCount: 0, labels: [] };
110
+ }
111
+ }
112
+ // ---------------------------------------------------------------------------
113
+ // Composite scrub — the single call site for journal-write / palace-write
114
+ // ---------------------------------------------------------------------------
115
+ /**
116
+ * scrubForCloud(content) applies both layers in order:
117
+ * 1. scrubPromptInjection — removes injection/override attempts
118
+ * 2. scrubSecretContent — redacts known secret token patterns
119
+ *
120
+ * Returns the sanitised string. Never throws.
121
+ */
122
+ export function scrubForCloud(content) {
123
+ try {
124
+ const afterInjection = scrubPromptInjection(content);
125
+ const { content: afterSecrets } = scrubSecretContent(afterInjection);
126
+ return afterSecrets;
127
+ }
128
+ catch {
129
+ return content;
130
+ }
131
+ }
132
+ // ---------------------------------------------------------------------------
133
+ // Fail-CLOSED export scrub — for deliberate egress (e.g. `ar corrections export`)
134
+ // ---------------------------------------------------------------------------
135
+ /**
136
+ * Raised by scrubForExport when a secret survives scrubbing. Distinct error type
137
+ * so callers can abort an export and name the offending record.
138
+ */
139
+ export class SecretScanError extends Error {
140
+ label;
141
+ constructor(label) {
142
+ super(`secret survived export scrub (${label}) — refusing to emit`);
143
+ this.label = label;
144
+ this.name = "SecretScanError";
145
+ }
146
+ }
147
+ /**
148
+ * scrubForExport(content) — the fail-CLOSED sibling of scrubForCloud.
149
+ *
150
+ * scrubForCloud is fail-OPEN: on any internal error it returns the ORIGINAL
151
+ * content unchanged, which is the right call on the sync hot-path (never block a
152
+ * write) but the WRONG call for a deliberate export that will be handed to an
153
+ * external store. scrubForExport adds a post-condition: it re-scans the scrubbed
154
+ * output and THROWS SecretScanError if any known secret pattern still matches —
155
+ * so a redaction that silently failed open aborts the export instead of leaking.
156
+ *
157
+ * Use this for every string that leaves AgentRecall via an export/adapter path.
158
+ */
159
+ export function scrubForExport(content) {
160
+ const scrubbed = scrubForCloud(content);
161
+ // Fail-CLOSED post-condition. Re-scan the OUTPUT with the secret patterns
162
+ // DIRECTLY — not via scrubSecretContent(), whose own try/catch returns
163
+ // redactedCount:0 on an internal error and would silently re-open the fail-open
164
+ // hole this function exists to close. A bare re.test() here lets any regex-engine
165
+ // error propagate and abort the export rather than leak.
166
+ //
167
+ // Under scrubForCloud's current contract a successful scrub leaves no residue,
168
+ // so this never fires on normal input — it is a defense-in-depth guard that trips
169
+ // only if scrubForCloud fails open (its outer catch returns the original) or its
170
+ // redaction contract regresses. Either way: refuse to emit.
171
+ for (const { re, label } of SECRET_CONTENT_PATTERNS) {
172
+ re.lastIndex = 0;
173
+ if (re.test(scrubbed)) {
174
+ throw new SecretScanError(label);
175
+ }
176
+ }
177
+ return scrubbed;
178
+ }
179
+ //# sourceMappingURL=content-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-guard.js","sourceRoot":"","sources":["../../src/storage/content-guard.ts"],"names":[],"mappings":"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"}
@@ -30,12 +30,63 @@ export interface CorrectionRecord {
30
30
  /** Set when retractCorrection() soft-deletes this record. */
31
31
  retracted_at?: string;
32
32
  retract_reason?: string;
33
+ /**
34
+ * Wave 5 — corrections-prediction (north-star).
35
+ *
36
+ * `authoritative`: a human correction is GROUND TRUTH that can OVERRIDE the
37
+ * model (check_action `verdict:'blocked'`). Defaults true for `kind:'correction'`
38
+ * via applyCorrectionDefaults; explicit `authoritative:false` opts a record out
39
+ * of the override gate. Insights/hunches/facts default to NOT authoritative.
40
+ *
41
+ * predict_* counters track the predict-the-correction loop. They are kept
42
+ * STRICTLY SEPARATE from `precision` (= heeded/retrieved) — `predict_precision`
43
+ * = predict_hits / predicted_count and must never mutate the heeded metric.
44
+ */
45
+ authoritative?: boolean;
46
+ predicted_count?: number;
47
+ predict_hits?: number;
48
+ predict_precision?: number;
49
+ last_predicted?: string;
50
+ /**
51
+ * Consolidation & lifecycle (2026-06-29). Borrowed from Hindsight's REAL
52
+ * mechanisms — proof-count evidence grounding, refine-not-overwrite
53
+ * consolidation, contradiction→supersession, staleness — implemented
54
+ * AR-native (local, file-backed, no LLM on the storage path). Every field is
55
+ * optional and defaulted in applyCorrectionDefaults so pre-existing JSON
56
+ * (which has none of them) normalizes on read with no migration.
57
+ */
58
+ proof_count?: number;
59
+ proof_confidence?: number;
60
+ superseded_by?: string;
61
+ merged_from?: string[];
62
+ stale?: boolean;
63
+ }
64
+ /**
65
+ * One discarded correction-candidate, appended to corrections/_rejected.jsonl
66
+ * when the capture gate rejects the text. This is the survivorship-bias probe:
67
+ * the soft corrections the palace never sees ("that's not what I meant",
68
+ * "closer but the spacing is off") become VISIBLE here instead of vanishing.
69
+ *
70
+ * Written best-effort only — see logRejectedCorrection. A rejection log can
71
+ * NEVER throw into the capture path.
72
+ */
73
+ export interface RejectedCorrectionRecord {
74
+ ts: string;
75
+ project: string;
76
+ rule: string;
77
+ reason: string;
78
+ gate_version: string;
33
79
  }
34
80
  export interface CorrectionOutcome {
35
81
  correction_id: string;
36
82
  project: string;
37
- /** "heeded" = agent's action honored the warning. "recurred" = same bug happened again. */
38
- kind: "retrieved" | "heeded" | "recurred";
83
+ /**
84
+ * "retrieved" = surfaced via check/recall. "heeded" = agent's action honored
85
+ * the warning. "recurred" = same bug happened again.
86
+ * Wave 5 — "predicted" = predictCorrection fired this risk before the user
87
+ * corrected; "predict_hit" = that prediction later became a real recurrence.
88
+ */
89
+ kind: "retrieved" | "heeded" | "recurred" | "predicted" | "predict_hit";
39
90
  /** ISO timestamp */
40
91
  at: string;
41
92
  /** Free-text evidence — what made you decide. */
@@ -63,30 +114,105 @@ export interface CorrectionKPI {
63
114
  precision: number;
64
115
  retrieved: number;
65
116
  }>;
117
+ /** P4: active corrections untouched > STALE_DAYS — review candidates. */
118
+ stale_candidates: Array<{
119
+ id: string;
120
+ rule: string;
121
+ last_seen: string;
122
+ }>;
66
123
  }
124
+ /**
125
+ * Gate version stamp — bump whenever isLikelyRealCorrection's accept criteria
126
+ * change so a rejected-log analysis can attribute discard rates to a specific
127
+ * gate revision. Kept in lock-step with the classifier below.
128
+ *
129
+ * v3 (2026-06-21, Loop 8): the gate now scans the FULL correction text (and its
130
+ * decimal-safe sentence fragments) for an actionable marker instead of only the
131
+ * truncated first sentence. Loop 7 proved the first-sentence-slice discarded
132
+ * genuine soft corrections whose directive lived in sentence 2. The NOISE
133
+ * filters (system-fragment / too-short / pure-acknowledgment / doc-header) are
134
+ * unchanged and still run FIRST so the precision floor holds.
135
+ *
136
+ * v4 (2026-06-22, Loop 14): split directive markers into STRONG (accept anywhere)
137
+ * vs WEAK (accept only outside a hedged/reporting frame), closing the round-table's
138
+ * MEDIUM false-accept where tentative filler ("I think we should use it") passed on
139
+ * a bare weak verb. Recall-safe — no fixture correction relies on a hedged weak verb.
140
+ */
141
+ export declare const GATE_VERSION = "v4-2026-06-22";
142
+ /**
143
+ * P4: a correction is stale when its most recent touch (last_retrieved, else
144
+ * last_outcome, else its date) is older than STALE_DAYS. Pure — `nowMs` is
145
+ * injectable for tests. INFORMATIONAL ONLY: the corrections room is decay-
146
+ * protected, so this never archives on its own; it surfaces a review candidate.
147
+ */
148
+ export declare function isStaleCorrection(rec: CorrectionRecord, nowMs?: number): boolean;
149
+ /**
150
+ * Decimal-safe sentence splitter. Splits on sentence-ending punctuation
151
+ * (`.`, `!`, `?`, or a newline) ONLY when followed by whitespace or end-of-text
152
+ * — NOT on a bare `.` that sits between digits/word chars. This protects
153
+ * version/model tokens like "Opus 4.7", "v3.4.32", "novada-search" and URLs
154
+ * from being chopped mid-fragment (the exact Loop-7 mis-split that hid the
155
+ * imperative in "Show BOTH Opus 4.7 and 4.8" behind the slice "Show BOTH Opus 4").
156
+ *
157
+ * Returns the FULL text as a single fragment when no sentence boundary is found.
158
+ * Empty fragments are dropped. This is a classifier helper, not a linguistic
159
+ * tokenizer — it deliberately errs toward NOT splitting.
160
+ */
161
+ export declare function splitSentences(text: string): string[];
67
162
  /**
68
163
  * Capture-quality gate — rejects context-free fragments, pure acknowledgments,
69
164
  * and text that carries no actionable signal.
70
165
  *
71
- * v2 (2026-06-12): classifies on the RULE field only (context param reserved for
72
- * future use but never classified onprevents long context from bypassing the
73
- * acknowledgment gate).
74
- *
75
- * Gates (in order):
76
- * 1. Must be >= 12 chars after trim.
77
- * 2. Must NOT be a pure acknowledgment/fragment applied unconditionally (no
78
- * length cap v1 60-char cap allowed long-context bypass).
79
- * 3. Reject system/tool fragments: starts with '<', is a pure number, or is a
80
- * bare file path (no spaces, contains path separator, no verb-ish content).
81
- * 4. PASS if any of:
82
- * a) imperative/modal marker present
83
- * b) preference statement ("user wants/prefers/likes/needs", CJK equiv.)
84
- * c) substantive rule: len >= 40 AND >= 2 words of >= 5 chars AND verb-ish
85
- * 5. else reject: "no actionable signal"
86
- *
87
- * Returns { ok: true } when the text passes all gates, or { ok: false, reason }
88
- * explaining which gate fired. Callers may surface the reason in a warning.
166
+ * v3 (2026-06-21, Loop 8): the ACTIONABLE-signal scan now runs over the FULL
167
+ * text AND each decimal-safe sentence fragmentaccepting if ANY fragment
168
+ * carries an imperative/modal/preference marker. This fixes the Loop-7 root
169
+ * cause where the gate only ever saw the truncated first sentence
170
+ * (`text.split(/[.\n]/)[0].slice(0,100)`), discarding ~60% of genuine soft
171
+ * corrections whose directive lived in sentence 2 (e.g. "No, that's wrong.
172
+ * Don't use dark backgrounds.") or whose first sentence was chopped by a
173
+ * decimal ("Show BOTH Opus 4.7 and 4.8" → "Show BOTH Opus 4").
174
+ *
175
+ * PRECISION FLOOR: the HARD noise gates run FIRST, on the WHOLE text — these can
176
+ * never be rescued by the actionable scan:
177
+ * 1. too-short (< 12 chars).
178
+ * 2. system/tool fragment: starts with '<', pure number, bare file path.
179
+ * 3. doc/report/transcript header (starts with '#', a report/mission title,
180
+ * or a file:// URL) pasted artifacts, never a behavioral rule.
181
+ *
182
+ * Then the ACTIONABLE-signal scan runs over the FULL text + each fragment. A
183
+ * text that OPENS like an acknowledgment ("No, that's wrong …") is RESCUED only
184
+ * if a fragment carries a genuine directive (the Loop-7 leak: "No, that's wrong.
185
+ * Don't use dark backgrounds." → fragment 2 "Don't use …" is a real rule).
186
+ *
187
+ * Finally the SOFT acknowledgment gate rejects pure acks that the actionable
188
+ * scan did NOT rescue (bare "ok sure", "no that's not what I meant"). Because it
189
+ * runs AFTER the actionable scan, it can no longer eat a genuine correction that
190
+ * merely opens with "no" — but a content-free ack still has no directive to
191
+ * rescue it, so it is still dropped. The marker set is TIGHT (dropped the v2
192
+ * loose "verb-ish anywhere" path) so a long prose blob with no real directive
193
+ * is NOT re-admitted just because it contains a generic verb.
194
+ *
195
+ * Returns { ok: true } when the text passes, or { ok: false, reason } explaining
196
+ * which gate fired. Callers may surface the reason in a warning.
89
197
  */
198
+ /**
199
+ * dropHardNoise — the four hard-noise precision-floor gates extracted so they
200
+ * can be called independently by the two-lane router (both lanes apply the same
201
+ * pre-filter before routing).
202
+ *
203
+ * Returns true = text passes (KEEP — not obviously noise)
204
+ * Returns false = text fails a hard gate (DROP — un-rescuable by actionable scan)
205
+ *
206
+ * Identical semantics to the inline gates in isLikelyRealCorrection; this
207
+ * extraction must NOT change gate v4 behaviour (Loops 7/8/14 must stay intact).
208
+ *
209
+ * Gate 1 — minimum length (< 12 chars)
210
+ * Gate 2a — starts with '<' (system/tool fragment)
211
+ * Gate 2b — pure digits (bare number, no rule content)
212
+ * Gate 2c — bare file path (no spaces, has / or \, no 4+ letter word)
213
+ * Gate 3 — doc/report/transcript header (markdown '#', file://, ⏺, report title)
214
+ */
215
+ export declare function dropHardNoise(text: string): boolean;
90
216
  export declare function isLikelyRealCorrection(rule: string, _context?: string): {
91
217
  ok: boolean;
92
218
  reason?: string;
@@ -94,6 +220,10 @@ export declare function isLikelyRealCorrection(rule: string, _context?: string):
94
220
  export interface WriteCorrectionResult {
95
221
  written: boolean;
96
222
  reason?: string;
223
+ /** P1 consolidation: true when this intake was folded into an existing record. */
224
+ merged?: boolean;
225
+ /** id of the written record, or the existing record's id on a merge. */
226
+ id?: string;
97
227
  }
98
228
  /**
99
229
  * Write a correction to persistent storage.
@@ -128,15 +258,110 @@ export interface RetractCorrectionResult {
128
258
  * The file is rewritten atomically — never deleted. The record remains in
129
259
  * _outcomes.jsonl history and can be manually reactivated by editing the JSON.
130
260
  */
131
- export declare function retractCorrection(project: string, id: string, reason?: string): RetractCorrectionResult;
261
+ export declare function retractCorrection(project: string, id: string, reason?: string, supersededBy?: string): RetractCorrectionResult;
132
262
  /**
133
263
  * Record an outcome event for a correction (retrieved / heeded / recurred).
134
264
  * Appends to _outcomes.jsonl and also updates the correction JSON's counters
135
265
  * + precision cache. Atomic per-write.
136
266
  */
137
267
  export declare function recordOutcome(outcome: CorrectionOutcome): void;
268
+ /**
269
+ * Best-effort: append one row to corrections/_rejected.jsonl recording a
270
+ * gate-rejected correction candidate. INVARIANT: never throws — every fs op is
271
+ * wrapped so a rejection log can never escalate into the capture path. Reads
272
+ * nothing on the hot path except the (already-small) file it rotates.
273
+ *
274
+ * Rotation: when the file exceeds REJECTED_LOG_CAP rows, it is rewritten with
275
+ * only the most-recent rows (append-only semantics, bounded size). Rotation is
276
+ * itself best-effort — a rotation failure still leaves the append intact.
277
+ */
278
+ export declare function logRejectedCorrection(project: string, rule: string, reason: string): void;
279
+ /**
280
+ * Read all rejected correction candidates for a project, oldest-first (file
281
+ * order). Returns [] when no log exists — never throws. Skips malformed lines.
282
+ */
283
+ export declare function readRejectedCorrections(project: string): RejectedCorrectionRecord[];
284
+ export interface RejectedStats {
285
+ project: string;
286
+ discarded: number;
287
+ /** Discard rate = discarded / (discarded + accepted). undefined if accepted unknown. */
288
+ rate?: number;
289
+ /** Accepted count if known (e.g. from readCorrections). */
290
+ accepted?: number;
291
+ /** Reasons sorted by descending count. */
292
+ top_reasons: Array<{
293
+ reason: string;
294
+ count: number;
295
+ }>;
296
+ }
297
+ /**
298
+ * Aggregate the rejected log into discard count + per-reason breakdown. When
299
+ * `acceptedCount` is supplied the discard RATE is computed too. Read-only.
300
+ */
301
+ export declare function getRejectedStats(project: string, acceptedCount?: number): RejectedStats;
302
+ /**
303
+ * Wave 5 — single source for "what outcomes already fired today" across the
304
+ * predict / check-action / session-start / session-end call sites. Reads the
305
+ * _outcomes.jsonl audit trail and buckets today's events (local-TZ) per
306
+ * correction id. Returns an empty Map when no log exists — never throws.
307
+ *
308
+ * Local-TZ date (`sv` locale → YYYY-MM-DD) matches the 1/day guards elsewhere
309
+ * (session-start/session-end) so "today" agrees across all four readers.
310
+ */
311
+ export declare function readOutcomesForToday(project: string): Map<string, Set<CorrectionOutcome["kind"]>>;
312
+ /**
313
+ * Loop 3 — bucket outcome events recorded STRICTLY BEFORE a given ISO/date
314
+ * cutoff (local-TZ day comparison). Mirrors readOutcomesForToday but with an
315
+ * explicit date arg, so the cross-day predict_hit path can ask "was this risk
316
+ * already PREDICTED on an earlier day?" without depending on today's bucket.
317
+ *
318
+ * `isoCutoff` may be a full ISO timestamp or a YYYY-MM-DD date; only its
319
+ * local-TZ day is used. An event on the SAME day as the cutoff is EXCLUDED
320
+ * (strictly-before) — this is what keeps a same-session/same-day prediction
321
+ * from ever counting as a cross-day hit.
322
+ */
323
+ export declare function readOutcomesBefore(project: string, isoCutoff: string): Map<string, Set<CorrectionOutcome["kind"]>>;
324
+ /**
325
+ * Loop 3 — bucket outcome events recorded ON a specific local-TZ day. Mirrors
326
+ * readOutcomesForToday but with an explicit date arg (for replaying a past day
327
+ * in tests / offline analysis). `isoDate` may be a full ISO timestamp or a
328
+ * YYYY-MM-DD date; only its local-TZ day is used.
329
+ */
330
+ export declare function readOutcomesOnDate(project: string, isoDate: string): Map<string, Set<CorrectionOutcome["kind"]>>;
138
331
  /**
139
332
  * Aggregate KPIs over all corrections for a project — the "is this learning loop working?" view.
140
333
  */
141
334
  export declare function getCorrectionKPIs(project: string): CorrectionKPI;
335
+ export interface NoiseReview {
336
+ /** Low-signal corrections (precision<0.3, retrieved≥3) proposed for archiving. */
337
+ suggestions: Array<{
338
+ id: string;
339
+ rule: string;
340
+ precision: number;
341
+ }>;
342
+ /** ids actually retracted — non-empty ONLY when auto mode is on. */
343
+ pruned: string[];
344
+ /** Whether this call ran in auto-prune mode. */
345
+ auto: boolean;
346
+ }
347
+ /**
348
+ * P4: review low-signal corrections for archiving. SUGGEST-ONLY by default —
349
+ * returns candidates and mutates NOTHING. Set AR_CONSOLIDATE_AUTO=1 (or pass
350
+ * { auto: true }) to actually retract them. This mirrors AR's conservative
351
+ * posture: deleting belief is a deliberate act, so the default never mutates;
352
+ * an explicit human (or opt-in flag) triggers the retraction.
353
+ */
354
+ export declare function reviewNoiseCorrections(project: string, opts?: {
355
+ auto?: boolean;
356
+ }): NoiseReview;
357
+ /**
358
+ * P5: order corrections for surfacing when a cap applies. Today P0s are surfaced
359
+ * `slice(0, 10)` in newest-first FILENAME order — so when a project has >10 P0s
360
+ * the ones that survive are arbitrary (just the most-recently-dated). This ranks
361
+ * by a composite LOCAL score (NO key, NO network) so the most authoritative +
362
+ * evidence-backed + recently-relevant rules win the cap:
363
+ * severity (p0 always above p1) ≫ proof_confidence ≫ recency ≫ proof_count.
364
+ * Deterministic and stable; pure (Date.now only for recency decay).
365
+ */
366
+ export declare function rankCorrections(records: CorrectionRecord[], limit?: number): CorrectionRecord[];
142
367
  //# sourceMappingURL=corrections.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"corrections.d.ts","sourceRoot":"","sources":["../../src/storage/corrections.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"corrections.d.ts","sourceRoot":"","sources":["../../src/storage/corrections.ts"],"names":[],"mappings":"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"}