@remnic/core 10.0.11 → 10.0.13

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 (294) hide show
  1. package/dist/access-admin-ops-surface.js +31 -31
  2. package/dist/access-authorization-probe.js +32 -32
  3. package/dist/access-boundary.js +31 -31
  4. package/dist/access-cli.js +84 -84
  5. package/dist/access-extraction-force-flush.js +31 -31
  6. package/dist/access-http-briefing.js +32 -32
  7. package/dist/access-http-query.js +33 -33
  8. package/dist/access-http.js +49 -49
  9. package/dist/access-identity-continuity-surface.js +31 -31
  10. package/dist/access-lcm-surface.js +31 -31
  11. package/dist/access-mcp.js +42 -42
  12. package/dist/access-memory-search-fanout.js +3 -3
  13. package/dist/access-namespace-preflight.js +31 -31
  14. package/dist/access-observe-write-category.js +1 -1
  15. package/dist/access-observe-write-surface.js +31 -31
  16. package/dist/access-offline-manifest.js +7 -7
  17. package/dist/access-operations-batch.js +33 -33
  18. package/dist/access-operations.js +40 -40
  19. package/dist/access-recall-concurrency.js +31 -31
  20. package/dist/access-recall-diagnostics.js +4 -4
  21. package/dist/access-recall-response.js +31 -31
  22. package/dist/access-recall-surface.js +31 -31
  23. package/dist/access-service.js +31 -31
  24. package/dist/access-surface-catalog.js +33 -33
  25. package/dist/active-memory-bridge.js +3 -3
  26. package/dist/active-recall.js +8 -8
  27. package/dist/{auto-sync-WSJAOLOP.js → auto-sync-DGJOZYGT.js} +6 -6
  28. package/dist/briefing.js +7 -7
  29. package/dist/buffer.js +6 -6
  30. package/dist/calibration.d.ts +20 -0
  31. package/dist/calibration.d.ts.map +1 -1
  32. package/dist/calibration.js +60 -13
  33. package/dist/calibration.js.map +1 -1
  34. package/dist/capabilities.d.ts +3 -2
  35. package/dist/capabilities.d.ts.map +1 -1
  36. package/dist/capabilities.js +1 -1
  37. package/dist/causal-consolidation.js +8 -8
  38. package/dist/{chunk-TCYLCPC6.js → chunk-2LUSQV4U.js} +2 -2
  39. package/dist/{chunk-EKKAHJ4B.js → chunk-2ZQJLBV6.js} +2 -2
  40. package/dist/{chunk-BX4WDBTE.js → chunk-3J5JKBYD.js} +26 -26
  41. package/dist/{chunk-XYOT5GQU.js → chunk-3NF4QUNZ.js} +3 -3
  42. package/dist/{chunk-EEDI3OXB.js → chunk-4Q26RNSR.js} +2 -2
  43. package/dist/{chunk-O52WWLKU.js → chunk-4THZGKQ2.js} +5 -5
  44. package/dist/{chunk-L3G5CGL5.js → chunk-4TTGRETU.js} +66 -22
  45. package/dist/chunk-4TTGRETU.js.map +1 -0
  46. package/dist/{chunk-MK552I5J.js → chunk-5AOAQR37.js} +3 -3
  47. package/dist/{chunk-JXWTPOMJ.js → chunk-5JCLELOP.js} +2 -2
  48. package/dist/{chunk-VBJD4RSJ.js → chunk-5MDM7UE4.js} +2 -2
  49. package/dist/{chunk-VAOC6GHN.js → chunk-5PHOU5QI.js} +2 -2
  50. package/dist/{chunk-WL7N5VGG.js → chunk-5TJEOU6Y.js} +2 -2
  51. package/dist/{chunk-I2M4ZVDD.js → chunk-5ZJYHOJT.js} +3 -3
  52. package/dist/{chunk-W4RLOZOG.js → chunk-6M56RFFJ.js} +2 -2
  53. package/dist/{chunk-YS7SA4HD.js → chunk-6OMUHXHP.js} +3 -3
  54. package/dist/{chunk-MO25AN7J.js → chunk-6OQ6N5RP.js} +14 -14
  55. package/dist/{chunk-N75Q5ZSP.js → chunk-6Z2AZ4AJ.js} +2 -2
  56. package/dist/{chunk-4G2YCKLT.js → chunk-7G5NTS7F.js} +2 -2
  57. package/dist/{chunk-E6KXJSMA.js → chunk-7KYJNHGM.js} +2 -2
  58. package/dist/{chunk-7UX44C4N.js → chunk-A2E4WNW4.js} +3 -3
  59. package/dist/{chunk-WH4QXVKU.js → chunk-A6TVQ3QP.js} +2 -2
  60. package/dist/{chunk-KJOGIRMF.js → chunk-AKREOU5F.js} +2 -2
  61. package/dist/{chunk-YYNHJF3N.js → chunk-B43NMCGQ.js} +2 -2
  62. package/dist/{chunk-PDVWGGX4.js → chunk-B7CANWCA.js} +2 -2
  63. package/dist/{chunk-AEGNDL24.js → chunk-BVRZSI7Q.js} +2 -2
  64. package/dist/{chunk-OM3RWZQK.js → chunk-BZTRPCCH.js} +2 -2
  65. package/dist/{chunk-2EMROIXS.js → chunk-C5LWPYS3.js} +2 -1
  66. package/dist/{chunk-2EMROIXS.js.map → chunk-C5LWPYS3.js.map} +1 -1
  67. package/dist/{chunk-A2L3P2IY.js → chunk-CKUUP64O.js} +2 -2
  68. package/dist/{chunk-O6YDGTH4.js → chunk-CNG2XVZG.js} +3 -3
  69. package/dist/{chunk-WXFKXCOQ.js → chunk-CS2JEHTB.js} +6 -6
  70. package/dist/{chunk-VDXTXVFZ.js → chunk-DA2INEB5.js} +4 -4
  71. package/dist/{chunk-JXSYWTFK.js → chunk-DYJHGJZ4.js} +2 -2
  72. package/dist/{chunk-LOFVW6JA.js → chunk-EGDYVYU7.js} +4 -4
  73. package/dist/{chunk-NQMG2W5L.js → chunk-EMFBC7L3.js} +2 -2
  74. package/dist/{chunk-OEIA4IHU.js → chunk-ESG6ITGP.js} +2 -2
  75. package/dist/{chunk-7XI2UJHL.js → chunk-ETZUIRCI.js} +4 -4
  76. package/dist/{chunk-VUQDJ3JB.js → chunk-FZB4TS2W.js} +2 -2
  77. package/dist/{chunk-XLIK2VDE.js → chunk-GD7BWGIB.js} +2 -2
  78. package/dist/{chunk-N6UMXWBA.js → chunk-GKIXBH7Y.js} +2 -2
  79. package/dist/{chunk-GKOML66M.js → chunk-HYNEDMYJ.js} +4 -4
  80. package/dist/{chunk-J7MDPTX7.js → chunk-IWHEJXR2.js} +189 -43
  81. package/dist/chunk-IWHEJXR2.js.map +1 -0
  82. package/dist/{chunk-VJGDQA3D.js → chunk-IZT3BVDW.js} +3 -3
  83. package/dist/{chunk-4TP3MJ3D.js → chunk-JFVCDEIC.js} +5 -5
  84. package/dist/{chunk-56GJLXBA.js → chunk-JUWJYXI4.js} +3 -3
  85. package/dist/{chunk-PPIASWWR.js → chunk-K2FSASGZ.js} +2 -2
  86. package/dist/{chunk-5X4ZJESN.js → chunk-K4QY55XV.js} +2 -2
  87. package/dist/{chunk-MB5EJ2CT.js → chunk-KC46VZR5.js} +3 -3
  88. package/dist/{chunk-CAUNCRLQ.js → chunk-KZO43HPY.js} +39 -39
  89. package/dist/{chunk-E57LYSHI.js → chunk-LZACDIM2.js} +2 -2
  90. package/dist/{chunk-QAIKLICT.js → chunk-M7KGIW5F.js} +2 -2
  91. package/dist/{chunk-UOA2VQ7C.js → chunk-M7V65M6H.js} +2 -2
  92. package/dist/{chunk-2AFHZTPI.js → chunk-NSFOERZQ.js} +2 -2
  93. package/dist/{chunk-BFIZXFUG.js → chunk-NWIT3U2N.js} +2 -2
  94. package/dist/{chunk-7SUWY37K.js → chunk-O4KYRDRT.js} +2 -2
  95. package/dist/{chunk-6OAXWYE3.js → chunk-ON4ILX3G.js} +2 -2
  96. package/dist/{chunk-55ZVZBX4.js → chunk-OYKQ6T4V.js} +4 -4
  97. package/dist/{chunk-JVNEXW6X.js → chunk-P34FDDB5.js} +2 -2
  98. package/dist/{chunk-CDWFWOSZ.js → chunk-P4JED3ZL.js} +2 -2
  99. package/dist/{chunk-OGWEWJRH.js → chunk-PCWXLAJY.js} +2 -2
  100. package/dist/{chunk-SSAXGPXY.js → chunk-QUA7RLK6.js} +2 -2
  101. package/dist/{chunk-XQIHFXYP.js → chunk-RP5SJ3XR.js} +2 -2
  102. package/dist/{chunk-J6FFBORM.js → chunk-RT6D3WN7.js} +2 -2
  103. package/dist/{chunk-SQA2MM2F.js → chunk-RWRQ67OR.js} +2 -2
  104. package/dist/{chunk-A5ZYP4K5.js → chunk-TNRCDMQT.js} +2 -2
  105. package/dist/{chunk-VA2HNBGQ.js → chunk-U7VPOXVM.js} +23 -23
  106. package/dist/{chunk-BH44JOLA.js → chunk-UOKPJFO3.js} +2 -2
  107. package/dist/{chunk-4N2MFNTG.js → chunk-UZSBCQEC.js} +2 -2
  108. package/dist/{chunk-5BUCKFRE.js → chunk-VOKHZRHW.js} +2 -2
  109. package/dist/{chunk-O5MW6CQL.js → chunk-VYPFEVOM.js} +2 -2
  110. package/dist/{chunk-E5H4TM4Y.js → chunk-WC3V7HHP.js} +3 -3
  111. package/dist/{chunk-WCTL3PVM.js → chunk-WETFW255.js} +2 -2
  112. package/dist/{chunk-OFDIGTC2.js → chunk-WWSRLS4M.js} +10 -10
  113. package/dist/{chunk-D5UPBXZM.js → chunk-X3VID2TT.js} +3 -3
  114. package/dist/{chunk-KX36OCGK.js → chunk-XERVJYH2.js} +2 -2
  115. package/dist/{chunk-KWVI52ER.js → chunk-XHWJRUVP.js} +4 -4
  116. package/dist/{chunk-SQ2O52SU.js → chunk-XRBHXUTQ.js} +7 -7
  117. package/dist/{chunk-3ZCRHW7U.js → chunk-XZLWYZ7C.js} +2 -2
  118. package/dist/{chunk-BD5QEP3T.js → chunk-Y3VDGK2O.js} +3 -3
  119. package/dist/{chunk-SOJ3IQD3.js → chunk-YEM7K3KD.js} +4 -4
  120. package/dist/{chunk-JLIGUFPF.js → chunk-YN2DQ2D6.js} +2 -2
  121. package/dist/{chunk-UCJINCZT.js → chunk-YUZRI3QU.js} +2 -2
  122. package/dist/{chunk-2U4BM3TW.js → chunk-ZIZ2G47N.js} +2 -2
  123. package/dist/{chunk-RNPJ4GQA.js → chunk-ZUMXY4KA.js} +5 -5
  124. package/dist/cli.js +62 -62
  125. package/dist/coding/export-okf-codegraph.js +6 -6
  126. package/dist/compounding/engine.d.ts +15 -11
  127. package/dist/compounding/engine.d.ts.map +1 -1
  128. package/dist/compounding/engine.js +9 -9
  129. package/dist/compounding/iso-week.d.ts +2 -0
  130. package/dist/compounding/iso-week.d.ts.map +1 -1
  131. package/dist/compounding/weekly-scheduler.d.ts +81 -0
  132. package/dist/compounding/weekly-scheduler.d.ts.map +1 -0
  133. package/dist/compounding/weekly-synthesis-queue.d.ts +9 -0
  134. package/dist/compounding/weekly-synthesis-queue.d.ts.map +1 -0
  135. package/dist/config.js +8 -8
  136. package/dist/connectors/codex-materialize-runner.js +7 -7
  137. package/dist/connectors/index.js +8 -8
  138. package/dist/contradiction/index.js +3 -3
  139. package/dist/{contradiction-scan-GGRTVB7C.js → contradiction-scan-P7KXB5R4.js} +3 -3
  140. package/dist/convergence-refresh.js +9 -9
  141. package/dist/corpus-watermark.js +9 -9
  142. package/dist/day-summary.js +2 -2
  143. package/dist/embedding-fallback.js +2 -2
  144. package/dist/entity-retrieval.js +7 -7
  145. package/dist/explicit-capture.js +2 -2
  146. package/dist/external-wiki-access.js +32 -32
  147. package/dist/extraction-judge.js +3 -3
  148. package/dist/extraction-normalization.js +3 -3
  149. package/dist/extraction-prompt.js +2 -2
  150. package/dist/extraction.js +18 -18
  151. package/dist/{first-start-migration-OM3PHMZO.js → first-start-migration-HYAMKJ6V.js} +2 -2
  152. package/dist/harmonic-retrieval.js +7 -7
  153. package/dist/index.js +84 -84
  154. package/dist/local-llm.js +2 -2
  155. package/dist/location/index.js +9 -9
  156. package/dist/maintenance/memory-governance.js +7 -7
  157. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +7 -7
  158. package/dist/maintenance/rebuild-memory-projection-runner.js +9 -9
  159. package/dist/maintenance/rebuild-memory-projection.js +8 -8
  160. package/dist/memory-browse-operations.js +32 -32
  161. package/dist/namespaces/migrate.js +8 -8
  162. package/dist/namespaces/principal.js +2 -2
  163. package/dist/namespaces/search.js +4 -4
  164. package/dist/namespaces/storage.js +7 -7
  165. package/dist/offline-sync-impression-drain.js +5 -5
  166. package/dist/operator-doctor-corpus.js +10 -10
  167. package/dist/operator-toolkit.js +20 -20
  168. package/dist/orchestration/compression-guideline-coordinator.js +2 -2
  169. package/dist/orchestration/maintenance.d.ts +2 -0
  170. package/dist/orchestration/maintenance.d.ts.map +1 -1
  171. package/dist/orchestration/maintenance.js +24 -20
  172. package/dist/orchestrator.js +84 -84
  173. package/dist/recall-navigation-operations.js +32 -32
  174. package/dist/recall-navigation.js +31 -31
  175. package/dist/recall-why-service.js +5 -5
  176. package/dist/recall-why.js +3 -3
  177. package/dist/rerank-outcome.js +2 -2
  178. package/dist/{resolution-E4GLHLY6.js → resolution-EKJHREVJ.js} +4 -4
  179. package/dist/resume-bundles.js +9 -9
  180. package/dist/search/embed-helper.js +2 -2
  181. package/dist/search/factory.js +3 -3
  182. package/dist/search/index.js +3 -3
  183. package/dist/semantic-consolidation.js +8 -8
  184. package/dist/semantic-rule-promotion.js +7 -7
  185. package/dist/semantic-rule-verifier.js +7 -7
  186. package/dist/shared-context/manager.js +2 -2
  187. package/dist/source-agent-qualifier.js +13 -13
  188. package/dist/standup/build.js +7 -7
  189. package/dist/storage.js +6 -6
  190. package/dist/summarizer.js +3 -3
  191. package/dist/support-passport/index.js +34 -34
  192. package/dist/{tier-stats-M2FMMD2N.js → tier-stats-RQM76XYY.js} +2 -2
  193. package/dist/transfer/export-okf.js +7 -7
  194. package/dist/verified-recall.js +7 -7
  195. package/dist/who-knows-cli.js +8 -8
  196. package/dist/who-knows.js +7 -7
  197. package/package.json +2 -2
  198. package/src/calibration.test.ts +80 -1
  199. package/src/calibration.ts +77 -8
  200. package/src/capabilities.test.ts +1 -0
  201. package/src/capabilities.ts +4 -4
  202. package/src/compounding/engine.ts +32 -31
  203. package/src/compounding/iso-week.ts +16 -0
  204. package/src/compounding/weekly-scheduler.test.ts +426 -0
  205. package/src/compounding/weekly-scheduler.ts +231 -0
  206. package/src/compounding/weekly-synthesis-queue.ts +23 -0
  207. package/src/orchestration/maintenance.ts +6 -2
  208. package/dist/chunk-J7MDPTX7.js.map +0 -1
  209. package/dist/chunk-L3G5CGL5.js.map +0 -1
  210. /package/dist/{auto-sync-WSJAOLOP.js.map → auto-sync-DGJOZYGT.js.map} +0 -0
  211. /package/dist/{chunk-TCYLCPC6.js.map → chunk-2LUSQV4U.js.map} +0 -0
  212. /package/dist/{chunk-EKKAHJ4B.js.map → chunk-2ZQJLBV6.js.map} +0 -0
  213. /package/dist/{chunk-BX4WDBTE.js.map → chunk-3J5JKBYD.js.map} +0 -0
  214. /package/dist/{chunk-XYOT5GQU.js.map → chunk-3NF4QUNZ.js.map} +0 -0
  215. /package/dist/{chunk-EEDI3OXB.js.map → chunk-4Q26RNSR.js.map} +0 -0
  216. /package/dist/{chunk-O52WWLKU.js.map → chunk-4THZGKQ2.js.map} +0 -0
  217. /package/dist/{chunk-MK552I5J.js.map → chunk-5AOAQR37.js.map} +0 -0
  218. /package/dist/{chunk-JXWTPOMJ.js.map → chunk-5JCLELOP.js.map} +0 -0
  219. /package/dist/{chunk-VBJD4RSJ.js.map → chunk-5MDM7UE4.js.map} +0 -0
  220. /package/dist/{chunk-VAOC6GHN.js.map → chunk-5PHOU5QI.js.map} +0 -0
  221. /package/dist/{chunk-WL7N5VGG.js.map → chunk-5TJEOU6Y.js.map} +0 -0
  222. /package/dist/{chunk-I2M4ZVDD.js.map → chunk-5ZJYHOJT.js.map} +0 -0
  223. /package/dist/{chunk-W4RLOZOG.js.map → chunk-6M56RFFJ.js.map} +0 -0
  224. /package/dist/{chunk-YS7SA4HD.js.map → chunk-6OMUHXHP.js.map} +0 -0
  225. /package/dist/{chunk-MO25AN7J.js.map → chunk-6OQ6N5RP.js.map} +0 -0
  226. /package/dist/{chunk-N75Q5ZSP.js.map → chunk-6Z2AZ4AJ.js.map} +0 -0
  227. /package/dist/{chunk-4G2YCKLT.js.map → chunk-7G5NTS7F.js.map} +0 -0
  228. /package/dist/{chunk-E6KXJSMA.js.map → chunk-7KYJNHGM.js.map} +0 -0
  229. /package/dist/{chunk-7UX44C4N.js.map → chunk-A2E4WNW4.js.map} +0 -0
  230. /package/dist/{chunk-WH4QXVKU.js.map → chunk-A6TVQ3QP.js.map} +0 -0
  231. /package/dist/{chunk-KJOGIRMF.js.map → chunk-AKREOU5F.js.map} +0 -0
  232. /package/dist/{chunk-YYNHJF3N.js.map → chunk-B43NMCGQ.js.map} +0 -0
  233. /package/dist/{chunk-PDVWGGX4.js.map → chunk-B7CANWCA.js.map} +0 -0
  234. /package/dist/{chunk-AEGNDL24.js.map → chunk-BVRZSI7Q.js.map} +0 -0
  235. /package/dist/{chunk-OM3RWZQK.js.map → chunk-BZTRPCCH.js.map} +0 -0
  236. /package/dist/{chunk-A2L3P2IY.js.map → chunk-CKUUP64O.js.map} +0 -0
  237. /package/dist/{chunk-O6YDGTH4.js.map → chunk-CNG2XVZG.js.map} +0 -0
  238. /package/dist/{chunk-WXFKXCOQ.js.map → chunk-CS2JEHTB.js.map} +0 -0
  239. /package/dist/{chunk-VDXTXVFZ.js.map → chunk-DA2INEB5.js.map} +0 -0
  240. /package/dist/{chunk-JXSYWTFK.js.map → chunk-DYJHGJZ4.js.map} +0 -0
  241. /package/dist/{chunk-LOFVW6JA.js.map → chunk-EGDYVYU7.js.map} +0 -0
  242. /package/dist/{chunk-NQMG2W5L.js.map → chunk-EMFBC7L3.js.map} +0 -0
  243. /package/dist/{chunk-OEIA4IHU.js.map → chunk-ESG6ITGP.js.map} +0 -0
  244. /package/dist/{chunk-7XI2UJHL.js.map → chunk-ETZUIRCI.js.map} +0 -0
  245. /package/dist/{chunk-VUQDJ3JB.js.map → chunk-FZB4TS2W.js.map} +0 -0
  246. /package/dist/{chunk-XLIK2VDE.js.map → chunk-GD7BWGIB.js.map} +0 -0
  247. /package/dist/{chunk-N6UMXWBA.js.map → chunk-GKIXBH7Y.js.map} +0 -0
  248. /package/dist/{chunk-GKOML66M.js.map → chunk-HYNEDMYJ.js.map} +0 -0
  249. /package/dist/{chunk-VJGDQA3D.js.map → chunk-IZT3BVDW.js.map} +0 -0
  250. /package/dist/{chunk-4TP3MJ3D.js.map → chunk-JFVCDEIC.js.map} +0 -0
  251. /package/dist/{chunk-56GJLXBA.js.map → chunk-JUWJYXI4.js.map} +0 -0
  252. /package/dist/{chunk-PPIASWWR.js.map → chunk-K2FSASGZ.js.map} +0 -0
  253. /package/dist/{chunk-5X4ZJESN.js.map → chunk-K4QY55XV.js.map} +0 -0
  254. /package/dist/{chunk-MB5EJ2CT.js.map → chunk-KC46VZR5.js.map} +0 -0
  255. /package/dist/{chunk-CAUNCRLQ.js.map → chunk-KZO43HPY.js.map} +0 -0
  256. /package/dist/{chunk-E57LYSHI.js.map → chunk-LZACDIM2.js.map} +0 -0
  257. /package/dist/{chunk-QAIKLICT.js.map → chunk-M7KGIW5F.js.map} +0 -0
  258. /package/dist/{chunk-UOA2VQ7C.js.map → chunk-M7V65M6H.js.map} +0 -0
  259. /package/dist/{chunk-2AFHZTPI.js.map → chunk-NSFOERZQ.js.map} +0 -0
  260. /package/dist/{chunk-BFIZXFUG.js.map → chunk-NWIT3U2N.js.map} +0 -0
  261. /package/dist/{chunk-7SUWY37K.js.map → chunk-O4KYRDRT.js.map} +0 -0
  262. /package/dist/{chunk-6OAXWYE3.js.map → chunk-ON4ILX3G.js.map} +0 -0
  263. /package/dist/{chunk-55ZVZBX4.js.map → chunk-OYKQ6T4V.js.map} +0 -0
  264. /package/dist/{chunk-JVNEXW6X.js.map → chunk-P34FDDB5.js.map} +0 -0
  265. /package/dist/{chunk-CDWFWOSZ.js.map → chunk-P4JED3ZL.js.map} +0 -0
  266. /package/dist/{chunk-OGWEWJRH.js.map → chunk-PCWXLAJY.js.map} +0 -0
  267. /package/dist/{chunk-SSAXGPXY.js.map → chunk-QUA7RLK6.js.map} +0 -0
  268. /package/dist/{chunk-XQIHFXYP.js.map → chunk-RP5SJ3XR.js.map} +0 -0
  269. /package/dist/{chunk-J6FFBORM.js.map → chunk-RT6D3WN7.js.map} +0 -0
  270. /package/dist/{chunk-SQA2MM2F.js.map → chunk-RWRQ67OR.js.map} +0 -0
  271. /package/dist/{chunk-A5ZYP4K5.js.map → chunk-TNRCDMQT.js.map} +0 -0
  272. /package/dist/{chunk-VA2HNBGQ.js.map → chunk-U7VPOXVM.js.map} +0 -0
  273. /package/dist/{chunk-BH44JOLA.js.map → chunk-UOKPJFO3.js.map} +0 -0
  274. /package/dist/{chunk-4N2MFNTG.js.map → chunk-UZSBCQEC.js.map} +0 -0
  275. /package/dist/{chunk-5BUCKFRE.js.map → chunk-VOKHZRHW.js.map} +0 -0
  276. /package/dist/{chunk-O5MW6CQL.js.map → chunk-VYPFEVOM.js.map} +0 -0
  277. /package/dist/{chunk-E5H4TM4Y.js.map → chunk-WC3V7HHP.js.map} +0 -0
  278. /package/dist/{chunk-WCTL3PVM.js.map → chunk-WETFW255.js.map} +0 -0
  279. /package/dist/{chunk-OFDIGTC2.js.map → chunk-WWSRLS4M.js.map} +0 -0
  280. /package/dist/{chunk-D5UPBXZM.js.map → chunk-X3VID2TT.js.map} +0 -0
  281. /package/dist/{chunk-KX36OCGK.js.map → chunk-XERVJYH2.js.map} +0 -0
  282. /package/dist/{chunk-KWVI52ER.js.map → chunk-XHWJRUVP.js.map} +0 -0
  283. /package/dist/{chunk-SQ2O52SU.js.map → chunk-XRBHXUTQ.js.map} +0 -0
  284. /package/dist/{chunk-3ZCRHW7U.js.map → chunk-XZLWYZ7C.js.map} +0 -0
  285. /package/dist/{chunk-BD5QEP3T.js.map → chunk-Y3VDGK2O.js.map} +0 -0
  286. /package/dist/{chunk-SOJ3IQD3.js.map → chunk-YEM7K3KD.js.map} +0 -0
  287. /package/dist/{chunk-JLIGUFPF.js.map → chunk-YN2DQ2D6.js.map} +0 -0
  288. /package/dist/{chunk-UCJINCZT.js.map → chunk-YUZRI3QU.js.map} +0 -0
  289. /package/dist/{chunk-2U4BM3TW.js.map → chunk-ZIZ2G47N.js.map} +0 -0
  290. /package/dist/{chunk-RNPJ4GQA.js.map → chunk-ZUMXY4KA.js.map} +0 -0
  291. /package/dist/{contradiction-scan-GGRTVB7C.js.map → contradiction-scan-P7KXB5R4.js.map} +0 -0
  292. /package/dist/{first-start-migration-OM3PHMZO.js.map → first-start-migration-HYAMKJ6V.js.map} +0 -0
  293. /package/dist/{resolution-E4GLHLY6.js.map → resolution-EKJHREVJ.js.map} +0 -0
  294. /package/dist/{tier-stats-M2FMMD2N.js.map → tier-stats-RQM76XYY.js.map} +0 -0
@@ -1,9 +1,33 @@
1
1
  import assert from "node:assert/strict";
2
+ import { mkdtemp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
2
5
  import test from "node:test";
3
6
 
4
- import { synthesizeCalibrationRules, type CorrectionMemory } from "./calibration.js";
7
+ import {
8
+ readCalibrationIndex,
9
+ runCalibrationConsolidation,
10
+ synthesizeCalibrationRules,
11
+ withAppliedCalibrationWeek,
12
+ type CalibrationRule,
13
+ type CorrectionMemory,
14
+ } from "./calibration.js";
5
15
  import type { FallbackLlmClient } from "./fallback-llm.js";
6
16
 
17
+ const existingRule: CalibrationRule = {
18
+ id: "cal-existing",
19
+ ruleType: "model_tendency",
20
+ condition: "When reporting status",
21
+ modelTendency: "It overstates progress",
22
+ userExpectation: "Report what finished",
23
+ calibration: "Name the checks that finished.",
24
+ confidence: 0.8,
25
+ evidenceCount: 2,
26
+ evidenceCorrectionIds: ["c1", "c2"],
27
+ createdAt: "2026-03-16T00:00:00.000Z",
28
+ lastReinforcedAt: "2026-03-16T00:00:00.000Z",
29
+ };
30
+
7
31
  const corrections: CorrectionMemory[] = [
8
32
  {
9
33
  id: "c1",
@@ -97,3 +121,58 @@ test("synthesizeCalibrationRules clamps confidence and filters evidence IDs", as
97
121
  assert.deepEqual(rules[1]?.evidenceCorrectionIds, []);
98
122
  assert.equal(rules[1]?.evidenceCount, 0);
99
123
  });
124
+
125
+ test("withAppliedCalibrationWeek commits the week stamp with the reinforced index", () => {
126
+ const stamped = withAppliedCalibrationWeek({
127
+ rules: [existingRule],
128
+ updatedAt: "2026-03-16T00:00:00.000Z",
129
+ totalCorrectionsAnalyzed: 4,
130
+ }, " 2026-W11 ");
131
+ assert.deepEqual(stamped.appliedWeekIds, ["2026-W11"]);
132
+ assert.equal(stamped.rules[0]?.evidenceCount, 2);
133
+
134
+ const preserved = withAppliedCalibrationWeek(stamped, " ");
135
+ assert.deepEqual(preserved.appliedWeekIds, ["2026-W11"]);
136
+ assert.deepEqual(withAppliedCalibrationWeek(stamped, "x".repeat(33)).appliedWeekIds, ["2026-W11"]);
137
+
138
+ // A later week keeps the earlier stamp: an out-of-order retry of week A
139
+ // after week B must still be recognized as already applied.
140
+ assert.deepEqual(withAppliedCalibrationWeek(stamped, "2026-W13").appliedWeekIds, ["2026-W11", "2026-W13"]);
141
+ });
142
+
143
+ test("runCalibrationConsolidation does not reinforce an already-applied week", async () => {
144
+ const memoryDir = await mkdtemp(path.join(tmpdir(), "calibration-week-"));
145
+ try {
146
+ // Legacy on-disk shape: the pre-list index persisted a single appliedWeekId.
147
+ const indexDir = path.join(memoryDir, "state", "calibration");
148
+ await mkdir(indexDir, { recursive: true });
149
+ const indexPath = path.join(indexDir, "calibration-index.json");
150
+ const body = JSON.stringify(
151
+ {
152
+ rules: [existingRule],
153
+ updatedAt: "2026-03-16T00:00:00.000Z",
154
+ totalCorrectionsAnalyzed: 3,
155
+ appliedWeekId: "2026-W11",
156
+ },
157
+ null,
158
+ 2
159
+ );
160
+ await writeFile(indexPath, body, "utf8");
161
+
162
+ // Retry of the stamped week: no reinforcement, no rewrite.
163
+ const rules = await runCalibrationConsolidation({
164
+ memoryDir,
165
+ idempotencyKey: "2026-W11",
166
+ });
167
+ assert.equal(rules[0]?.evidenceCount, 2);
168
+ assert.equal(await readFile(indexPath, "utf8"), body);
169
+
170
+ // A retry of an older week stays recognized after a newer week applied:
171
+ // the reader folds the legacy single stamp into the applied-week list.
172
+ const reread = await readCalibrationIndex(memoryDir);
173
+ assert.deepEqual(reread.appliedWeekIds, ["2026-W11"]);
174
+ assert.equal(reread.rules[0]?.evidenceCount, 2);
175
+ } finally {
176
+ await rm(memoryDir, { recursive: true, force: true });
177
+ }
178
+ });
@@ -13,7 +13,7 @@
13
13
  */
14
14
 
15
15
  import { createHash } from "node:crypto";
16
- import { mkdir, readFile, writeFile } from "node:fs/promises";
16
+ import { mkdir, readFile } from "node:fs/promises";
17
17
  import path from "node:path";
18
18
  import { resolveLocalLlmCapabilities } from "./capabilities.js";
19
19
  import { OUTPUT_LANGUAGE_POLICY } from "./extraction-prompt.js";
@@ -21,6 +21,7 @@ import { FallbackLlmClient } from "./fallback-llm.js";
21
21
  import { listJsonFiles } from "./json-store.js";
22
22
  import { LocalLlmClient } from "./local-llm.js";
23
23
  import { log } from "./logger.js";
24
+ import { writeFileAtomically } from "./maintenance/atomic-file.js";
24
25
  import type { AgentPersonaModelConfig, GatewayConfig, PluginConfig } from "./types.js";
25
26
 
26
27
  // ─── Types ───────────────────────────────────────────────────────────────────
@@ -43,6 +44,12 @@ export interface CalibrationIndex {
43
44
  rules: CalibrationRule[];
44
45
  updatedAt: string;
45
46
  totalCorrectionsAnalyzed: number;
47
+ /**
48
+ * Weeks whose rule reinforcement is already committed. A retry of any of
49
+ * these weeks must not increment `evidenceCount` again. Older indexes
50
+ * persisted a single `appliedWeekId`; reads fold it into this list.
51
+ */
52
+ appliedWeekIds?: string[];
46
53
  }
47
54
 
48
55
  // ─── Storage ─────────────────────────────────────────────────────────────────
@@ -55,24 +62,74 @@ function calibrationIndexPath(memoryDir: string): string {
55
62
  return path.join(calibrationDir(memoryDir), "calibration-index.json");
56
63
  }
57
64
 
65
+ /** Week ids are short (`YYYY-Www`). Longer values are not used as stamps. */
66
+ const MAX_APPLIED_WEEK_ID_LENGTH = 32;
67
+
68
+ export function appliedCalibrationWeekId(value: unknown): string | undefined {
69
+ if (typeof value !== "string") return undefined;
70
+ const trimmed = value.trim();
71
+ if (trimmed.length === 0 || trimmed.length > MAX_APPLIED_WEEK_ID_LENGTH) return undefined;
72
+ return trimmed;
73
+ }
74
+
58
75
  export async function readCalibrationIndex(memoryDir: string): Promise<CalibrationIndex> {
59
76
  try {
60
77
  const raw = JSON.parse(await readFile(calibrationIndexPath(memoryDir), "utf8"));
78
+ const appliedWeekIds = normalizeAppliedWeekIds(raw.appliedWeekIds, raw.appliedWeekId);
61
79
  return {
62
80
  rules: Array.isArray(raw.rules) ? raw.rules : [],
63
81
  updatedAt: typeof raw.updatedAt === "string" ? raw.updatedAt : new Date().toISOString(),
64
82
  totalCorrectionsAnalyzed: typeof raw.totalCorrectionsAnalyzed === "number" ? raw.totalCorrectionsAnalyzed : 0,
83
+ ...(appliedWeekIds.length > 0 ? { appliedWeekIds } : {}),
65
84
  };
66
85
  } catch {
67
86
  return { rules: [], updatedAt: new Date().toISOString(), totalCorrectionsAnalyzed: 0 };
68
87
  }
69
88
  }
70
89
 
90
+ function normalizeAppliedWeekIds(list: unknown, additional: unknown): string[] {
91
+ const weeks: string[] = [];
92
+ if (Array.isArray(list)) {
93
+ for (const entry of list) {
94
+ const week = appliedCalibrationWeekId(entry);
95
+ if (week && !weeks.includes(week)) weeks.push(week);
96
+ }
97
+ }
98
+ const extra = appliedCalibrationWeekId(additional);
99
+ if (extra && !weeks.includes(extra)) weeks.push(extra);
100
+ return weeks;
101
+ }
102
+
103
+ /**
104
+ * Attach the week stamp to the index that will be written with the reinforced
105
+ * rules. The stamp and the evidence increment commit together. Every
106
+ * previously applied week stays in the list so an out-of-order retry of an
107
+ * older week is still recognized as already applied.
108
+ */
109
+ export function withAppliedCalibrationWeek(
110
+ index: CalibrationIndex,
111
+ idempotencyKey: string | undefined,
112
+ ): CalibrationIndex {
113
+ const appliedWeekIds = normalizeAppliedWeekIds(index.appliedWeekIds, idempotencyKey);
114
+ return {
115
+ rules: index.rules,
116
+ updatedAt: index.updatedAt,
117
+ totalCorrectionsAnalyzed: index.totalCorrectionsAnalyzed,
118
+ ...(appliedWeekIds.length > 0 ? { appliedWeekIds } : {}),
119
+ };
120
+ }
121
+
71
122
  async function writeCalibrationIndex(memoryDir: string, index: CalibrationIndex): Promise<void> {
72
123
  const dir = calibrationDir(memoryDir);
73
124
  await mkdir(dir, { recursive: true });
74
- index.updatedAt = new Date().toISOString();
75
- await writeFile(calibrationIndexPath(memoryDir), JSON.stringify(index, null, 2), "utf8");
125
+ const appliedWeekIds = normalizeAppliedWeekIds(index.appliedWeekIds, undefined);
126
+ const stamped: CalibrationIndex = {
127
+ rules: index.rules,
128
+ updatedAt: new Date().toISOString(),
129
+ totalCorrectionsAnalyzed: index.totalCorrectionsAnalyzed,
130
+ ...(appliedWeekIds.length > 0 ? { appliedWeekIds } : {}),
131
+ };
132
+ await writeFileAtomically(calibrationIndexPath(memoryDir), JSON.stringify(stamped, null, 2));
76
133
  }
77
134
 
78
135
  // ─── Correction Reading ──────────────────────────────────────────────────────
@@ -432,8 +489,21 @@ export async function runCalibrationConsolidation(options: {
432
489
  modelChain?: AgentPersonaModelConfig;
433
490
  workspaceDir?: string;
434
491
  pluginConfig?: PluginConfig;
492
+ /**
493
+ * When set, a week whose reinforcement is already in the index is returned
494
+ * as-is. Weekly synthesis passes the ISO week id so a retry after a later
495
+ * artifact failure does not count the same corrections twice.
496
+ */
497
+ idempotencyKey?: string;
435
498
  }): Promise<CalibrationRule[]> {
436
499
  try {
500
+ const idempotencyKey = appliedCalibrationWeekId(options.idempotencyKey);
501
+ const existingIndex = await readCalibrationIndex(options.memoryDir);
502
+ if (idempotencyKey && (existingIndex.appliedWeekIds ?? []).includes(idempotencyKey)) {
503
+ log.debug(`[calibration] week ${idempotencyKey} already applied — skipping`);
504
+ return existingIndex.rules;
505
+ }
506
+
437
507
  const llm = resolveCalibrationChatClient(options);
438
508
  if (!llm) return [];
439
509
 
@@ -443,8 +513,6 @@ export async function runCalibrationConsolidation(options: {
443
513
  return [];
444
514
  }
445
515
 
446
- const existingIndex = await readCalibrationIndex(options.memoryDir);
447
-
448
516
  const newRules = await synthesizeCalibrationRules(
449
517
  corrections,
450
518
  llm,
@@ -472,11 +540,12 @@ export async function runCalibrationConsolidation(options: {
472
540
  }
473
541
 
474
542
  const allRules = [...ruleMap.values()];
475
- await writeCalibrationIndex(options.memoryDir, {
543
+ await writeCalibrationIndex(options.memoryDir, withAppliedCalibrationWeek({
476
544
  rules: allRules,
477
- updatedAt: new Date().toISOString(),
545
+ updatedAt: existingIndex.updatedAt,
478
546
  totalCorrectionsAnalyzed: corrections.length,
479
- });
547
+ appliedWeekIds: existingIndex.appliedWeekIds,
548
+ }, idempotencyKey));
480
549
 
481
550
  log.debug(`[calibration] synthesized ${newRules.length} new rule(s), ${allRules.length} total`);
482
551
  return allRules;
@@ -1090,6 +1090,7 @@ const CONSOLIDATION_FIELD_TO_FLAG: Record<keyof ConsolidationCapabilitySet, stri
1090
1090
  compoundingSemantic: "compoundingSemanticEnabled",
1091
1091
  abstractionAnchors: "abstractionAnchorsEnabled",
1092
1092
  compounding: "compoundingEnabled",
1093
+ compoundingWeeklyCron: "compoundingWeeklyCronEnabled",
1093
1094
  calibration: "calibrationEnabled",
1094
1095
  semanticConsolidation: "semanticConsolidationEnabled",
1095
1096
  patternReinforcement: "patternReinforcementEnabled",
@@ -898,8 +898,8 @@ export interface ConsolidationCapabilitySet {
898
898
  readonly compoundingSemantic: boolean;
899
899
  /** `abstractionAnchorsEnabled` — abstraction-anchor extraction. */
900
900
  readonly abstractionAnchors: boolean;
901
- /** `compoundingEnabled` — master compounding switch. */
902
- readonly compounding: boolean;
901
+ /** `compoundingEnabled` master switch; `compoundingWeeklyCronEnabled` daemon weekly run. */
902
+ readonly compounding: boolean; readonly compoundingWeeklyCron: boolean;
903
903
  /** `calibrationEnabled` — memory calibration pass. */
904
904
  readonly calibration: boolean;
905
905
  /** `semanticConsolidationEnabled` — semantic consolidation pass. */
@@ -919,7 +919,7 @@ export type ConsolidationConfigProjection = Pick<
919
919
  PluginConfig,
920
920
  "compoundingSemanticEnabled" |
921
921
  "abstractionAnchorsEnabled" |
922
- "compoundingEnabled" |
922
+ "compoundingEnabled" | "compoundingWeeklyCronEnabled" |
923
923
  "calibrationEnabled" |
924
924
  "semanticConsolidationEnabled" |
925
925
  "patternReinforcementEnabled" |
@@ -934,7 +934,7 @@ export function resolveConsolidationCapabilities(config: ConsolidationConfigProj
934
934
  return Object.freeze({
935
935
  compoundingSemantic: config.compoundingSemanticEnabled,
936
936
  abstractionAnchors: config.abstractionAnchorsEnabled,
937
- compounding: config.compoundingEnabled,
937
+ compounding: config.compoundingEnabled, compoundingWeeklyCron: config.compoundingWeeklyCronEnabled,
938
938
  calibration: config.calibrationEnabled,
939
939
  semanticConsolidation: config.semanticConsolidationEnabled,
940
940
  patternReinforcement: config.patternReinforcementEnabled,
@@ -1,7 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
3
3
  import path from "node:path";
4
- import { isoWeekId } from "./iso-week.js";
4
+ import { cadenceStaleWindowMs, isoWeekId } from "./iso-week.js";
5
5
  import { log } from "../logger.js";
6
6
  import { composeSalvagedEnvelope } from "../salvage-envelope.js";
7
7
  import { sanitizeMemoryContent } from "../sanitize.js";
@@ -11,6 +11,7 @@ import { migrateLegacyFeedbackInbox, resolveFeedbackInboxPath, type SharedFeedba
11
11
  import { parseContinuityImprovementLoops } from "../identity-continuity.js";
12
12
  import { resolveQmdCapabilities, type QmdConfigProjection, resolveConsolidationCapabilities } from "../capabilities.js";
13
13
  import { resolveConversationContextCapabilities } from "../capabilities.js";
14
+ import { writeFileAtomically } from "../maintenance/atomic-file.js";
14
15
  import {
15
16
  actionEventsVisibleInStore, capWeeklyPatternDetails,
16
17
  buildActionFailurePatterns,
@@ -24,6 +25,7 @@ import {
24
25
  type WeeklyActionEvent,
25
26
  type WeeklyCorrectionEvidence,
26
27
  } from "./weekly-evidence.js";
28
+ import { queueWeeklySynthesis } from "./weekly-synthesis-queue.js";
27
29
 
28
30
  type MistakesFile = {
29
31
  version?: number;
@@ -422,20 +424,18 @@ function monthIdFromIsoWeek(weekId: string): string {
422
424
  return isoMonthId(monday);
423
425
  }
424
426
 
425
- function cadenceStaleWindowMs(cadence: "daily" | "weekly" | "monthly" | "quarterly"): number {
426
- switch (cadence) {
427
- case "daily":
428
- return 2 * 24 * 60 * 60 * 1000;
429
- case "weekly":
430
- return 10 * 24 * 60 * 60 * 1000;
431
- case "monthly":
432
- return 45 * 24 * 60 * 60 * 1000;
433
- case "quarterly":
434
- return 120 * 24 * 60 * 60 * 1000;
435
- default:
436
- return 45 * 24 * 60 * 60 * 1000;
437
- }
438
- }
427
+ export type WeeklySynthesisOptions = { weekId?: string };
428
+
429
+ export type WeeklySynthesisResult = {
430
+ weekId: string;
431
+ reportPath: string;
432
+ reportJsonPath: string;
433
+ mistakesCount: number;
434
+ rubricsPath: string;
435
+ rubricsIndexPath: string;
436
+ promotionCandidateCount: number;
437
+ };
438
+
439
439
 
440
440
  export class CompoundingEngine {
441
441
  private readonly weeklyDir: string;
@@ -474,17 +474,12 @@ export class CompoundingEngine {
474
474
  await mkdir(this.rubricsWorkflowsDir, { recursive: true });
475
475
  }
476
476
 
477
- async synthesizeWeekly(opts?: {
478
- weekId?: string;
479
- }): Promise<{
480
- weekId: string;
481
- reportPath: string;
482
- reportJsonPath: string;
483
- mistakesCount: number;
484
- rubricsPath: string;
485
- rubricsIndexPath: string;
486
- promotionCandidateCount: number;
487
- }> {
477
+ /** Serialized per memory directory — see weekly-synthesis-queue.ts. */
478
+ async synthesizeWeekly(opts?: WeeklySynthesisOptions): Promise<WeeklySynthesisResult> {
479
+ return await queueWeeklySynthesis(this.config.memoryDir, () => this.synthesizeWeeklyExclusive(opts));
480
+ }
481
+
482
+ private async synthesizeWeeklyExclusive(opts?: WeeklySynthesisOptions): Promise<WeeklySynthesisResult> {
488
483
  await this.ensureDirs();
489
484
  const weekId = opts?.weekId ?? isoWeekId(new Date());
490
485
 
@@ -559,11 +554,16 @@ export class CompoundingEngine {
559
554
  log.warn(`[cmc] causal consolidation in synthesizeWeekly failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);
560
555
  }
561
556
  }
562
- // PEDC: Run calibration consolidation during weekly synthesis
563
- if (resolveConsolidationCapabilities(this.config).calibration) {
557
+ // PEDC: calibration consolidation, keyed by the week id so a retry does
558
+ // not reinforce the same rules. Only a completed week consolidates: a
559
+ // manual in-progress-week run must not double-count partial evidence.
560
+ if (resolveConsolidationCapabilities(this.config).calibration && weekId < isoWeekId(new Date())) {
564
561
  try {
565
562
  const { calibrationConsolidationInput, runCalibrationConsolidation } = await import("../calibration.js");
566
- const calRules = await runCalibrationConsolidation(calibrationConsolidationInput(this.config));
563
+ const calRules = await runCalibrationConsolidation({
564
+ ...calibrationConsolidationInput(this.config),
565
+ idempotencyKey: weekId,
566
+ });
567
567
  log.debug(`[calibration] weekly synthesis produced ${calRules.length} calibration rule(s)`);
568
568
  } catch (error) {
569
569
  log.warn(`[calibration] weekly consolidation failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);
@@ -573,10 +573,10 @@ export class CompoundingEngine {
573
573
  ? await this.readContinuityAuditReferences(weekId)
574
574
  : { monthId: monthIdFromIsoWeek(weekId), weeklyPath: null, monthlyPath: null };
575
575
 
576
- // Write weekly report (always, even if empty: "day-one outcomes").
576
+ // The markdown report is the completion marker, so it is written after the
577
+ // JSON, rubrics, and mistakes artifacts. A crash before that write retries.
577
578
  const reportPath = path.join(this.weeklyDir, `${weekId}.md`);
578
579
  const md = this.formatWeeklyReport(weekId, entries, mistakes.patterns, mistakes.details, continuity, outcomeSummary, promotionCandidates);
579
- await writeFile(reportPath, md, "utf-8");
580
580
 
581
581
  const reportJsonPath = path.join(this.weeklyDir, `${weekId}.json`);
582
582
  const weeklyArtifact: WeeklyCompoundingArtifact = {
@@ -633,6 +633,7 @@ export class CompoundingEngine {
633
633
  }, null, 2) + "\n",
634
634
  "utf-8",
635
635
  );
636
+ await writeFileAtomically(reportPath, md);
636
637
 
637
638
  log.info(
638
639
  `compounding: wrote weekly=${reportPath} weeklyJson=${reportJsonPath} rubrics=${this.rubricsPath} rubricsIndex=${this.rubricsIndexPath} mistakes=${this.mistakesPath}`,
@@ -58,3 +58,19 @@ export function isIsoWeekId(weekId: string): boolean {
58
58
  const weekNum = Number(week);
59
59
  return weekNum >= 1 && weekNum <= 53;
60
60
  }
61
+
62
+ /** How long a rubric cadence may go unreviewed before it counts as stale. */
63
+ export function cadenceStaleWindowMs(cadence: "daily" | "weekly" | "monthly" | "quarterly"): number {
64
+ switch (cadence) {
65
+ case "daily":
66
+ return 2 * 24 * 60 * 60 * 1000;
67
+ case "weekly":
68
+ return 10 * 24 * 60 * 60 * 1000;
69
+ case "monthly":
70
+ return 45 * 24 * 60 * 60 * 1000;
71
+ case "quarterly":
72
+ return 120 * 24 * 60 * 60 * 1000;
73
+ default:
74
+ return 45 * 24 * 60 * 60 * 1000;
75
+ }
76
+ }