@remnic/core 9.3.629 → 9.3.631

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 (221) hide show
  1. package/dist/access-cli.js +15 -13
  2. package/dist/access-cli.js.map +1 -1
  3. package/dist/access-http.d.ts +5 -4
  4. package/dist/access-http.js +7 -6
  5. package/dist/access-mcp.d.ts +5 -4
  6. package/dist/access-mcp.js +6 -5
  7. package/dist/{access-service-BdThkfIE.d.ts → access-service-C9_EpVHd.d.ts} +2 -2
  8. package/dist/access-service.d.ts +5 -4
  9. package/dist/access-service.js +5 -4
  10. package/dist/action-confidence.d.ts +1 -1
  11. package/dist/active-memory-bridge.d.ts +1 -1
  12. package/dist/active-recall.d.ts +1 -1
  13. package/dist/active-recall.js +1 -1
  14. package/dist/auto-sync-RFADEHIQ.js +75 -0
  15. package/dist/auto-sync-RFADEHIQ.js.map +1 -0
  16. package/dist/behavior-learner.d.ts +1 -1
  17. package/dist/behavior-signals.d.ts +1 -1
  18. package/dist/bootstrap.d.ts +4 -3
  19. package/dist/briefing.d.ts +1 -1
  20. package/dist/briefing.js +3 -2
  21. package/dist/buffer-surprise-report.d.ts +1 -1
  22. package/dist/buffer.d.ts +1 -1
  23. package/dist/calibration.d.ts +1 -1
  24. package/dist/causal-behavior.d.ts +1 -1
  25. package/dist/causal-consolidation.d.ts +1 -1
  26. package/dist/causal-consolidation.js +4 -3
  27. package/dist/causal-consolidation.js.map +1 -1
  28. package/dist/{chunk-532VCWYW.js → chunk-242XFZ36.js} +2 -2
  29. package/dist/{chunk-XXO5TI3B.js → chunk-32U3N7H5.js} +3 -3
  30. package/dist/{chunk-KB4MFBF5.js → chunk-3RDYU3JS.js} +3 -3
  31. package/dist/{chunk-57QXN2CS.js → chunk-4S3N6HFG.js} +2 -2
  32. package/dist/{chunk-OLNNOHBC.js → chunk-5PT5I6JQ.js} +20 -14
  33. package/dist/{chunk-OLNNOHBC.js.map → chunk-5PT5I6JQ.js.map} +1 -1
  34. package/dist/{chunk-GE7Q7KXP.js → chunk-7A2QKUUA.js} +2 -2
  35. package/dist/{chunk-KKTXCFD7.js → chunk-7H5WCPBS.js} +95 -11
  36. package/dist/{chunk-KKTXCFD7.js.map → chunk-7H5WCPBS.js.map} +1 -1
  37. package/dist/{chunk-3MNBW7R7.js → chunk-C4KKM62E.js} +2 -2
  38. package/dist/{chunk-NKCW223V.js → chunk-CMN5AWAZ.js} +2 -2
  39. package/dist/{chunk-JXHMAQYT.js → chunk-DOBJH4I6.js} +4 -4
  40. package/dist/{chunk-TZDSNIRO.js → chunk-IFVFQRZ2.js} +5 -5
  41. package/dist/{chunk-LQYTQCXM.js → chunk-JCLECECB.js} +2 -2
  42. package/dist/chunk-KVDUDYEN.js +1164 -0
  43. package/dist/chunk-KVDUDYEN.js.map +1 -0
  44. package/dist/{chunk-QDV6VAD4.js → chunk-LEG7XWS2.js} +2 -2
  45. package/dist/chunk-M7XQSUBB.js +280 -0
  46. package/dist/chunk-M7XQSUBB.js.map +1 -0
  47. package/dist/{chunk-N5RGXWLQ.js → chunk-PUEAEQSN.js} +2 -2
  48. package/dist/{chunk-UGHUNQ74.js → chunk-QYGIQ5NM.js} +212 -417
  49. package/dist/chunk-QYGIQ5NM.js.map +1 -0
  50. package/dist/{chunk-JKCDQBDW.js → chunk-UXFOGILU.js} +2 -2
  51. package/dist/{chunk-MVQN73GT.js → chunk-VTR3MNYF.js} +2 -2
  52. package/dist/{chunk-KVFYTRMV.js → chunk-W25I7G6U.js} +2 -2
  53. package/dist/{chunk-3GLCUPXP.js → chunk-WLZBVYC6.js} +192 -889
  54. package/dist/chunk-WLZBVYC6.js.map +1 -0
  55. package/dist/{chunk-3R2UZV3U.js → chunk-X7EJF46S.js} +2 -2
  56. package/dist/{chunk-54KDA6UK.js → chunk-XG4NAWAV.js} +3 -3
  57. package/dist/{chunk-P2D2MM47.js → chunk-YROCXMCK.js} +2 -2
  58. package/dist/{cli-DAsHklrf.d.ts → cli-CuVEQWKr.d.ts} +3 -3
  59. package/dist/cli.d.ts +6 -5
  60. package/dist/cli.js +18 -17
  61. package/dist/compounding/engine.d.ts +1 -1
  62. package/dist/compounding/engine.js +3 -2
  63. package/dist/compounding/preference-consolidator.d.ts +1 -1
  64. package/dist/compression-optimizer.d.ts +1 -1
  65. package/dist/config.d.ts +1 -1
  66. package/dist/config.js +1 -1
  67. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  68. package/dist/connectors/codex-materialize-runner.js +3 -2
  69. package/dist/connectors/codex-materialize.d.ts +1 -1
  70. package/dist/connectors/index.d.ts +1 -1
  71. package/dist/connectors/index.js +3 -2
  72. package/dist/consolidation-provenance-check.d.ts +1 -1
  73. package/dist/consolidation-undo.d.ts +1 -1
  74. package/dist/contradiction/index.d.ts +1 -1
  75. package/dist/contradiction/index.js +4 -4
  76. package/dist/conversation-index/backend.d.ts +1 -1
  77. package/dist/conversation-index/chunker.d.ts +1 -1
  78. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  79. package/dist/conversation-index/indexer.d.ts +1 -1
  80. package/dist/conversation-index/search.d.ts +1 -1
  81. package/dist/day-summary.d.ts +1 -1
  82. package/dist/delinearize.d.ts +1 -1
  83. package/dist/direct-answer-wiring.d.ts +1 -1
  84. package/dist/direct-answer.d.ts +1 -1
  85. package/dist/embedding-fallback.d.ts +1 -1
  86. package/dist/enrichment/index.d.ts +1 -1
  87. package/dist/entity-retrieval.d.ts +1 -1
  88. package/dist/entity-retrieval.js +3 -2
  89. package/dist/entity-schema.d.ts +1 -1
  90. package/dist/explicit-capture.d.ts +4 -3
  91. package/dist/extraction-judge-telemetry.d.ts +1 -1
  92. package/dist/extraction-judge-training.d.ts +1 -1
  93. package/dist/extraction-judge.d.ts +1 -1
  94. package/dist/extraction.d.ts +1 -1
  95. package/dist/fallback-llm.d.ts +1 -1
  96. package/dist/identity-continuity.d.ts +1 -1
  97. package/dist/importance.d.ts +1 -1
  98. package/dist/index.d.ts +8 -8
  99. package/dist/index.js +49 -45
  100. package/dist/index.js.map +1 -1
  101. package/dist/intent.d.ts +1 -1
  102. package/dist/lcm/engine.d.ts +1 -1
  103. package/dist/lcm/index.d.ts +1 -1
  104. package/dist/lcm/tools.d.ts +1 -1
  105. package/dist/lifecycle.d.ts +1 -1
  106. package/dist/live-connectors-runner.d.ts +1 -1
  107. package/dist/local-llm.d.ts +1 -1
  108. package/dist/maintenance/memory-governance.d.ts +1 -1
  109. package/dist/maintenance/memory-governance.js +3 -2
  110. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -2
  111. package/dist/maintenance/rebuild-memory-projection.js +4 -3
  112. package/dist/mcp-memory-inspector-app.d.ts +5 -4
  113. package/dist/memory-action-policy.d.ts +1 -1
  114. package/dist/memory-cache.d.ts +1 -1
  115. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  116. package/dist/memory-projection-store.d.ts +1 -1
  117. package/dist/memory-provenance.d.ts +1 -1
  118. package/dist/memory-worth-outcomes.d.ts +1 -1
  119. package/dist/models-json.d.ts +1 -1
  120. package/dist/namespaces/migrate.d.ts +1 -1
  121. package/dist/namespaces/migrate.js +4 -3
  122. package/dist/namespaces/principal.d.ts +1 -1
  123. package/dist/namespaces/search.d.ts +1 -1
  124. package/dist/namespaces/storage.d.ts +1 -1
  125. package/dist/namespaces/storage.js +3 -2
  126. package/dist/native-knowledge.d.ts +1 -1
  127. package/dist/operator-toolkit.d.ts +1 -1
  128. package/dist/operator-toolkit.js +7 -6
  129. package/dist/{orchestrator-BexeSJ2j.d.ts → orchestrator-CoqytbK_.d.ts} +102 -10
  130. package/dist/orchestrator.d.ts +4 -3
  131. package/dist/orchestrator.js +12 -10
  132. package/dist/patterns-cli.d.ts +1 -1
  133. package/dist/policy-runtime.d.ts +1 -1
  134. package/dist/qmd-recall-cache.d.ts +1 -1
  135. package/dist/qmd.d.ts +1 -1
  136. package/dist/recall-disclosure-escalation.d.ts +1 -1
  137. package/dist/recall-explain-renderer.d.ts +1 -1
  138. package/dist/recall-planner-llm.d.ts +1 -1
  139. package/dist/recall-state.d.ts +1 -1
  140. package/dist/recall-tag-filter.d.ts +1 -1
  141. package/dist/recall-xray-cli.d.ts +1 -1
  142. package/dist/recall-xray-renderer.d.ts +1 -1
  143. package/dist/recall-xray.d.ts +1 -1
  144. package/dist/resolve-auth-token.d.ts +1 -1
  145. package/dist/resume-bundles.js +2 -2
  146. package/dist/retrieval-agents.d.ts +1 -1
  147. package/dist/retrieval-tiers.d.ts +1 -1
  148. package/dist/routing/engine.d.ts +1 -1
  149. package/dist/routing/store.d.ts +1 -1
  150. package/dist/search/embed-helper.d.ts +1 -1
  151. package/dist/search/factory.d.ts +1 -1
  152. package/dist/search/index.d.ts +1 -1
  153. package/dist/search/lancedb-backend.d.ts +1 -1
  154. package/dist/search/meilisearch-backend.d.ts +1 -1
  155. package/dist/search/noop-backend.d.ts +1 -1
  156. package/dist/search/orama-backend.d.ts +1 -1
  157. package/dist/search/port.d.ts +1 -1
  158. package/dist/search/remote-backend.d.ts +1 -1
  159. package/dist/{semantic-consolidation-PwkzNfdK.d.ts → semantic-consolidation-BPs6BURk.d.ts} +1 -1
  160. package/dist/semantic-consolidation.d.ts +2 -2
  161. package/dist/semantic-consolidation.js +4 -3
  162. package/dist/semantic-rule-promotion.js +3 -2
  163. package/dist/semantic-rule-verifier.d.ts +1 -1
  164. package/dist/semantic-rule-verifier.js +3 -2
  165. package/dist/session-observer-bands.d.ts +1 -1
  166. package/dist/session-observer-state.d.ts +1 -1
  167. package/dist/shared-context/manager.d.ts +1 -1
  168. package/dist/signal.d.ts +1 -1
  169. package/dist/storage.d.ts +38 -2
  170. package/dist/storage.js +6 -3
  171. package/dist/summarizer.d.ts +1 -1
  172. package/dist/summary-snapshot.d.ts +1 -1
  173. package/dist/temporal-supersession.d.ts +1 -1
  174. package/dist/temporal-validity.d.ts +1 -1
  175. package/dist/threading.d.ts +1 -1
  176. package/dist/tier-migration.d.ts +1 -1
  177. package/dist/tier-routing.d.ts +1 -1
  178. package/dist/topics.d.ts +1 -1
  179. package/dist/transcript.d.ts +1 -1
  180. package/dist/{types-BCF2wqKa.d.ts → types-CpMPD8xl.d.ts} +59 -11
  181. package/dist/types.d.ts +1 -1
  182. package/dist/utility-runtime.d.ts +1 -1
  183. package/dist/verified-recall.js +3 -2
  184. package/package.json +1 -1
  185. package/src/orchestrator.ts +74 -0
  186. package/src/storage.ts +100 -0
  187. package/src/wearables/auto-sync.test.ts +181 -0
  188. package/src/wearables/auto-sync.ts +129 -0
  189. package/src/wearables/cli.ts +6 -0
  190. package/src/wearables/config.test.ts +90 -11
  191. package/src/wearables/config.ts +113 -11
  192. package/src/wearables/memory-gen.test.ts +416 -1
  193. package/src/wearables/memory-gen.ts +381 -23
  194. package/src/wearables/pipeline.test.ts +396 -5
  195. package/src/wearables/pipeline.ts +174 -22
  196. package/src/wearables/service.test.ts +172 -0
  197. package/src/wearables/service.ts +84 -3
  198. package/src/wearables/storage-io.test.ts +81 -0
  199. package/src/wearables/trust.test.ts +123 -0
  200. package/src/wearables/trust.ts +168 -0
  201. package/src/wearables/types.ts +57 -9
  202. package/dist/chunk-3GLCUPXP.js.map +0 -1
  203. package/dist/chunk-UGHUNQ74.js.map +0 -1
  204. /package/dist/{chunk-532VCWYW.js.map → chunk-242XFZ36.js.map} +0 -0
  205. /package/dist/{chunk-XXO5TI3B.js.map → chunk-32U3N7H5.js.map} +0 -0
  206. /package/dist/{chunk-KB4MFBF5.js.map → chunk-3RDYU3JS.js.map} +0 -0
  207. /package/dist/{chunk-57QXN2CS.js.map → chunk-4S3N6HFG.js.map} +0 -0
  208. /package/dist/{chunk-GE7Q7KXP.js.map → chunk-7A2QKUUA.js.map} +0 -0
  209. /package/dist/{chunk-3MNBW7R7.js.map → chunk-C4KKM62E.js.map} +0 -0
  210. /package/dist/{chunk-NKCW223V.js.map → chunk-CMN5AWAZ.js.map} +0 -0
  211. /package/dist/{chunk-JXHMAQYT.js.map → chunk-DOBJH4I6.js.map} +0 -0
  212. /package/dist/{chunk-TZDSNIRO.js.map → chunk-IFVFQRZ2.js.map} +0 -0
  213. /package/dist/{chunk-LQYTQCXM.js.map → chunk-JCLECECB.js.map} +0 -0
  214. /package/dist/{chunk-QDV6VAD4.js.map → chunk-LEG7XWS2.js.map} +0 -0
  215. /package/dist/{chunk-N5RGXWLQ.js.map → chunk-PUEAEQSN.js.map} +0 -0
  216. /package/dist/{chunk-JKCDQBDW.js.map → chunk-UXFOGILU.js.map} +0 -0
  217. /package/dist/{chunk-MVQN73GT.js.map → chunk-VTR3MNYF.js.map} +0 -0
  218. /package/dist/{chunk-KVFYTRMV.js.map → chunk-W25I7G6U.js.map} +0 -0
  219. /package/dist/{chunk-3R2UZV3U.js.map → chunk-X7EJF46S.js.map} +0 -0
  220. /package/dist/{chunk-54KDA6UK.js.map → chunk-XG4NAWAV.js.map} +0 -0
  221. /package/dist/{chunk-P2D2MM47.js.map → chunk-YROCXMCK.js.map} +0 -0
@@ -25,17 +25,20 @@ test("boolean-ish strings coerce; garbage booleans throw", () => {
25
25
  assert.throws(() => parseWearablesConfig({ enabled: "fales" }), /wearables.enabled/);
26
26
  });
27
27
 
28
- test("source settings default to the least-privileged memory mode", () => {
28
+ test("source settings default to the fully-automated smart pipeline", () => {
29
29
  const parsed = parseWearablesConfig({
30
30
  enabled: true,
31
31
  sources: { limitless: { enabled: true } },
32
32
  });
33
33
  const source = parsed.sources.limitless;
34
- assert.equal(source.memoryMode, "review");
34
+ assert.equal(source.memoryMode, "smart");
35
+ assert.equal(source.sourceTrust, 0.8);
36
+ assert.equal(source.autoApproveTrust, 0.7);
37
+ assert.equal(source.reviewTrust, 0.45);
35
38
  assert.equal(source.minConfidence, 0.6);
36
39
  assert.equal(source.minImportance, "low");
37
- assert.equal(source.maxMemoriesPerDay, 20);
38
- assert.equal(source.importNativeMemories, "off");
40
+ assert.equal(source.maxMemoriesPerDay, 0, "uncapped by default");
41
+ assert.equal(source.importNativeMemories, "smart");
39
42
  assert.deepEqual(source.cleanup, {
40
43
  mergeSameSpeaker: true,
41
44
  stripFillers: true,
@@ -44,6 +47,32 @@ test("source settings default to the least-privileged memory mode", () => {
44
47
  });
45
48
  });
46
49
 
50
+ test("top-level defaults are full-featured: digest and off-the-record on", () => {
51
+ const parsed = parseWearablesConfig({});
52
+ assert.equal(parsed.digestEnabled, true);
53
+ assert.equal(parsed.offTheRecordEnabled, true);
54
+ assert.equal(parsed.redactionEnabled, true);
55
+ });
56
+
57
+ test("trust knobs validate range and ordering", () => {
58
+ assert.throws(
59
+ () => parseWearablesConfig({ sources: { bee: { sourceTrust: 1.5 } } }),
60
+ /sourceTrust must be a number between 0 and 1/,
61
+ );
62
+ assert.throws(
63
+ () => parseWearablesConfig({ sources: { bee: { autoApproveTrust: -1 } } }),
64
+ /autoApproveTrust/,
65
+ );
66
+ assert.throws(
67
+ () => parseWearablesConfig({ sources: { bee: { reviewTrust: 0.9, autoApproveTrust: 0.7 } } }),
68
+ /reviewTrust .* must be below autoApproveTrust/,
69
+ );
70
+ const parsed = parseWearablesConfig({
71
+ sources: { bee: { sourceTrust: 0.5, autoApproveTrust: 0.8, reviewTrust: 0.3 } },
72
+ });
73
+ assert.equal(parsed.sources.bee.sourceTrust, 0.5);
74
+ });
75
+
47
76
  test("invalid enum values list the valid options", () => {
48
77
  assert.throws(
49
78
  () =>
@@ -66,15 +95,15 @@ test("maxMemoriesPerDay honors the documented 0-disables value and bounds", () =
66
95
  sources: { limitless: { maxMemoriesPerDay: 0 } },
67
96
  });
68
97
  assert.equal(parsed.sources.limitless.maxMemoriesPerDay, 0);
69
- // Over-ceiling values reject instead of silently clamping to 500.
70
- assert.throws(
71
- () => parseWearablesConfig({ sources: { limitless: { maxMemoriesPerDay: 99999 } } }),
72
- /maxMemoriesPerDay must be an integer between 0 and 500/,
73
- );
98
+ // No ceiling: any non-negative integer cap is the operator's call.
74
99
  assert.equal(
75
- parseWearablesConfig({ sources: { limitless: { maxMemoriesPerDay: 500 } } })
100
+ parseWearablesConfig({ sources: { limitless: { maxMemoriesPerDay: 99999 } } })
76
101
  .sources.limitless.maxMemoriesPerDay,
77
- 500,
102
+ 99999,
103
+ );
104
+ assert.throws(
105
+ () => parseWearablesConfig({ sources: { limitless: { maxMemoriesPerDay: -1 } } }),
106
+ /maxMemoriesPerDay must be a non-negative integer/,
78
107
  );
79
108
  assert.throws(
80
109
  () => parseWearablesConfig({ sources: { limitless: { maxMemoriesPerDay: "lots" } } }),
@@ -141,3 +170,53 @@ test("minConfidence rejects out-of-range values instead of clamping", () => {
141
170
  0.85,
142
171
  );
143
172
  });
173
+
174
+ test("auto-sync defaults to enabled with sane window settings", () => {
175
+ const parsed = parseWearablesConfig({});
176
+ assert.equal(parsed.autoSyncEnabled, true);
177
+ assert.equal(parsed.autoSyncIntervalMinutes, 15);
178
+ assert.equal(parsed.autoSyncDays, 2);
179
+ assert.equal(parsed.autoSyncDeepDays, 7);
180
+ });
181
+
182
+ test("auto-sync knobs parse, coerce, and loud-reject invalid values", () => {
183
+ const parsed = parseWearablesConfig({
184
+ autoSyncEnabled: "false",
185
+ autoSyncIntervalMinutes: "30",
186
+ autoSyncDays: 3,
187
+ autoSyncDeepDays: 14,
188
+ });
189
+ assert.equal(parsed.autoSyncEnabled, false, "boolean-ish strings coerce");
190
+ assert.equal(parsed.autoSyncIntervalMinutes, 30, "numeric strings coerce");
191
+ assert.equal(parsed.autoSyncDays, 3);
192
+ assert.equal(parsed.autoSyncDeepDays, 14);
193
+
194
+ assert.throws(
195
+ () => parseWearablesConfig({ autoSyncIntervalMinutes: 0 }),
196
+ /autoSyncIntervalMinutes must be an integer between 1 and 1440/,
197
+ );
198
+ assert.throws(
199
+ () => parseWearablesConfig({ autoSyncIntervalMinutes: 2.5 }),
200
+ /autoSyncIntervalMinutes/,
201
+ );
202
+ assert.throws(
203
+ () => parseWearablesConfig({ autoSyncDays: 0 }),
204
+ /autoSyncDays must be an integer between 1 and 90/,
205
+ );
206
+ assert.throws(
207
+ () => parseWearablesConfig({ autoSyncDeepDays: 91 }),
208
+ /autoSyncDeepDays must be an integer between 0 and 90/,
209
+ );
210
+ });
211
+
212
+ test("a deep window narrower than the tick window is rejected, 0 disables", () => {
213
+ assert.throws(
214
+ () => parseWearablesConfig({ autoSyncDays: 5, autoSyncDeepDays: 3 }),
215
+ /autoSyncDeepDays must be 0 \(disabled\) or >= wearables.autoSyncDays/,
216
+ );
217
+ assert.equal(parseWearablesConfig({ autoSyncDeepDays: 0 }).autoSyncDeepDays, 0);
218
+ assert.equal(
219
+ parseWearablesConfig({ autoSyncDays: 5, autoSyncDeepDays: 5 }).autoSyncDeepDays,
220
+ 5,
221
+ );
222
+ });
@@ -22,7 +22,7 @@ import type {
22
22
 
23
23
  export const KNOWN_WEARABLE_SOURCE_IDS = ["limitless", "bee", "omi"] as const;
24
24
 
25
- const MEMORY_MODES: WearableMemoryMode[] = ["off", "review", "auto"];
25
+ const MEMORY_MODES: WearableMemoryMode[] = ["off", "review", "auto", "smart"];
26
26
  const IMPORTANCE_LEVELS: ImportanceLevel[] = [
27
27
  "trivial",
28
28
  "low",
@@ -30,12 +30,23 @@ const IMPORTANCE_LEVELS: ImportanceLevel[] = [
30
30
  "high",
31
31
  "critical",
32
32
  ];
33
- const NATIVE_IMPORT_MODES = ["off", "review"] as const;
33
+ const NATIVE_IMPORT_MODES = ["off", "review", "smart"] as const;
34
34
 
35
35
  const DEFAULT_MIN_CONFIDENCE = 0.6;
36
36
  const DEFAULT_MIN_IMPORTANCE: ImportanceLevel = "low";
37
- const DEFAULT_MAX_MEMORIES_PER_DAY = 20;
38
- const MAX_MEMORIES_PER_DAY_CEILING = 500;
37
+ // Uncapped by default — wearables capture full days and the smart trust
38
+ // pipeline is the quality gate; a count cap would drop real memories on
39
+ // busy days. Operators who want a ceiling set any positive integer.
40
+ const DEFAULT_MAX_MEMORIES_PER_DAY = 0;
41
+ const DEFAULT_AUTO_SYNC_ENABLED = true;
42
+ const DEFAULT_AUTO_SYNC_INTERVAL_MINUTES = 15;
43
+ const MAX_AUTO_SYNC_INTERVAL_MINUTES = 1440;
44
+ const DEFAULT_AUTO_SYNC_DAYS = 2;
45
+ const DEFAULT_AUTO_SYNC_DEEP_DAYS = 7;
46
+ const MAX_AUTO_SYNC_WINDOW_DAYS = 90;
47
+ const DEFAULT_SOURCE_TRUST = 0.8;
48
+ const DEFAULT_AUTO_APPROVE_TRUST = 0.7;
49
+ const DEFAULT_REVIEW_TRUST = 0.45;
39
50
 
40
51
  export function defaultWearableCleanupSettings(): WearableCleanupSettings {
41
52
  return {
@@ -49,11 +60,14 @@ export function defaultWearableCleanupSettings(): WearableCleanupSettings {
49
60
  export function defaultWearableSourceSettings(): WearableSourceSettings {
50
61
  return {
51
62
  enabled: false,
52
- memoryMode: "review",
63
+ memoryMode: "smart",
64
+ sourceTrust: DEFAULT_SOURCE_TRUST,
65
+ autoApproveTrust: DEFAULT_AUTO_APPROVE_TRUST,
66
+ reviewTrust: DEFAULT_REVIEW_TRUST,
53
67
  minConfidence: DEFAULT_MIN_CONFIDENCE,
54
68
  minImportance: DEFAULT_MIN_IMPORTANCE,
55
69
  maxMemoriesPerDay: DEFAULT_MAX_MEMORIES_PER_DAY,
56
- importNativeMemories: "off",
70
+ importNativeMemories: "smart",
57
71
  cleanup: defaultWearableCleanupSettings(),
58
72
  };
59
73
  }
@@ -63,8 +77,12 @@ export function defaultWearablesConfig(): WearablesConfig {
63
77
  enabled: false,
64
78
  redactionEnabled: true,
65
79
  redactionPatterns: [],
66
- offTheRecordEnabled: false,
67
- digestEnabled: false,
80
+ offTheRecordEnabled: true,
81
+ digestEnabled: true,
82
+ autoSyncEnabled: DEFAULT_AUTO_SYNC_ENABLED,
83
+ autoSyncIntervalMinutes: DEFAULT_AUTO_SYNC_INTERVAL_MINUTES,
84
+ autoSyncDays: DEFAULT_AUTO_SYNC_DAYS,
85
+ autoSyncDeepDays: DEFAULT_AUTO_SYNC_DEEP_DAYS,
68
86
  corrections: [],
69
87
  sources: {},
70
88
  };
@@ -192,17 +210,39 @@ function parseSourceSettings(
192
210
  raw.maxMemoriesPerDay !== undefined &&
193
211
  (maxPerDayRaw === undefined ||
194
212
  !Number.isInteger(maxPerDayRaw) ||
195
- maxPerDayRaw < 0 ||
196
- maxPerDayRaw > MAX_MEMORIES_PER_DAY_CEILING)
213
+ maxPerDayRaw < 0)
197
214
  ) {
198
215
  throw new Error(
199
- `${keyPath}.maxMemoriesPerDay must be an integer between 0 and ${MAX_MEMORIES_PER_DAY_CEILING} (0 disables the cap); got ${JSON.stringify(raw.maxMemoriesPerDay)}`,
216
+ `${keyPath}.maxMemoriesPerDay must be a non-negative integer (0, the default, disables the cap); got ${JSON.stringify(raw.maxMemoriesPerDay)}`,
200
217
  );
201
218
  }
202
219
  // 0 is the documented "disable the cap" value — honored here AND in
203
220
  // the schema minimum (CLAUDE.md rule 45).
204
221
  const maxMemoriesPerDay = maxPerDayRaw ?? defaults.maxMemoriesPerDay;
205
222
 
223
+ const parseUnitInterval = (value: unknown, name: string, fallback: number): number => {
224
+ if (value === undefined) return fallback;
225
+ const coerced = coerceNumber(value);
226
+ if (coerced === undefined || coerced < 0 || coerced > 1) {
227
+ throw new Error(
228
+ `${keyPath}.${name} must be a number between 0 and 1 (got ${JSON.stringify(value)})`,
229
+ );
230
+ }
231
+ return coerced;
232
+ };
233
+ const sourceTrust = parseUnitInterval(raw.sourceTrust, "sourceTrust", defaults.sourceTrust);
234
+ const autoApproveTrust = parseUnitInterval(
235
+ raw.autoApproveTrust,
236
+ "autoApproveTrust",
237
+ defaults.autoApproveTrust,
238
+ );
239
+ const reviewTrust = parseUnitInterval(raw.reviewTrust, "reviewTrust", defaults.reviewTrust);
240
+ if (reviewTrust >= autoApproveTrust) {
241
+ throw new Error(
242
+ `${keyPath}.reviewTrust (${reviewTrust}) must be below autoApproveTrust (${autoApproveTrust})`,
243
+ );
244
+ }
245
+
206
246
  const rawCleanup =
207
247
  raw.cleanup === undefined ? {} : requireObject(raw.cleanup, `${keyPath}.cleanup`);
208
248
  const cleanup: WearableCleanupSettings = {
@@ -240,6 +280,9 @@ function parseSourceSettings(
240
280
  MEMORY_MODES,
241
281
  defaults.memoryMode,
242
282
  ),
283
+ sourceTrust,
284
+ autoApproveTrust,
285
+ reviewTrust,
243
286
  minConfidence,
244
287
  minImportance: parseEnum(
245
288
  raw.minImportance,
@@ -291,6 +334,57 @@ export function parseWearablesConfig(value: unknown): WearablesConfig {
291
334
  compileRedactionPatterns(redactionPatterns);
292
335
  }
293
336
 
337
+ const parseBoundedInt = (
338
+ value: unknown,
339
+ name: string,
340
+ fallback: number,
341
+ min: number,
342
+ max: number,
343
+ ): number => {
344
+ if (value === undefined) return fallback;
345
+ const coerced = coerceNumber(value);
346
+ if (
347
+ coerced === undefined ||
348
+ !Number.isInteger(coerced) ||
349
+ coerced < min ||
350
+ coerced > max
351
+ ) {
352
+ throw new Error(
353
+ `${name} must be an integer between ${min} and ${max}; got ${JSON.stringify(value)}`,
354
+ );
355
+ }
356
+ return coerced;
357
+ };
358
+ const autoSyncIntervalMinutes = parseBoundedInt(
359
+ raw.autoSyncIntervalMinutes,
360
+ "wearables.autoSyncIntervalMinutes",
361
+ defaults.autoSyncIntervalMinutes,
362
+ 1,
363
+ MAX_AUTO_SYNC_INTERVAL_MINUTES,
364
+ );
365
+ const autoSyncDays = parseBoundedInt(
366
+ raw.autoSyncDays,
367
+ "wearables.autoSyncDays",
368
+ defaults.autoSyncDays,
369
+ 1,
370
+ MAX_AUTO_SYNC_WINDOW_DAYS,
371
+ );
372
+ const autoSyncDeepDays = parseBoundedInt(
373
+ raw.autoSyncDeepDays,
374
+ "wearables.autoSyncDeepDays",
375
+ defaults.autoSyncDeepDays,
376
+ 0,
377
+ MAX_AUTO_SYNC_WINDOW_DAYS,
378
+ );
379
+ // A deep window narrower than the every-tick window would make the
380
+ // "deep" pass fetch LESS than a normal tick — reject the confusion
381
+ // instead of silently honoring it (0 disables the deep pass).
382
+ if (autoSyncDeepDays !== 0 && autoSyncDeepDays < autoSyncDays) {
383
+ throw new Error(
384
+ `wearables.autoSyncDeepDays must be 0 (disabled) or >= wearables.autoSyncDays (${autoSyncDays}); got ${autoSyncDeepDays}`,
385
+ );
386
+ }
387
+
294
388
  const sources: Record<string, WearableSourceSettings> = {};
295
389
  if (raw.sources !== undefined) {
296
390
  const rawSources = requireObject(raw.sources, "wearables.sources");
@@ -326,6 +420,14 @@ export function parseWearablesConfig(value: unknown): WearablesConfig {
326
420
  "wearables.digestEnabled",
327
421
  defaults.digestEnabled,
328
422
  ),
423
+ autoSyncEnabled: parseBool(
424
+ raw.autoSyncEnabled,
425
+ "wearables.autoSyncEnabled",
426
+ defaults.autoSyncEnabled,
427
+ ),
428
+ autoSyncIntervalMinutes,
429
+ autoSyncDays,
430
+ autoSyncDeepDays,
329
431
  corrections: parseCorrectionRules(raw.corrections, "wearables.corrections"),
330
432
  sources,
331
433
  };