@remnic/core 10.0.50 → 10.0.52

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 (272) hide show
  1. package/dist/access-admin-ops-surface.js +22 -22
  2. package/dist/access-authorization-probe.js +23 -23
  3. package/dist/access-boundary.d.ts +6 -1
  4. package/dist/access-boundary.d.ts.map +1 -1
  5. package/dist/access-boundary.js +22 -22
  6. package/dist/access-cli.js +68 -68
  7. package/dist/access-errors.d.ts.map +1 -1
  8. package/dist/access-errors.js +1 -1
  9. package/dist/access-extraction-force-flush.js +22 -22
  10. package/dist/access-http-briefing.js +23 -23
  11. package/dist/access-http-query.js +24 -24
  12. package/dist/access-http.js +42 -42
  13. package/dist/access-identity-continuity-surface.js +22 -22
  14. package/dist/access-lcm-surface.js +22 -22
  15. package/dist/access-mcp.js +32 -32
  16. package/dist/access-memory-search-fanout.js +2 -2
  17. package/dist/access-namespace-preflight.js +22 -22
  18. package/dist/access-observe-write-category.js +2 -2
  19. package/dist/access-observe-write-surface.js +22 -22
  20. package/dist/access-offline-manifest.js +2 -2
  21. package/dist/access-operations-batch.js +23 -23
  22. package/dist/access-operations.js +30 -30
  23. package/dist/access-recall-concurrency.js +22 -22
  24. package/dist/access-recall-diagnostics.js +2 -2
  25. package/dist/access-recall-response.js +22 -22
  26. package/dist/access-recall-surface.js +22 -22
  27. package/dist/access-schema.d.ts +245 -773
  28. package/dist/access-schema.d.ts.map +1 -1
  29. package/dist/access-schema.js +1 -1
  30. package/dist/access-service.js +22 -22
  31. package/dist/access-surface-catalog.js +24 -24
  32. package/dist/access-token-capabilities.js +2 -2
  33. package/dist/active-recall.js +5 -5
  34. package/dist/briefing.js +3 -3
  35. package/dist/causal-consolidation.js +4 -4
  36. package/dist/{chunk-7YVER7ZO.js → chunk-2EXF6IIB.js} +2 -2
  37. package/dist/{chunk-HPNXS6W6.js → chunk-2ONKXEC7.js} +3 -3
  38. package/dist/{chunk-DMKTOCC7.js → chunk-2S6JADBB.js} +2 -2
  39. package/dist/{chunk-ZSEFGDCI.js → chunk-2TGIKMMZ.js} +2 -2
  40. package/dist/{chunk-Q3PNQYAC.js → chunk-44EUCSG4.js} +2 -2
  41. package/dist/{chunk-PJCVI44H.js → chunk-4FM35YIA.js} +3 -3
  42. package/dist/{chunk-M6TP6UYD.js → chunk-6ZAU7LAR.js} +2 -2
  43. package/dist/{chunk-SJTSWG2Z.js → chunk-72CBJ5VP.js} +3 -3
  44. package/dist/{chunk-EKYWZYZJ.js → chunk-75BK4XGV.js} +17 -17
  45. package/dist/{chunk-HKOMHP6D.js → chunk-A6JDT6QF.js} +2 -2
  46. package/dist/{chunk-TFWJXWL6.js → chunk-AHGOOZUC.js} +2 -2
  47. package/dist/{chunk-A7AISUJI.js → chunk-AJG2TAMR.js} +2 -2
  48. package/dist/{chunk-VCOMACR6.js → chunk-AZLD4CKG.js} +19 -19
  49. package/dist/{chunk-GXVXBYRA.js → chunk-B35EQQ7L.js} +3 -3
  50. package/dist/{chunk-E6UNM67F.js → chunk-B6SPPYGJ.js} +2 -2
  51. package/dist/{chunk-TXKQBQYW.js → chunk-CK6GCGMX.js} +3 -3
  52. package/dist/{chunk-NPLM7AFU.js → chunk-DF6ZF2BN.js} +3 -3
  53. package/dist/{chunk-6ZQX3R66.js → chunk-DJFULNXK.js} +4 -4
  54. package/dist/{chunk-JBWD3J5U.js → chunk-DQOGZZJA.js} +3 -3
  55. package/dist/{chunk-K5QQXVG6.js → chunk-EC2KVA27.js} +7 -7
  56. package/dist/{chunk-N74WJ7B2.js → chunk-EZS6QJNC.js} +2 -2
  57. package/dist/{chunk-MWURUSRE.js → chunk-FNNGWN3O.js} +2 -2
  58. package/dist/{chunk-5FUDSK6Z.js → chunk-FT75AQ74.js} +3 -3
  59. package/dist/{chunk-ZMO2S5RT.js → chunk-G6A3SGCE.js} +3 -3
  60. package/dist/chunk-G6A3SGCE.js.map +1 -0
  61. package/dist/{chunk-IMKOJVD4.js → chunk-GBGU5OZP.js} +52 -51
  62. package/dist/chunk-GBGU5OZP.js.map +1 -0
  63. package/dist/{chunk-5X2H3X4J.js → chunk-GE3ZX6YK.js} +2 -2
  64. package/dist/{chunk-UNOAVHV4.js → chunk-HCIRR3BA.js} +3 -3
  65. package/dist/{chunk-MLNXATFG.js → chunk-HEF4BRMT.js} +3 -3
  66. package/dist/{chunk-Z5277JWF.js → chunk-HQUYENKK.js} +7 -10
  67. package/dist/chunk-HQUYENKK.js.map +1 -0
  68. package/dist/{chunk-6UDLN4IA.js → chunk-I6ORDT54.js} +2 -2
  69. package/dist/{chunk-M4HRYLOA.js → chunk-IUQXRRJB.js} +3 -3
  70. package/dist/{chunk-GQIYL7OD.js → chunk-JIJAWTRK.js} +3 -3
  71. package/dist/{chunk-4KS4IHKH.js → chunk-JX3E4XCW.js} +2 -2
  72. package/dist/{chunk-ZFNXJEUG.js → chunk-KAJYSO3U.js} +2 -2
  73. package/dist/{chunk-QS765SBL.js → chunk-KETS5A62.js} +2 -2
  74. package/dist/{chunk-N7FNCE7F.js → chunk-KIWO4327.js} +2 -2
  75. package/dist/{chunk-FC3ZFEXF.js → chunk-KJ3MDX4V.js} +2 -2
  76. package/dist/{chunk-BNJAVRNJ.js → chunk-L3EFYRYK.js} +8 -8
  77. package/dist/{chunk-3MUKQQ7A.js → chunk-LGEH473S.js} +24 -29
  78. package/dist/chunk-LGEH473S.js.map +1 -0
  79. package/dist/{chunk-P7OVFGMU.js → chunk-LMB47UM6.js} +2 -2
  80. package/dist/{chunk-7SAE6T36.js → chunk-LWMLBVGB.js} +2 -2
  81. package/dist/{chunk-ZNRTHYYW.js → chunk-MC7PXJDP.js} +7 -7
  82. package/dist/{chunk-M2DOJBH7.js → chunk-MUNYUSBU.js} +2 -2
  83. package/dist/{chunk-LMMBV7QC.js → chunk-OCRLJJOV.js} +4 -4
  84. package/dist/{chunk-7J6A5MV2.js → chunk-ON77FQXH.js} +2 -2
  85. package/dist/{chunk-WV4UYDP6.js → chunk-POJRFSJM.js} +3 -3
  86. package/dist/{chunk-LKRXGOQW.js → chunk-QA3Y2O6H.js} +2 -2
  87. package/dist/{chunk-23ZLN5X6.js → chunk-QT5MGENX.js} +14 -6
  88. package/dist/chunk-QT5MGENX.js.map +1 -0
  89. package/dist/{chunk-YECEEJUU.js → chunk-RA7YRL6H.js} +2 -2
  90. package/dist/{chunk-UALXWWGN.js → chunk-RJDYDF5K.js} +4 -4
  91. package/dist/{chunk-WXJC2L66.js → chunk-ROAKLYOL.js} +2 -2
  92. package/dist/{chunk-NWIT3U2N.js → chunk-S5CQI2KF.js} +2 -2
  93. package/dist/{chunk-P6P35FY4.js → chunk-SDESKFKT.js} +2 -2
  94. package/dist/{chunk-UXGXJUZ5.js → chunk-SFRBUBUZ.js} +7 -7
  95. package/dist/{chunk-CRN3EPE2.js → chunk-SHNM7RIT.js} +3 -3
  96. package/dist/{chunk-XC3H7KON.js → chunk-SPTPBKZX.js} +2 -2
  97. package/dist/{chunk-IUYXCTA7.js → chunk-TC55M5PO.js} +2 -2
  98. package/dist/{chunk-EWBXMGXR.js → chunk-UCLJTGP3.js} +2 -2
  99. package/dist/{chunk-UZVQFGAY.js → chunk-UM3ZLT2X.js} +206 -165
  100. package/dist/chunk-UM3ZLT2X.js.map +1 -0
  101. package/dist/{chunk-754XN6LX.js → chunk-V27FK6D6.js} +2 -2
  102. package/dist/{chunk-LIBVANOF.js → chunk-V6Z4NAJZ.js} +2 -2
  103. package/dist/{chunk-XTXWR6KQ.js → chunk-VUMWVYMR.js} +7 -7
  104. package/dist/{chunk-ZSMA67FV.js → chunk-WY66J4PI.js} +2 -2
  105. package/dist/{chunk-5G53JSRO.js → chunk-XWJUFER3.js} +3 -3
  106. package/dist/{chunk-NSP5PIQH.js → chunk-Y3T5KQCR.js} +2 -2
  107. package/dist/{chunk-QTDZ2NYC.js → chunk-Y77FXULH.js} +2 -2
  108. package/dist/{chunk-IG747LRN.js → chunk-YO2JEX2Z.js} +2 -2
  109. package/dist/{chunk-KW5YZELC.js → chunk-ZKK3VMWU.js} +2 -2
  110. package/dist/cli.js +55 -55
  111. package/dist/coding/export-okf-codegraph.js +2 -2
  112. package/dist/compounding/engine.js +4 -4
  113. package/dist/config.js +5 -5
  114. package/dist/connectors/codex-materialize-runner.js +3 -3
  115. package/dist/connectors/index.js +7 -7
  116. package/dist/convergence-refresh.js +5 -5
  117. package/dist/corpus-watermark.js +7 -7
  118. package/dist/deep-recall-config.js +2 -2
  119. package/dist/deep-recall-http-glue.js +4 -4
  120. package/dist/{entity-canonical-id-migration-ZBNRGUNV.js → entity-canonical-id-migration-F3JVG6K6.js} +2 -2
  121. package/dist/entity-retrieval.js +3 -3
  122. package/dist/external-wiki-access.js +23 -23
  123. package/dist/extraction-span-wire.d.ts.map +1 -1
  124. package/dist/extraction-span-wire.js +1 -1
  125. package/dist/extraction.js +11 -11
  126. package/dist/harmonic-retrieval.js +3 -3
  127. package/dist/index.js +68 -68
  128. package/dist/location/index.js +6 -6
  129. package/dist/maintenance/memory-governance.js +3 -3
  130. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  131. package/dist/maintenance/rebuild-memory-projection-runner.js +5 -5
  132. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  133. package/dist/memory-browse-http-glue.js +2 -2
  134. package/dist/memory-browse-operations.js +23 -23
  135. package/dist/namespaces/migrate.js +4 -4
  136. package/dist/namespaces/storage.js +3 -3
  137. package/dist/offline-sync-impression-drain.js +2 -2
  138. package/dist/operator-doctor-corpus.js +10 -10
  139. package/dist/operator-doctor-replica.js +4 -4
  140. package/dist/operator-toolkit.js +17 -17
  141. package/dist/orchestration/extraction-persist-deps.d.ts +2 -0
  142. package/dist/orchestration/extraction-persist-deps.d.ts.map +1 -1
  143. package/dist/orchestration/extraction-persist-promotion.d.ts +40 -10
  144. package/dist/orchestration/extraction-persist-promotion.d.ts.map +1 -1
  145. package/dist/orchestration/extraction-persist.d.ts.map +1 -1
  146. package/dist/orchestration/maintenance.js +15 -15
  147. package/dist/orchestrator.d.ts.map +1 -1
  148. package/dist/orchestrator.js +68 -68
  149. package/dist/recall-navigation-http-glue.js +2 -2
  150. package/dist/recall-navigation-operations.js +23 -23
  151. package/dist/recall-navigation.js +22 -22
  152. package/dist/relay/mission.d.ts +731 -3403
  153. package/dist/relay/mission.d.ts.map +1 -1
  154. package/dist/replica-divergence.js +3 -3
  155. package/dist/resume-bundles.js +6 -6
  156. package/dist/schemas.d.ts +346 -1771
  157. package/dist/schemas.d.ts.map +1 -1
  158. package/dist/semantic-consolidation.js +4 -4
  159. package/dist/semantic-rule-promotion.js +3 -3
  160. package/dist/semantic-rule-verifier.js +3 -3
  161. package/dist/shared-context/manager.d.ts +13 -33
  162. package/dist/shared-context/manager.d.ts.map +1 -1
  163. package/dist/source-agent-qualifier.js +9 -9
  164. package/dist/standup/build.js +4 -4
  165. package/dist/storage.js +2 -2
  166. package/dist/support-passport/access-operations.d.ts +51 -51
  167. package/dist/support-passport/contracts.d.ts +85 -126
  168. package/dist/support-passport/contracts.d.ts.map +1 -1
  169. package/dist/support-passport/generated-batch.d.ts +3 -17
  170. package/dist/support-passport/generated-batch.d.ts.map +1 -1
  171. package/dist/support-passport/grant-contracts.d.ts +75 -381
  172. package/dist/support-passport/grant-contracts.d.ts.map +1 -1
  173. package/dist/support-passport/index.js +25 -25
  174. package/dist/support-passport/model-audit.d.ts +17 -82
  175. package/dist/support-passport/model-audit.d.ts.map +1 -1
  176. package/dist/support-passport/model-bridge.d.ts +12 -51
  177. package/dist/support-passport/model-bridge.d.ts.map +1 -1
  178. package/dist/support-passport/model-contracts.d.ts +53 -192
  179. package/dist/support-passport/model-contracts.d.ts.map +1 -1
  180. package/dist/tokens.js +3 -3
  181. package/dist/transfer/export-okf.js +3 -3
  182. package/dist/transfer/types.d.ts +32 -737
  183. package/dist/transfer/types.d.ts.map +1 -1
  184. package/dist/verified-recall.js +3 -3
  185. package/dist/who-knows-cli.js +5 -5
  186. package/dist/who-knows.js +4 -4
  187. package/package.json +3 -4
  188. package/src/access-boundary.test.ts +14 -0
  189. package/src/access-boundary.ts +48 -42
  190. package/src/access-category-alias.test.ts +9 -7
  191. package/src/access-errors.test.ts +21 -9
  192. package/src/access-errors.ts +45 -31
  193. package/src/access-http.test.ts +1 -1
  194. package/src/access-schema.ts +13 -17
  195. package/src/extraction-scope-source-agent.test.ts +6 -6
  196. package/src/extraction-span-wire.test.ts +28 -0
  197. package/src/extraction-span-wire.ts +34 -6
  198. package/src/orchestration/extraction-persist-deps.ts +3 -0
  199. package/src/orchestration/extraction-persist-promotion.ts +104 -16
  200. package/src/orchestration/extraction-persist.ts +66 -77
  201. package/src/orchestrator-entity-write-failure.test.ts +370 -0
  202. package/src/orchestrator.ts +1 -0
  203. package/src/storage/entity-canonical-id-migration.ts +2 -2
  204. package/dist/chunk-23ZLN5X6.js.map +0 -1
  205. package/dist/chunk-3MUKQQ7A.js.map +0 -1
  206. package/dist/chunk-IMKOJVD4.js.map +0 -1
  207. package/dist/chunk-UZVQFGAY.js.map +0 -1
  208. package/dist/chunk-Z5277JWF.js.map +0 -1
  209. package/dist/chunk-ZMO2S5RT.js.map +0 -1
  210. /package/dist/{chunk-7YVER7ZO.js.map → chunk-2EXF6IIB.js.map} +0 -0
  211. /package/dist/{chunk-HPNXS6W6.js.map → chunk-2ONKXEC7.js.map} +0 -0
  212. /package/dist/{chunk-DMKTOCC7.js.map → chunk-2S6JADBB.js.map} +0 -0
  213. /package/dist/{chunk-ZSEFGDCI.js.map → chunk-2TGIKMMZ.js.map} +0 -0
  214. /package/dist/{chunk-Q3PNQYAC.js.map → chunk-44EUCSG4.js.map} +0 -0
  215. /package/dist/{chunk-PJCVI44H.js.map → chunk-4FM35YIA.js.map} +0 -0
  216. /package/dist/{chunk-M6TP6UYD.js.map → chunk-6ZAU7LAR.js.map} +0 -0
  217. /package/dist/{chunk-SJTSWG2Z.js.map → chunk-72CBJ5VP.js.map} +0 -0
  218. /package/dist/{chunk-EKYWZYZJ.js.map → chunk-75BK4XGV.js.map} +0 -0
  219. /package/dist/{chunk-HKOMHP6D.js.map → chunk-A6JDT6QF.js.map} +0 -0
  220. /package/dist/{chunk-TFWJXWL6.js.map → chunk-AHGOOZUC.js.map} +0 -0
  221. /package/dist/{chunk-A7AISUJI.js.map → chunk-AJG2TAMR.js.map} +0 -0
  222. /package/dist/{chunk-VCOMACR6.js.map → chunk-AZLD4CKG.js.map} +0 -0
  223. /package/dist/{chunk-GXVXBYRA.js.map → chunk-B35EQQ7L.js.map} +0 -0
  224. /package/dist/{chunk-E6UNM67F.js.map → chunk-B6SPPYGJ.js.map} +0 -0
  225. /package/dist/{chunk-TXKQBQYW.js.map → chunk-CK6GCGMX.js.map} +0 -0
  226. /package/dist/{chunk-NPLM7AFU.js.map → chunk-DF6ZF2BN.js.map} +0 -0
  227. /package/dist/{chunk-6ZQX3R66.js.map → chunk-DJFULNXK.js.map} +0 -0
  228. /package/dist/{chunk-JBWD3J5U.js.map → chunk-DQOGZZJA.js.map} +0 -0
  229. /package/dist/{chunk-K5QQXVG6.js.map → chunk-EC2KVA27.js.map} +0 -0
  230. /package/dist/{chunk-N74WJ7B2.js.map → chunk-EZS6QJNC.js.map} +0 -0
  231. /package/dist/{chunk-MWURUSRE.js.map → chunk-FNNGWN3O.js.map} +0 -0
  232. /package/dist/{chunk-5FUDSK6Z.js.map → chunk-FT75AQ74.js.map} +0 -0
  233. /package/dist/{chunk-5X2H3X4J.js.map → chunk-GE3ZX6YK.js.map} +0 -0
  234. /package/dist/{chunk-UNOAVHV4.js.map → chunk-HCIRR3BA.js.map} +0 -0
  235. /package/dist/{chunk-MLNXATFG.js.map → chunk-HEF4BRMT.js.map} +0 -0
  236. /package/dist/{chunk-6UDLN4IA.js.map → chunk-I6ORDT54.js.map} +0 -0
  237. /package/dist/{chunk-M4HRYLOA.js.map → chunk-IUQXRRJB.js.map} +0 -0
  238. /package/dist/{chunk-GQIYL7OD.js.map → chunk-JIJAWTRK.js.map} +0 -0
  239. /package/dist/{chunk-4KS4IHKH.js.map → chunk-JX3E4XCW.js.map} +0 -0
  240. /package/dist/{chunk-ZFNXJEUG.js.map → chunk-KAJYSO3U.js.map} +0 -0
  241. /package/dist/{chunk-QS765SBL.js.map → chunk-KETS5A62.js.map} +0 -0
  242. /package/dist/{chunk-N7FNCE7F.js.map → chunk-KIWO4327.js.map} +0 -0
  243. /package/dist/{chunk-FC3ZFEXF.js.map → chunk-KJ3MDX4V.js.map} +0 -0
  244. /package/dist/{chunk-BNJAVRNJ.js.map → chunk-L3EFYRYK.js.map} +0 -0
  245. /package/dist/{chunk-P7OVFGMU.js.map → chunk-LMB47UM6.js.map} +0 -0
  246. /package/dist/{chunk-7SAE6T36.js.map → chunk-LWMLBVGB.js.map} +0 -0
  247. /package/dist/{chunk-ZNRTHYYW.js.map → chunk-MC7PXJDP.js.map} +0 -0
  248. /package/dist/{chunk-M2DOJBH7.js.map → chunk-MUNYUSBU.js.map} +0 -0
  249. /package/dist/{chunk-LMMBV7QC.js.map → chunk-OCRLJJOV.js.map} +0 -0
  250. /package/dist/{chunk-7J6A5MV2.js.map → chunk-ON77FQXH.js.map} +0 -0
  251. /package/dist/{chunk-WV4UYDP6.js.map → chunk-POJRFSJM.js.map} +0 -0
  252. /package/dist/{chunk-LKRXGOQW.js.map → chunk-QA3Y2O6H.js.map} +0 -0
  253. /package/dist/{chunk-YECEEJUU.js.map → chunk-RA7YRL6H.js.map} +0 -0
  254. /package/dist/{chunk-UALXWWGN.js.map → chunk-RJDYDF5K.js.map} +0 -0
  255. /package/dist/{chunk-WXJC2L66.js.map → chunk-ROAKLYOL.js.map} +0 -0
  256. /package/dist/{chunk-NWIT3U2N.js.map → chunk-S5CQI2KF.js.map} +0 -0
  257. /package/dist/{chunk-P6P35FY4.js.map → chunk-SDESKFKT.js.map} +0 -0
  258. /package/dist/{chunk-UXGXJUZ5.js.map → chunk-SFRBUBUZ.js.map} +0 -0
  259. /package/dist/{chunk-CRN3EPE2.js.map → chunk-SHNM7RIT.js.map} +0 -0
  260. /package/dist/{chunk-XC3H7KON.js.map → chunk-SPTPBKZX.js.map} +0 -0
  261. /package/dist/{chunk-IUYXCTA7.js.map → chunk-TC55M5PO.js.map} +0 -0
  262. /package/dist/{chunk-EWBXMGXR.js.map → chunk-UCLJTGP3.js.map} +0 -0
  263. /package/dist/{chunk-754XN6LX.js.map → chunk-V27FK6D6.js.map} +0 -0
  264. /package/dist/{chunk-LIBVANOF.js.map → chunk-V6Z4NAJZ.js.map} +0 -0
  265. /package/dist/{chunk-XTXWR6KQ.js.map → chunk-VUMWVYMR.js.map} +0 -0
  266. /package/dist/{chunk-ZSMA67FV.js.map → chunk-WY66J4PI.js.map} +0 -0
  267. /package/dist/{chunk-5G53JSRO.js.map → chunk-XWJUFER3.js.map} +0 -0
  268. /package/dist/{chunk-NSP5PIQH.js.map → chunk-Y3T5KQCR.js.map} +0 -0
  269. /package/dist/{chunk-QTDZ2NYC.js.map → chunk-Y77FXULH.js.map} +0 -0
  270. /package/dist/{chunk-IG747LRN.js.map → chunk-YO2JEX2Z.js.map} +0 -0
  271. /package/dist/{chunk-KW5YZELC.js.map → chunk-ZKK3VMWU.js.map} +0 -0
  272. /package/dist/{entity-canonical-id-migration-ZBNRGUNV.js.map → entity-canonical-id-migration-F3JVG6K6.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transfer/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transfer/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,sBAAsB;;;;;;;;;;;iBAajC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,0BAA0B;;;iBAGrC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;iBAG/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAWlE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,QAAkE,CAAC;AA+BlG,eAAO,MAAM,4BAA4B;;;iBAiBvC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,eAAO,MAAM,qBAAqB;;;;;iBAKhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB;;;;iBAe9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;iBAoC7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAcjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAG/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAMlE,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AACpE,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,cAAc,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC;IACtB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAqC5E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG;IACjD,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B,CAcA"}
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  compareVerifiedEpisodeResults,
3
3
  searchVerifiedEpisodes
4
- } from "./chunk-WXJC2L66.js";
4
+ } from "./chunk-ROAKLYOL.js";
5
5
  import "./chunk-B7RWBZXW.js";
6
- import "./chunk-GQIYL7OD.js";
6
+ import "./chunk-JIJAWTRK.js";
7
7
  import "./chunk-UHVXE24Y.js";
8
8
  import "./chunk-DM5QZ3YU.js";
9
- import "./chunk-ZMO2S5RT.js";
9
+ import "./chunk-G6A3SGCE.js";
10
10
  import "./chunk-G6OFEGUR.js";
11
11
  import "./chunk-LXXIV7Y2.js";
12
12
  import "./chunk-JS44PBCM.js";
@@ -4,12 +4,12 @@ import {
4
4
  renderWhoKnows,
5
5
  renderWhoKnowsJson,
6
6
  renderWhoKnowsText
7
- } from "./chunk-IUYXCTA7.js";
8
- import "./chunk-HPNXS6W6.js";
9
- import "./chunk-GQIYL7OD.js";
7
+ } from "./chunk-TC55M5PO.js";
8
+ import "./chunk-2ONKXEC7.js";
9
+ import "./chunk-JIJAWTRK.js";
10
10
  import "./chunk-UHVXE24Y.js";
11
11
  import "./chunk-DM5QZ3YU.js";
12
- import "./chunk-ZMO2S5RT.js";
12
+ import "./chunk-G6A3SGCE.js";
13
13
  import "./chunk-G6OFEGUR.js";
14
14
  import "./chunk-LXXIV7Y2.js";
15
15
  import "./chunk-JS44PBCM.js";
@@ -104,7 +104,7 @@ import "./chunk-X4OZMANG.js";
104
104
  import "./chunk-ZEFVK7XC.js";
105
105
  import "./chunk-6KH5NLQS.js";
106
106
  import "./chunk-P2QRMMVQ.js";
107
- import "./chunk-3MUKQQ7A.js";
107
+ import "./chunk-LGEH473S.js";
108
108
  import "./chunk-R2MBW2S4.js";
109
109
  import "./chunk-QUIRIG2P.js";
110
110
  import "./chunk-LDPPTPO5.js";
package/dist/who-knows.js CHANGED
@@ -9,11 +9,11 @@ import {
9
9
  loadWhoKnowsEntities,
10
10
  tokenizeTopic,
11
11
  validateWhoKnowsInput
12
- } from "./chunk-HPNXS6W6.js";
13
- import "./chunk-GQIYL7OD.js";
12
+ } from "./chunk-2ONKXEC7.js";
13
+ import "./chunk-JIJAWTRK.js";
14
14
  import "./chunk-UHVXE24Y.js";
15
15
  import "./chunk-DM5QZ3YU.js";
16
- import "./chunk-ZMO2S5RT.js";
16
+ import "./chunk-G6A3SGCE.js";
17
17
  import "./chunk-G6OFEGUR.js";
18
18
  import "./chunk-LXXIV7Y2.js";
19
19
  import "./chunk-JS44PBCM.js";
@@ -108,7 +108,7 @@ import "./chunk-X4OZMANG.js";
108
108
  import "./chunk-ZEFVK7XC.js";
109
109
  import "./chunk-6KH5NLQS.js";
110
110
  import "./chunk-P2QRMMVQ.js";
111
- import "./chunk-3MUKQQ7A.js";
111
+ import "./chunk-LGEH473S.js";
112
112
  import "./chunk-R2MBW2S4.js";
113
113
  import "./chunk-QUIRIG2P.js";
114
114
  import "./chunk-LDPPTPO5.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "10.0.50",
3
+ "version": "10.0.52",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -3318,8 +3318,7 @@
3318
3318
  "node-gyp": "^12.3.0",
3319
3319
  "openai": "^6.0.0",
3320
3320
  "undici": "^6.29.1",
3321
- "zod": "^3.25.28",
3322
- "zod-to-json-schema": "^3.25.2"
3321
+ "zod": "^4.6.6"
3323
3322
  },
3324
3323
  "optionalDependencies": {
3325
3324
  "@lancedb/lancedb-darwin-arm64": "^0.26.2",
@@ -3347,7 +3346,7 @@
3347
3346
  "core"
3348
3347
  ],
3349
3348
  "peerDependencies": {
3350
- "@remnic/coding-graph": "^10.0.50"
3349
+ "@remnic/coding-graph": "^10.0.52"
3351
3350
  },
3352
3351
  "peerDependenciesMeta": {
3353
3352
  "@remnic/coding-graph": {
@@ -153,6 +153,20 @@ test("formatZodIssues: includes the (root) path for top-level errors", async ()
153
153
  assert.ok(message.length > 0);
154
154
  });
155
155
 
156
+ test("formatZodIssues: a missing required field keeps the zod message, a wrong type says must be a type", async () => {
157
+ const { z } = await import("zod");
158
+ const schema = z.object({ memoryId: z.string() });
159
+ const missing = schema.safeParse({});
160
+ assert.ok(!missing.success);
161
+ const missingMessage = formatZodIssues(missing.error);
162
+ assert.doesNotMatch(missingMessage, /must be a string/, "an absent field is not a type mismatch");
163
+ assert.match(missingMessage, /memoryId/);
164
+ assert.match(missingMessage, /received undefined/);
165
+ const wrong = schema.safeParse({ memoryId: 5 });
166
+ assert.ok(!wrong.success);
167
+ assert.match(formatZodIssues(wrong.error), /memoryId must be a string/);
168
+ });
169
+
156
170
  // ---------------------------------------------------------------------------
157
171
  // defineOperation / getOperation — registry contract
158
172
  // ---------------------------------------------------------------------------
@@ -306,7 +306,7 @@ export interface OperationSpec<In, Out> {
306
306
  * #2829 category aliases) are first-class, declared truthfully instead of
307
307
  * cast into an input-equals-output shape.
308
308
  */
309
- readonly schema: z.ZodType<In, z.ZodTypeDef, unknown>;
309
+ readonly schema: z.ZodType<In, unknown>;
310
310
  /** Handler invoked with the parsed input; throws EngramAccessInputError for domain faults. */
311
311
  readonly handler: (input: In, ctx: OperationContext) => Promise<Out>;
312
312
  /**
@@ -427,24 +427,47 @@ export function formatZodIssues(error: z.ZodError): string {
427
427
  : issue.path.length > 0 ? issue.path.join(".") : "(root)";
428
428
  const options = enumOptionsFromIssue(issue);
429
429
  const suffix = options ? `. Valid: ${options.join(", ")}` : "";
430
- parts.push(`${path}: ${issue.message}${suffix}`);
430
+ parts.push(`${path}: ${humanReadableIssueMessage(issue, path, hasNumeric)}${suffix}`);
431
431
  }
432
432
  return parts.length > 0
433
433
  ? `request validation failed: ${parts.join("; ")}`
434
434
  : "request validation failed";
435
435
  }
436
436
 
437
- function enumOptionsFromIssue(issue: z.ZodIssue): readonly string[] | undefined {
438
- // zod exposes accepted enum values on the issue for ZodEnum / ZodNativeEnum
439
- // and on the options of invalid_union discriminators. Reading them here
437
+ function enumOptionsFromIssue(issue: z.core.$ZodIssue): readonly string[] | undefined {
438
+ // zod 4 exposes accepted enum values on invalid_value issues as `values`
439
+ // (the v3 `options` spelling is kept as a fallback). Reading them here
440
440
  // keeps "list valid options" in ONE place rather than per handler.
441
- if (issue.code === z.ZodIssueCode.invalid_enum_value) {
442
- const rawOptions = (issue as { options?: unknown }).options;
443
- if (Array.isArray(rawOptions)) {
444
- return rawOptions.map((opt) => String(opt));
445
- }
441
+ if (issue.code !== "invalid_value") return undefined;
442
+ const rawValues = "values" in issue ? issue.values : undefined;
443
+ return Array.isArray(rawValues) ? rawValues.map((opt) => String(opt)) : undefined;
444
+ }
445
+
446
+ /**
447
+ * Human-readable "must be a <type>" message for generic type mismatches
448
+ * (rule 51). zod 4 removed parse-time error maps, so the boundary applies
449
+ * this post-parse in formatZodIssues instead — same messages, one place.
450
+ * The caller supplies the collapsed path label and its numeric-segment
451
+ * verdict so this helper runs no representation checks of its own.
452
+ */
453
+ function humanReadableIssueMessage(issue: z.core.$ZodIssue, pathLabel: string, hasNumericPath: boolean): string {
454
+ if (issue.code !== "invalid_type") return issue.message;
455
+ const expected = issue.expected;
456
+ // zod 4 issues carry no `received` field; its message ends "received undefined"
457
+ // for an absent value, which is a missing field, not a type mismatch.
458
+ if (issue.message.endsWith("received undefined")) return issue.message;
459
+ if (hasNumericPath && expected) {
460
+ return `${pathLabel} must be an array of ${expected}s`;
461
+ }
462
+ const fieldName = issue.path.length > 0 ? String(issue.path[issue.path.length - 1]) : "value";
463
+ switch (expected) {
464
+ case "string": return `${fieldName} must be a string`;
465
+ case "boolean": return `${fieldName} must be a boolean`;
466
+ case "number": return `${fieldName} must be a number`;
467
+ case "array": return `${fieldName} must be an array`;
468
+ case "object": return `${fieldName} must be an object`;
469
+ default: return issue.message;
446
470
  }
447
- return undefined;
448
471
  }
449
472
 
450
473
  // ---------------------------------------------------------------------------
@@ -458,33 +481,6 @@ const registry = new Map<OperationName, BoundOperation>();
458
481
  * registration is a programming error, not a runtime input fault, so it throws
459
482
  * a plain Error (not the input-error class surfaces translate for clients).
460
483
  */
461
- /**
462
- * Error map that converts Zod's generic type-mismatch messages into
463
- * human-readable "must be a <type>" messages (rule 51). Applied at the
464
- * boundary chokepoint so every operation gets consistent messaging
465
- * without per-handler boilerplate.
466
- */
467
- const humanReadableErrorMap: z.ZodErrorMap = (issue, ctx) => {
468
- if (issue.code === z.ZodIssueCode.invalid_type) {
469
- if (issue.received === "undefined") return { message: ctx.defaultError };
470
- // Array-element type errors — collapse to field-level message.
471
- if (issue.path.some((p) => typeof p === "number")) {
472
- const arrField = issue.path.filter((p) => typeof p === "string").join(".");
473
- return { message: `${arrField} must be an array of ${issue.expected}s` };
474
- }
475
- const fieldName = issue.path.length > 0 ? String(issue.path[issue.path.length - 1]) : "value";
476
- switch (issue.expected) {
477
- case "string": return { message: `${fieldName} must be a string` };
478
- case "boolean": return { message: `${fieldName} must be a boolean` };
479
- case "number": return { message: `${fieldName} must be a number` };
480
- case "array": return { message: `${fieldName} must be an array` };
481
- case "object": return { message: `${fieldName} must be an object` };
482
- default: return { message: ctx.defaultError };
483
- }
484
- }
485
- return { message: ctx.defaultError };
486
- };
487
-
488
484
  export function defineOperation<In, Out>(spec: OperationSpec<In, Out>): BoundOperation<In, Out> {
489
485
  if (registry.has(spec.name)) {
490
486
  throw new Error(`access-boundary: operation already registered: ${spec.name}`);
@@ -492,7 +488,7 @@ export function defineOperation<In, Out>(spec: OperationSpec<In, Out>): BoundOpe
492
488
  const bound: BoundOperation<In, Out> = {
493
489
  spec,
494
490
  run: async (rawInput, ctx) => {
495
- const parseResult = spec.schema.safeParse(rawInput, { errorMap: humanReadableErrorMap });
491
+ const parseResult = spec.schema.safeParse(rawInput);
496
492
  if (!parseResult.success) {
497
493
  throw new EngramAccessInputError(formatZodIssues(parseResult.error));
498
494
  }
@@ -516,9 +512,19 @@ export function operationRequiresAuthorizedNamespace(name: OperationName): boole
516
512
  if (name === "namespace_writable") return false;
517
513
  if (IMPLICIT_HTTP_NAMESPACE_OPERATIONS.has(name)) return true;
518
514
  let schema: unknown = registry.get(name)?.spec.schema;
519
- // preprocess/transform/refine each wrap ZodEffects. One unwrap left
520
- // suggestion_submit looking namespace-free after the category transform.
521
- while (schema instanceof z.ZodEffects) schema = schema.innerType();
515
+ // zod 4 has no ZodEffects. Transforms and preprocessors wrap as pipes with
516
+ // the base schema on the side opposite the ZodTransform. Unwrap until the
517
+ // base object appears — one unwrap left suggestion_submit looking
518
+ // namespace-free after the category transform, so the loop stays.
519
+ while (schema instanceof z.ZodType && !(schema instanceof z.ZodObject)) {
520
+ // SAFETY: pipe wrappers expose their two sides as `in` / `out`.
521
+ const wrapper = schema as { in?: unknown; out?: unknown };
522
+ const sides = [wrapper.in, wrapper.out].filter(
523
+ (side) => side instanceof z.ZodType && !(side instanceof z.ZodTransform),
524
+ );
525
+ if (sides.length !== 1) break;
526
+ schema = sides[0];
527
+ }
522
528
  return schema instanceof z.ZodObject && Object.hasOwn(schema.shape, "namespace");
523
529
  }
524
530
 
@@ -662,24 +662,26 @@ test("project-shaped category aliases store as fact and the response reports the
662
662
  // ---------------------------------------------------------------------------
663
663
 
664
664
  test("#2829/#2866 transformed write schemas still require an authorized namespace", () => {
665
+ // zod 4 replaced ZodEffects with ZodPipe/ZodPreprocess (both expose .out).
665
666
  assert.equal(
666
- memoryStoreRequestSchema instanceof z.ZodEffects,
667
- true,
667
+ memoryStoreRequestSchema instanceof z.ZodObject,
668
+ false,
668
669
  "memory_store schema is a category transform",
669
670
  );
670
671
  const suggestion = getOperation("suggestion_submit");
671
672
  assert.ok(suggestion);
673
+ const wrapper: unknown = suggestion.spec.schema;
672
674
  assert.ok(
673
- suggestion.spec.schema instanceof z.ZodEffects,
675
+ wrapper instanceof Object && "in" in wrapper,
674
676
  "suggestion_submit wraps preprocess around the transform",
675
677
  );
676
- const inner = suggestion.spec.schema.innerType();
678
+ // SAFETY: the assertion above established `in` exists on this object.
679
+ const inner = (wrapper as { in: unknown }).in;
677
680
  assert.equal(
678
- inner instanceof z.ZodEffects,
679
- true,
681
+ inner instanceof z.ZodObject,
682
+ false,
680
683
  "one unwrap still lands on the category transform, not the object",
681
684
  );
682
- assert.equal(inner instanceof z.ZodObject, false);
683
685
 
684
686
  for (const operation of ["memory_store", "suggestion_submit"] as const) {
685
687
  assert.equal(
@@ -104,7 +104,7 @@ test("invalidArgsError: names the failing field path", () => {
104
104
  assert.equal(parse.success, false);
105
105
  const msg = invalidArgsError("engram.memory_get", parse.error, MEMORY_GET_SCHEMA);
106
106
  assert.match(msg, /memory_id/);
107
- assert.match(msg, /required/i);
107
+ assert.match(msg, /received undefined/i);
108
108
  });
109
109
 
110
110
  test("invalidArgsError: the shown example actually parses against the schema", () => {
@@ -133,16 +133,28 @@ test("invalidArgsError: the shown example actually parses against the schema", (
133
133
  });
134
134
 
135
135
  test("invalidArgsError: an example that cannot round-trip is withheld, not shown", () => {
136
- // A schema whose safeParse always fails must produce no example section
137
- // rather than an example the caller cannot use.
138
- const alwaysFails = {
139
- _def: { typeName: "ZodObject", shape: () => ({ field: { _def: { typeName: "ZodString" } } }) },
140
- safeParse: () => ({ success: false }),
141
- };
142
- const parse = MEMORY_GET_SCHEMA.safeParse({});
136
+ // Real zod 4 object: exampleFromSchema emits { field: "<string>" }, but the
137
+ // refine rejects that placeholder so safeParse fails. The round-trip guard
138
+ // must then withhold the example rather than advertise unusable args.
139
+ const neverRoundTrips = z
140
+ .object({
141
+ field: z.string().refine((value) => value !== "<string>", {
142
+ message: "placeholder example is rejected",
143
+ }),
144
+ })
145
+ .strict();
146
+
147
+ const againstPlaceholder = neverRoundTrips.safeParse({ field: "<string>" });
148
+ assert.equal(
149
+ againstPlaceholder.success,
150
+ false,
151
+ "the synthetic placeholder must fail the refine so the round-trip guard is reachable",
152
+ );
153
+
154
+ const parse = neverRoundTrips.safeParse({});
143
155
  assert.equal(parse.success, false);
144
156
  if (parse.success) return;
145
- const msg = invalidArgsError("engram.memory_get", parse.error, alwaysFails);
157
+ const msg = invalidArgsError("engram.memory_get", parse.error, neverRoundTrips);
146
158
  assert.doesNotMatch(msg, /Example arguments/, "a non-parsing example must be withheld");
147
159
  });
148
160
 
@@ -141,53 +141,67 @@ function buildSuggestion(
141
141
  * `undefined` instead of a fabricated read.
142
142
  */
143
143
  function zodTypeName(schema: unknown): string | undefined {
144
- if (typeof schema !== "object" || schema === null || !("_def" in schema)) return undefined;
145
- const def = schema._def;
146
- if (typeof def !== "object" || def === null || !("typeName" in def)) return undefined;
147
- return typeof def.typeName === "string" ? def.typeName : undefined;
144
+ // zod 4: schema internals live on `_zod.def.type` (v3 read `_def.typeName`).
145
+ if (!(schema instanceof Object) || !("_zod" in schema)) return undefined;
146
+ // SAFETY: the guard above established `_zod` exists; its `.def` carries the
147
+ // discriminator string under `type`.
148
+ const def = (schema as { _zod?: { def?: { type?: unknown } } })._zod?.def;
149
+ // SAFETY: zod's `_zod.def.type` discriminator is always a string literal.
150
+ const discriminator = def?.type;
151
+ return discriminator === undefined ? undefined : String(discriminator);
148
152
  }
149
153
 
150
- /** Read `_def.<key>` with the same narrowing discipline. */
151
- function zodDefField(schema: unknown, key: string): unknown {
152
- if (typeof schema !== "object" || schema === null || !("_def" in schema)) return undefined;
153
- const def = schema._def;
154
- if (typeof def !== "object" || def === null) return undefined;
155
- return Object.hasOwn(def, key) ? (def as Record<string, unknown>)[key] : undefined;
156
- }
154
+ /**
155
+ * A zod schema node this module reflects over — any object the library
156
+ * exposes as a schema (v4 marks them with `_zod`).
157
+ */
158
+ /** Structural marker: every zod schema carries `_zod`. */
159
+ type ZodSchemaLike = { _zod?: unknown };
160
+
161
+ /**
162
+ * A synthetic example value derived from a schema: a placeholder the SAME
163
+ * schema accepts, so the error message can show a valid argument shape.
164
+ */
165
+ type SchemaExample = string | number | boolean | null | readonly SchemaExample[] | { [key: string]: SchemaExample };
157
166
 
158
167
  /**
159
168
  * Reverse-engineer ONE synthetic example value from a Zod schema type.
160
169
  * Returns a deterministic placeholder intended to round-trip through parse().
161
170
  */
162
- function exampleFromSchema(schema: unknown): unknown {
171
+ function exampleFromSchema(schema: ZodSchemaLike): SchemaExample | undefined {
163
172
  switch (zodTypeName(schema)) {
164
- case "ZodString":
173
+ case "string":
165
174
  return "<string>";
166
- case "ZodNumber":
175
+ case "number":
167
176
  return 42;
168
- case "ZodBoolean":
177
+ case "boolean":
169
178
  return true;
170
- case "ZodNullable":
179
+ case "nullable":
171
180
  return null;
172
- case "ZodArray":
181
+ case "array":
173
182
  return [];
174
- case "ZodOptional":
183
+ case "optional":
175
184
  // Optional fields are omitted from the example rather than sent as null.
176
185
  return undefined;
177
- case "ZodEnum": {
178
- const values = zodDefField(schema, "values");
179
- return Array.isArray(values) && values.length > 0 ? values[0] : "<value>";
186
+ case "enum": {
187
+ // v4 exposes accepted values as the public `.enum` record.
188
+ if (!(schema instanceof Object) || !("enum" in schema)) return "<value>";
189
+ // SAFETY: the guard established `.enum`; zod types it as a value record.
190
+ const values = Object.values((schema as { enum: Record<string, string> }).enum);
191
+ return values.length > 0 ? values[0] : "<value>";
180
192
  }
181
- case "ZodObject": {
182
- const shapeFn = zodDefField(schema, "shape");
183
- const shape = typeof shapeFn === "function" ? shapeFn() : undefined;
184
- if (typeof shape !== "object" || shape === null) return {};
185
- const result: Record<string, unknown> = {};
186
- for (const key of Object.getOwnPropertyNames(shape)) {
187
- if (!Object.hasOwn(shape, key)) continue;
188
- const field = (shape as Record<string, unknown>)[key];
189
- const value = exampleFromSchema(field);
190
- if (value !== undefined) result[key] = value;
193
+ case "object": {
194
+ // v4 exposes `.shape` as a plain property on the object schema.
195
+ if (!(schema instanceof Object) || !("shape" in schema)) return {};
196
+ // SAFETY: object schemas expose their field schemas keyed by name.
197
+ const fieldsByName = (schema as { shape: { [field: string]: ZodSchemaLike } }).shape;
198
+ if (!(fieldsByName instanceof Object)) return {};
199
+ const result: { [key: string]: SchemaExample } = {};
200
+ for (const field of Object.getOwnPropertyNames(fieldsByName)) {
201
+ if (!Object.hasOwn(fieldsByName, field)) continue;
202
+ const schemaNode = fieldsByName[field];
203
+ const value = exampleFromSchema(schemaNode);
204
+ if (value !== undefined) result[field] = value;
191
205
  }
192
206
  return result;
193
207
  }
@@ -2165,7 +2165,7 @@ test("HTTP offline snapshot rejects out-of-range baseline mtimes as validation e
2165
2165
  assert.equal(response.status, 400);
2166
2166
  assert.equal(body.code, "validation_error");
2167
2167
  assert.equal(body.details?.[0]?.field, "baseFiles.0.mtimeMs");
2168
- assert.match(body.details?.[0]?.message ?? "", /less than or equal/);
2168
+ assert.match(body.details?.[0]?.message ?? "", /<=8640000000000000/);
2169
2169
  assert.equal(calls, 0);
2170
2170
  } finally {
2171
2171
  await server.stop();
@@ -369,11 +369,7 @@ export function reapplyCategoryCoercion<T extends object>(
369
369
  const categoryWireSchema = z.enum(
370
370
  [...MEMORY_CATEGORY_CANONICAL_INPUT, ...MEMORY_CATEGORY_ALIAS_INPUT],
371
371
  {
372
- errorMap: () => ({
373
- message:
374
- `category must be one of: ${[...MEMORY_CATEGORY_CANONICAL_INPUT, ...MEMORY_CATEGORY_ALIAS_INPUT].join(", ")}; ` +
375
- 'for project state/facts use "fact"',
376
- }),
372
+ error: `category must be one of: ${[...MEMORY_CATEGORY_CANONICAL_INPUT, ...MEMORY_CATEGORY_ALIAS_INPUT].join(", ")}; for project state/facts use "fact"`,
377
373
  },
378
374
  );
379
375
 
@@ -454,7 +450,7 @@ export const reviewDispositionRequestSchema = z.object({
454
450
  export const trustZonePromoteRequestSchema = z.object({
455
451
  recordId: z.string().trim().min(1, "recordId is required"),
456
452
  targetZone: z.enum(["working", "trusted"], {
457
- errorMap: () => ({ message: "targetZone must be 'working' or 'trusted'" }),
453
+ error: "targetZone must be 'working' or 'trusted'",
458
454
  }),
459
455
  promotionReason: z.string().trim().min(1, "promotionReason is required"),
460
456
  recordedAt: z.string().trim().optional(),
@@ -662,16 +658,13 @@ export const offlineSyncSnapshotRequestSchema = z.object({
662
658
  .optional(),
663
659
  });
664
660
 
665
- export const offlineSyncApplyRequestSchema = z
666
- .object({
667
- namespace: namespaceSchema,
668
- changeset: z.unknown(),
669
- returnCurrentFiles: z.boolean().optional(),
670
- })
671
- .refine((value) => value.changeset !== undefined && value.changeset !== null, {
672
- message: "changeset is required",
673
- path: ["changeset"],
674
- });
661
+ export const offlineSyncApplyRequestSchema = z.object({
662
+ namespace: namespaceSchema,
663
+ // zod 4: refine messages cannot override its synthesized nonoptional check,
664
+ // so presence is enforced on the field itself.
665
+ changeset: z.custom<unknown>((value) => value !== undefined && value !== null, "changeset is required"),
666
+ returnCurrentFiles: z.boolean().optional(),
667
+ });
675
668
 
676
669
  export const offlineSyncFilesRequestSchema = z.object({
677
670
  namespace: namespaceSchema,
@@ -693,8 +686,11 @@ export const offlineSyncFileContentRequestSchema = z.object({
693
686
  // Action confidence
694
687
  // ---------------------------------------------------------------------------
695
688
 
689
+ // Outer .optional() keeps the inferred property optional: a transform-typed
690
+ // property becomes required-with-undefined under zod 4 inference, breaking
691
+ // object literals that legitimately omit the key.
696
692
  const nullableOptional = <T extends z.ZodTypeAny>(schema: T) =>
697
- schema.optional().nullable().transform((value) => value ?? undefined);
693
+ schema.nullable().transform((value) => value ?? undefined).optional();
698
694
 
699
695
  const actionConfidenceRuleSchema = z
700
696
  .object({
@@ -92,13 +92,13 @@ test("scope prompt qualifies tool knowledge as project, requires naming the agen
92
92
  assert.match(captured.system, /"`git status --short` emits compact output" -> "global"/);
93
93
  });
94
94
 
95
- // ExtractedFactSchema is z.object(...).superRefine(...); unwrap the ZodEffects
96
- // to reach the scope field's describe text (named const, not an inline cast).
95
+ // zod 4: superRefine attaches checks to the object itself — the schema stays
96
+ // a ZodObject, so the scope field's describe text is on `.shape` directly.
97
97
  function scopeDescribe(): string {
98
- const unwrapped = ExtractedFactSchema as unknown as {
99
- innerType(): { shape: Record<string, { description?: string }> };
100
- };
101
- return unwrapped.innerType().shape.scope?.description ?? "";
98
+ // SAFETY: ExtractedFactSchema is a ZodObject in zod 4 (superRefine attaches
99
+ // checks in place); its `.shape` maps field names to schema nodes.
100
+ const schema = ExtractedFactSchema as { shape: Record<string, { description?: string }> };
101
+ return schema.shape.scope?.description ?? "";
102
102
  }
103
103
 
104
104
  test("scope field schema describe no longer lists tool configs and qualifies by agent", () => {
@@ -34,3 +34,31 @@ test("provider schema omits span in off mode and keeps it in on/shadow (issue #2
34
34
  assert.deepEqual(extractionProviderJsonSchema("on"), extractionProviderJsonSchema("shadow"));
35
35
  assert.notEqual(extractionProviderJsonSchema("off"), extractionProviderJsonSchema("on"));
36
36
  });
37
+
38
+ // Providers receive this as the extraction response_format. zod 3 advertised
39
+ // additionalProperties:false on every object; the zod 4 port must too.
40
+ type SchemaNode = {
41
+ type?: string;
42
+ properties?: Record<string, SchemaNode>;
43
+ items?: SchemaNode;
44
+ anyOf?: SchemaNode[];
45
+ additionalProperties?: boolean | SchemaNode;
46
+ };
47
+
48
+ function openObjectSchemas(node: SchemaNode, path: string, found: string[]): void {
49
+ if (node.type === "object" && node.properties && node.additionalProperties !== false) found.push(path);
50
+ for (const [name, child] of Object.entries(node.properties ?? {})) {
51
+ openObjectSchemas(child, `${path}.${name}`, found);
52
+ }
53
+ if (node.items) openObjectSchemas(node.items, `${path}[]`, found);
54
+ node.anyOf?.forEach((child, index) => openObjectSchemas(child, `${path}|${index}`, found));
55
+ }
56
+
57
+ test("provider schema closes every object schema with additionalProperties false", () => {
58
+ for (const mode of ["off", "on"] as const) {
59
+ const open: string[] = [];
60
+ // SAFETY: extractionProviderJsonSchema returns a JSON Schema document; SchemaNode names the keys walked here.
61
+ openObjectSchemas(extractionProviderJsonSchema(mode) as SchemaNode, "$", open);
62
+ assert.deepEqual(open, [], `spanMode=${mode}: objects that let a provider emit extra keys`);
63
+ }
64
+ });
@@ -5,7 +5,7 @@
5
5
  * schema is mode-aware so off-mode structured output cannot advertise `span`.
6
6
  */
7
7
 
8
- import { zodToJsonSchema } from "zod-to-json-schema";
8
+ import { z } from "zod";
9
9
  import type { ExtractionSpanConfig } from "./extraction-span-config.js";
10
10
  import { parseSpanOffsets, type ParsedSpan } from "./extraction-span.js";
11
11
  import { ExtractionProviderOutputSchema } from "./schemas.js";
@@ -19,13 +19,41 @@ export function applySpanMode(opts: {
19
19
  return parseSpanOffsets(opts.text, { start: opts.start, end: opts.end }, opts.enabled);
20
20
  }
21
21
 
22
- const JSON_SCHEMA_OPTS = { $refStrategy: "none" as const, effectStrategy: "input" as const };
22
+ /** The parts of a JSON Schema node the extraction schema uses. */
23
+ type SchemaNode = {
24
+ type?: string;
25
+ properties?: Record<string, SchemaNode>;
26
+ items?: SchemaNode;
27
+ anyOf?: SchemaNode[];
28
+ additionalProperties?: boolean | SchemaNode;
29
+ };
23
30
 
24
- const EXTRACTION_PROVIDER_JSON_SCHEMA_WITH_SPAN = zodToJsonSchema(
25
- ExtractionProviderOutputSchema,
26
- JSON_SCHEMA_OPTS,
27
- ) as Record<string, unknown>;
31
+ /**
32
+ * `io: "input"` leaves objects open (zod accepts extra input keys), but providers
33
+ * must be told to emit no extra keys: zod-to-json-schema advertised
34
+ * additionalProperties:false on every object. Close any object schema that
35
+ * does not already state its own.
36
+ */
37
+ function closeObjectSchemas(node: SchemaNode): SchemaNode {
38
+ if (node.type === "object" && node.properties && node.additionalProperties === undefined) {
39
+ node.additionalProperties = false;
40
+ }
41
+ Object.values(node.properties ?? {}).forEach(closeObjectSchemas);
42
+ if (node.items) closeObjectSchemas(node.items);
43
+ node.anyOf?.forEach(closeObjectSchemas);
44
+ return node;
45
+ }
28
46
 
47
+ // zod 4 ships toJSONSchema natively; zod-to-json-schema emits an empty
48
+ // document for v4 schemas, so the dependency is dropped here. `io: "input"`
49
+ // matches the old effectStrategy: "input" (advertise the input shape of
50
+ // transforms/preprocess to providers).
51
+ // SAFETY: z.toJSONSchema returns a JSON-Schema document — always an object at
52
+ // the root; the record shape is what omitFactSpan walks.
53
+ const EXTRACTION_PROVIDER_JSON_SCHEMA_WITH_SPAN: SchemaNode = closeObjectSchemas(
54
+ // SAFETY: z.toJSONSchema returns a JSON Schema document; SchemaNode names the keys this file reads.
55
+ z.toJSONSchema(ExtractionProviderOutputSchema, { target: "draft-7", io: "input" }) as SchemaNode,
56
+ );
29
57
  type FactItems = {
30
58
  properties?: Record<string, unknown>;
31
59
  required?: string[];
@@ -106,4 +106,7 @@ export interface ExtractionPersistDeps {
106
106
  */
107
107
  invalidateGraphEdgeCache?: (storage: StorageManager) => void;
108
108
  updateTemporalTagIndexes: (storage: StorageManager, persistedIds: string[]) => Promise<void>;
109
+ /** Schedule QMD reindex after partial durable writes that throw out of persist. */
110
+ requestQmdMaintenance: () => void;
111
+
109
112
  }