wingfoil 0.2.1

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 (339) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +334 -0
  3. package/dist/cli/error.d.ts +11 -0
  4. package/dist/cli/error.d.ts.map +1 -0
  5. package/dist/cli/error.js +27 -0
  6. package/dist/cli/error.js.map +1 -0
  7. package/dist/cli/exit.d.ts +19 -0
  8. package/dist/cli/exit.d.ts.map +1 -0
  9. package/dist/cli/exit.js +14 -0
  10. package/dist/cli/exit.js.map +1 -0
  11. package/dist/cli/index.d.ts +28 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +36 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/cli/init-command.d.ts +34 -0
  16. package/dist/cli/init-command.d.ts.map +1 -0
  17. package/dist/cli/init-command.js +100 -0
  18. package/dist/cli/init-command.js.map +1 -0
  19. package/dist/cli/mcp-command.d.ts +24 -0
  20. package/dist/cli/mcp-command.d.ts.map +1 -0
  21. package/dist/cli/mcp-command.js +42 -0
  22. package/dist/cli/mcp-command.js.map +1 -0
  23. package/dist/cli/output.d.ts +13 -0
  24. package/dist/cli/output.d.ts.map +1 -0
  25. package/dist/cli/output.js +28 -0
  26. package/dist/cli/output.js.map +1 -0
  27. package/dist/cli/program.d.ts +12 -0
  28. package/dist/cli/program.d.ts.map +1 -0
  29. package/dist/cli/program.js +279 -0
  30. package/dist/cli/program.js.map +1 -0
  31. package/dist/cli/registrar.d.ts +69 -0
  32. package/dist/cli/registrar.d.ts.map +1 -0
  33. package/dist/cli/registrar.js +82 -0
  34. package/dist/cli/registrar.js.map +1 -0
  35. package/dist/cli.d.ts +3 -0
  36. package/dist/cli.d.ts.map +1 -0
  37. package/dist/cli.js +45 -0
  38. package/dist/cli.js.map +1 -0
  39. package/dist/core/approval-authority.d.ts +83 -0
  40. package/dist/core/approval-authority.d.ts.map +1 -0
  41. package/dist/core/approval-authority.js +112 -0
  42. package/dist/core/approval-authority.js.map +1 -0
  43. package/dist/core/builtin-asset.d.ts +71 -0
  44. package/dist/core/builtin-asset.d.ts.map +1 -0
  45. package/dist/core/builtin-asset.js +137 -0
  46. package/dist/core/builtin-asset.js.map +1 -0
  47. package/dist/core/builtin-integrity.d.ts +32 -0
  48. package/dist/core/builtin-integrity.d.ts.map +1 -0
  49. package/dist/core/builtin-integrity.js +148 -0
  50. package/dist/core/builtin-integrity.js.map +1 -0
  51. package/dist/core/confinement.d.ts +57 -0
  52. package/dist/core/confinement.d.ts.map +1 -0
  53. package/dist/core/confinement.js +108 -0
  54. package/dist/core/confinement.js.map +1 -0
  55. package/dist/core/context.d.ts +187 -0
  56. package/dist/core/context.d.ts.map +1 -0
  57. package/dist/core/context.js +192 -0
  58. package/dist/core/context.js.map +1 -0
  59. package/dist/core/directive-assign.d.ts +131 -0
  60. package/dist/core/directive-assign.d.ts.map +1 -0
  61. package/dist/core/directive-assign.js +352 -0
  62. package/dist/core/directive-assign.js.map +1 -0
  63. package/dist/core/directives-list.d.ts +80 -0
  64. package/dist/core/directives-list.d.ts.map +1 -0
  65. package/dist/core/directives-list.js +148 -0
  66. package/dist/core/directives-list.js.map +1 -0
  67. package/dist/core/exit-code.d.ts +85 -0
  68. package/dist/core/exit-code.d.ts.map +1 -0
  69. package/dist/core/exit-code.js +163 -0
  70. package/dist/core/exit-code.js.map +1 -0
  71. package/dist/core/git-identity.d.ts +32 -0
  72. package/dist/core/git-identity.d.ts.map +1 -0
  73. package/dist/core/git-identity.js +72 -0
  74. package/dist/core/git-identity.js.map +1 -0
  75. package/dist/core/index.d.ts +388 -0
  76. package/dist/core/index.d.ts.map +1 -0
  77. package/dist/core/index.js +1331 -0
  78. package/dist/core/index.js.map +1 -0
  79. package/dist/core/init.d.ts +78 -0
  80. package/dist/core/init.d.ts.map +1 -0
  81. package/dist/core/init.js +167 -0
  82. package/dist/core/init.js.map +1 -0
  83. package/dist/core/loaders.d.ts +174 -0
  84. package/dist/core/loaders.d.ts.map +1 -0
  85. package/dist/core/loaders.js +364 -0
  86. package/dist/core/loaders.js.map +1 -0
  87. package/dist/core/memory-add-type.d.ts +43 -0
  88. package/dist/core/memory-add-type.d.ts.map +1 -0
  89. package/dist/core/memory-add-type.js +151 -0
  90. package/dist/core/memory-add-type.js.map +1 -0
  91. package/dist/core/memory-transition.d.ts +111 -0
  92. package/dist/core/memory-transition.d.ts.map +1 -0
  93. package/dist/core/memory-transition.js +269 -0
  94. package/dist/core/memory-transition.js.map +1 -0
  95. package/dist/core/registry.d.ts +189 -0
  96. package/dist/core/registry.d.ts.map +1 -0
  97. package/dist/core/registry.js +66 -0
  98. package/dist/core/registry.js.map +1 -0
  99. package/dist/core/relevance.d.ts +86 -0
  100. package/dist/core/relevance.d.ts.map +1 -0
  101. package/dist/core/relevance.js +258 -0
  102. package/dist/core/relevance.js.map +1 -0
  103. package/dist/core/require-reason.d.ts +27 -0
  104. package/dist/core/require-reason.d.ts.map +1 -0
  105. package/dist/core/require-reason.js +95 -0
  106. package/dist/core/require-reason.js.map +1 -0
  107. package/dist/core/types.d.ts +45 -0
  108. package/dist/core/types.d.ts.map +1 -0
  109. package/dist/core/types.js +22 -0
  110. package/dist/core/types.js.map +1 -0
  111. package/dist/core/usage-error.d.ts +20 -0
  112. package/dist/core/usage-error.d.ts.map +1 -0
  113. package/dist/core/usage-error.js +29 -0
  114. package/dist/core/usage-error.js.map +1 -0
  115. package/dist/core/write-guard.d.ts +99 -0
  116. package/dist/core/write-guard.d.ts.map +1 -0
  117. package/dist/core/write-guard.js +247 -0
  118. package/dist/core/write-guard.js.map +1 -0
  119. package/dist/directives/create.d.ts +47 -0
  120. package/dist/directives/create.d.ts.map +1 -0
  121. package/dist/directives/create.js +82 -0
  122. package/dist/directives/create.js.map +1 -0
  123. package/dist/directives/index.d.ts +20 -0
  124. package/dist/directives/index.d.ts.map +1 -0
  125. package/dist/directives/index.js +32 -0
  126. package/dist/directives/index.js.map +1 -0
  127. package/dist/directives/roles-edit.d.ts +53 -0
  128. package/dist/directives/roles-edit.d.ts.map +1 -0
  129. package/dist/directives/roles-edit.js +286 -0
  130. package/dist/directives/roles-edit.js.map +1 -0
  131. package/dist/directives/schema.d.ts +65 -0
  132. package/dist/directives/schema.d.ts.map +1 -0
  133. package/dist/directives/schema.js +68 -0
  134. package/dist/directives/schema.js.map +1 -0
  135. package/dist/dna/edit.d.ts +61 -0
  136. package/dist/dna/edit.d.ts.map +1 -0
  137. package/dist/dna/edit.js +429 -0
  138. package/dist/dna/edit.js.map +1 -0
  139. package/dist/dna/index.d.ts +24 -0
  140. package/dist/dna/index.d.ts.map +1 -0
  141. package/dist/dna/index.js +59 -0
  142. package/dist/dna/index.js.map +1 -0
  143. package/dist/dna/mutate.d.ts +74 -0
  144. package/dist/dna/mutate.d.ts.map +1 -0
  145. package/dist/dna/mutate.js +318 -0
  146. package/dist/dna/mutate.js.map +1 -0
  147. package/dist/dna/path.d.ts +175 -0
  148. package/dist/dna/path.d.ts.map +1 -0
  149. package/dist/dna/path.js +289 -0
  150. package/dist/dna/path.js.map +1 -0
  151. package/dist/dna/roles.d.ts +57 -0
  152. package/dist/dna/roles.d.ts.map +1 -0
  153. package/dist/dna/roles.js +50 -0
  154. package/dist/dna/roles.js.map +1 -0
  155. package/dist/dna/schema.d.ts +172 -0
  156. package/dist/dna/schema.d.ts.map +1 -0
  157. package/dist/dna/schema.js +182 -0
  158. package/dist/dna/schema.js.map +1 -0
  159. package/dist/dna/set.d.ts +145 -0
  160. package/dist/dna/set.d.ts.map +1 -0
  161. package/dist/dna/set.js +428 -0
  162. package/dist/dna/set.js.map +1 -0
  163. package/dist/mcp/dna-resource.d.ts +16 -0
  164. package/dist/mcp/dna-resource.d.ts.map +1 -0
  165. package/dist/mcp/dna-resource.js +56 -0
  166. package/dist/mcp/dna-resource.js.map +1 -0
  167. package/dist/mcp/index.d.ts +49 -0
  168. package/dist/mcp/index.d.ts.map +1 -0
  169. package/dist/mcp/index.js +60 -0
  170. package/dist/mcp/index.js.map +1 -0
  171. package/dist/mcp/memory-resource.d.ts +17 -0
  172. package/dist/mcp/memory-resource.d.ts.map +1 -0
  173. package/dist/mcp/memory-resource.js +133 -0
  174. package/dist/mcp/memory-resource.js.map +1 -0
  175. package/dist/mcp/prompt.d.ts +48 -0
  176. package/dist/mcp/prompt.d.ts.map +1 -0
  177. package/dist/mcp/prompt.js +176 -0
  178. package/dist/mcp/prompt.js.map +1 -0
  179. package/dist/mcp/read-only.d.ts +42 -0
  180. package/dist/mcp/read-only.d.ts.map +1 -0
  181. package/dist/mcp/read-only.js +93 -0
  182. package/dist/mcp/read-only.js.map +1 -0
  183. package/dist/mcp/registrar.d.ts +54 -0
  184. package/dist/mcp/registrar.d.ts.map +1 -0
  185. package/dist/mcp/registrar.js +72 -0
  186. package/dist/mcp/registrar.js.map +1 -0
  187. package/dist/mcp/server.d.ts +58 -0
  188. package/dist/mcp/server.d.ts.map +1 -0
  189. package/dist/mcp/server.js +64 -0
  190. package/dist/mcp/server.js.map +1 -0
  191. package/dist/mcp/workflow-resource.d.ts +17 -0
  192. package/dist/mcp/workflow-resource.d.ts.map +1 -0
  193. package/dist/mcp/workflow-resource.js +63 -0
  194. package/dist/mcp/workflow-resource.js.map +1 -0
  195. package/dist/memory/add.d.ts +50 -0
  196. package/dist/memory/add.d.ts.map +1 -0
  197. package/dist/memory/add.js +131 -0
  198. package/dist/memory/add.js.map +1 -0
  199. package/dist/memory/audit.d.ts +177 -0
  200. package/dist/memory/audit.d.ts.map +1 -0
  201. package/dist/memory/audit.js +287 -0
  202. package/dist/memory/audit.js.map +1 -0
  203. package/dist/memory/commit-message.d.ts +146 -0
  204. package/dist/memory/commit-message.d.ts.map +1 -0
  205. package/dist/memory/commit-message.js +203 -0
  206. package/dist/memory/commit-message.js.map +1 -0
  207. package/dist/memory/entry.d.ts +56 -0
  208. package/dist/memory/entry.d.ts.map +1 -0
  209. package/dist/memory/entry.js +28 -0
  210. package/dist/memory/entry.js.map +1 -0
  211. package/dist/memory/frontmatter-edit.d.ts +68 -0
  212. package/dist/memory/frontmatter-edit.d.ts.map +1 -0
  213. package/dist/memory/frontmatter-edit.js +333 -0
  214. package/dist/memory/frontmatter-edit.js.map +1 -0
  215. package/dist/memory/git-log.d.ts +32 -0
  216. package/dist/memory/git-log.d.ts.map +1 -0
  217. package/dist/memory/git-log.js +100 -0
  218. package/dist/memory/git-log.js.map +1 -0
  219. package/dist/memory/history.d.ts +142 -0
  220. package/dist/memory/history.d.ts.map +1 -0
  221. package/dist/memory/history.js +250 -0
  222. package/dist/memory/history.js.map +1 -0
  223. package/dist/memory/index.d.ts +58 -0
  224. package/dist/memory/index.d.ts.map +1 -0
  225. package/dist/memory/index.js +107 -0
  226. package/dist/memory/index.js.map +1 -0
  227. package/dist/memory/query.d.ts +150 -0
  228. package/dist/memory/query.d.ts.map +1 -0
  229. package/dist/memory/query.js +307 -0
  230. package/dist/memory/query.js.map +1 -0
  231. package/dist/memory/reject.d.ts +11 -0
  232. package/dist/memory/reject.d.ts.map +1 -0
  233. package/dist/memory/reject.js +32 -0
  234. package/dist/memory/reject.js.map +1 -0
  235. package/dist/memory/schema.d.ts +104 -0
  236. package/dist/memory/schema.d.ts.map +1 -0
  237. package/dist/memory/schema.js +161 -0
  238. package/dist/memory/schema.js.map +1 -0
  239. package/dist/memory/state-machine.d.ts +166 -0
  240. package/dist/memory/state-machine.d.ts.map +1 -0
  241. package/dist/memory/state-machine.js +431 -0
  242. package/dist/memory/state-machine.js.map +1 -0
  243. package/dist/memory/submit.d.ts +11 -0
  244. package/dist/memory/submit.d.ts.map +1 -0
  245. package/dist/memory/submit.js +44 -0
  246. package/dist/memory/submit.js.map +1 -0
  247. package/dist/storage/builtin-directives.d.ts +54 -0
  248. package/dist/storage/builtin-directives.d.ts.map +1 -0
  249. package/dist/storage/builtin-directives.js +152 -0
  250. package/dist/storage/builtin-directives.js.map +1 -0
  251. package/dist/storage/commit.d.ts +92 -0
  252. package/dist/storage/commit.d.ts.map +1 -0
  253. package/dist/storage/commit.js +201 -0
  254. package/dist/storage/commit.js.map +1 -0
  255. package/dist/storage/confinement.d.ts +93 -0
  256. package/dist/storage/confinement.d.ts.map +1 -0
  257. package/dist/storage/confinement.js +164 -0
  258. package/dist/storage/confinement.js.map +1 -0
  259. package/dist/storage/document.d.ts +27 -0
  260. package/dist/storage/document.d.ts.map +1 -0
  261. package/dist/storage/document.js +52 -0
  262. package/dist/storage/document.js.map +1 -0
  263. package/dist/storage/errors.d.ts +36 -0
  264. package/dist/storage/errors.d.ts.map +1 -0
  265. package/dist/storage/errors.js +46 -0
  266. package/dist/storage/errors.js.map +1 -0
  267. package/dist/storage/frontmatter.d.ts +27 -0
  268. package/dist/storage/frontmatter.d.ts.map +1 -0
  269. package/dist/storage/frontmatter.js +37 -0
  270. package/dist/storage/frontmatter.js.map +1 -0
  271. package/dist/storage/git-root.d.ts +17 -0
  272. package/dist/storage/git-root.d.ts.map +1 -0
  273. package/dist/storage/git-root.js +49 -0
  274. package/dist/storage/git-root.js.map +1 -0
  275. package/dist/storage/index.d.ts +29 -0
  276. package/dist/storage/index.d.ts.map +1 -0
  277. package/dist/storage/index.js +66 -0
  278. package/dist/storage/index.js.map +1 -0
  279. package/dist/storage/init-state.d.ts +9 -0
  280. package/dist/storage/init-state.d.ts.map +1 -0
  281. package/dist/storage/init-state.js +24 -0
  282. package/dist/storage/init-state.js.map +1 -0
  283. package/dist/storage/layout.d.ts +51 -0
  284. package/dist/storage/layout.d.ts.map +1 -0
  285. package/dist/storage/layout.js +88 -0
  286. package/dist/storage/layout.js.map +1 -0
  287. package/dist/storage/memory-path.d.ts +72 -0
  288. package/dist/storage/memory-path.d.ts.map +1 -0
  289. package/dist/storage/memory-path.js +127 -0
  290. package/dist/storage/memory-path.js.map +1 -0
  291. package/dist/storage/snapshot.d.ts +16 -0
  292. package/dist/storage/snapshot.d.ts.map +1 -0
  293. package/dist/storage/snapshot.js +72 -0
  294. package/dist/storage/snapshot.js.map +1 -0
  295. package/dist/storage/templates.d.ts +88 -0
  296. package/dist/storage/templates.d.ts.map +1 -0
  297. package/dist/storage/templates.js +422 -0
  298. package/dist/storage/templates.js.map +1 -0
  299. package/dist/validation/error-mapper.d.ts +16 -0
  300. package/dist/validation/error-mapper.d.ts.map +1 -0
  301. package/dist/validation/error-mapper.js +18 -0
  302. package/dist/validation/error-mapper.js.map +1 -0
  303. package/dist/validation/errors.d.ts +69 -0
  304. package/dist/validation/errors.d.ts.map +1 -0
  305. package/dist/validation/errors.js +69 -0
  306. package/dist/validation/errors.js.map +1 -0
  307. package/dist/validation/id.d.ts +16 -0
  308. package/dist/validation/id.d.ts.map +1 -0
  309. package/dist/validation/id.js +177 -0
  310. package/dist/validation/id.js.map +1 -0
  311. package/dist/validation/index.d.ts +18 -0
  312. package/dist/validation/index.d.ts.map +1 -0
  313. package/dist/validation/index.js +37 -0
  314. package/dist/validation/index.js.map +1 -0
  315. package/dist/validation/secret-scan.d.ts +129 -0
  316. package/dist/validation/secret-scan.d.ts.map +1 -0
  317. package/dist/validation/secret-scan.js +367 -0
  318. package/dist/validation/secret-scan.js.map +1 -0
  319. package/dist/validation/two-pass.d.ts +24 -0
  320. package/dist/validation/two-pass.d.ts.map +1 -0
  321. package/dist/validation/two-pass.js +24 -0
  322. package/dist/validation/two-pass.js.map +1 -0
  323. package/dist/validation/warning.d.ts +31 -0
  324. package/dist/validation/warning.d.ts.map +1 -0
  325. package/dist/validation/warning.js +81 -0
  326. package/dist/validation/warning.js.map +1 -0
  327. package/dist/validation/yaml.d.ts +9 -0
  328. package/dist/validation/yaml.d.ts.map +1 -0
  329. package/dist/validation/yaml.js +30 -0
  330. package/dist/validation/yaml.js.map +1 -0
  331. package/dist/workflow/index.d.ts +10 -0
  332. package/dist/workflow/index.d.ts.map +1 -0
  333. package/dist/workflow/index.js +16 -0
  334. package/dist/workflow/index.js.map +1 -0
  335. package/dist/workflow/schema.d.ts +89 -0
  336. package/dist/workflow/schema.d.ts.map +1 -0
  337. package/dist/workflow/schema.js +73 -0
  338. package/dist/workflow/schema.js.map +1 -0
  339. package/package.json +78 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/memory/history.ts"],"names":[],"mappings":"AAiCA,sGAAsG;AACtG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,qFAAqF;IACrF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAcD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAexF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,kBAAkB,EAAE,CAUtB;AAmBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA+B9F;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACtC,YAAY,EAAE,MAAM,GACnB,kBAAkB,EAAE,CAEtB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,kBAAkB,EAAE,CA4BzF"}
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findElementCreationSha = findElementCreationSha;
4
+ exports.dropPreCreationAncestry = dropPreCreationAncestry;
5
+ exports.collectHistoricalPaths = collectHistoricalPaths;
6
+ exports.attachHistoricalPaths = attachHistoricalPaths;
7
+ exports.getMemoryHistory = getMemoryHistory;
8
+ /**
9
+ * Memory history primitive (task-008-dna-memory-query-latency, REQ-PERF-02) — the git-log walk
10
+ * underneath `wingfoil memory history` (P1.10), which shipped in `task-049-memory-history` as
11
+ * `src/core`'s `memoryHistory` operation. Per ADR-007 (stateless-state-derivation), git history is
12
+ * the sole audit trail for a Memory element's transitions — there is no secondary `.wingfoil/state/`
13
+ * log to query instead — so this walks `git log` directly over the element's file.
14
+ *
15
+ * Scope (see task-008's Execution Notes): this returns *structured commit records* (sha, author
16
+ * name/email, ISO-8601 author date, subject, body) — the walk itself. Deriving a human-facing
17
+ * "state change" (e.g. "pending -> backlog") from the commit body's `Approver:`/`Reason:` lines
18
+ * (CLAUDE.md §5.1) is not this primitive's concern; the raw `body` field carries that text verbatim
19
+ * for a caller to parse, and `./audit`'s `reconstructMemoryTransitions` is the caller that does — the
20
+ * `memoryHistory` operation projects that reconstruction rather than re-reading this walk itself.
21
+ *
22
+ * The `git log` walk/record-splitting plumbing itself lives in `./git-log` (factored out by
23
+ * task-015-complete-audit-trail, which needs the same plumbing for its own attribution audit) — this
24
+ * module owns only the `MemoryHistoryEntry` shape and the `--follow` single-document semantics.
25
+ *
26
+ * Those `--follow` semantics are this module's real subject, and they are not the ones the flag's
27
+ * name suggests (`task-089-fix-history-walk-attributes-only-real-commits`,
28
+ * `bug-077-history-follow-attributes-template-commits`). `--follow` does not only follow renames:
29
+ * git's path search runs with **copy** detection enabled, so when the path is absent from a parent
30
+ * commit git will accept a source that still exists there. Every Memory element is created by
31
+ * copying its type's template, which `wingfoil init` has already committed — so the walk crossed
32
+ * that copy edge and reported the commit that added the TEMPLATE as an entry of the element's own
33
+ * history, carrying a real sha, author and timestamp with every derived field null. See
34
+ * {@link findElementCreationSha} for the distinction that resolves it and why rename-following is
35
+ * kept rather than traded away.
36
+ */
37
+ const child_process_1 = require("child_process");
38
+ const git_log_1 = require("./git-log");
39
+ const LOG_FIELDS = ['%H', '%an', '%ae', '%aI', '%s', '%b'];
40
+ /**
41
+ * The same `--follow` walk as {@link getMemoryHistory}, narrowed by git to the commits whose edge for
42
+ * this path is a **copy**, and printing nothing but the sha. Deliberately a second `git log`
43
+ * invocation rather than extra output threaded through the first: `walkGitLogFields` recovers
44
+ * records by field arity over a stream of `<field>NUL` groups, so anything git appends outside the
45
+ * `--format` string — `--name-status` output, for instance — would be read as the next record's
46
+ * first field (task-086).
47
+ */
48
+ const CREATION_PROBE_ARGS = ['--follow', '--diff-filter=C', '--format=%H'];
49
+ /**
50
+ * The sha of the commit that introduced `relativePath` as a COPY of a file that outlives it — the
51
+ * element's own creation — or `null` when the followed chain contains no copy edge at all.
52
+ *
53
+ * This is the distinction the fix turns on. `git log --follow` can change path across two different
54
+ * kinds of edge, and they mean opposite things for an audit trail:
55
+ *
56
+ * - **`R` (rename)** — the element continuing under a new name. Keep following. This is not a
57
+ * hypothetical requirement: `docs/self/docs/04_memory/planning/v1/*` became `planning/rl-v1/*` in
58
+ * one commit in this repository, moving five `release` elements at once, because the `release`
59
+ * type's `path` pattern interpolates the release-line id (`memory.yaml`). For one of them a plain
60
+ * `git log -- <path>` returns a single commit where the followed walk returns seven, so dropping
61
+ * `--follow` would delete five sixths of that element's recorded history.
62
+ * - **`C` (copy)** — the element being born out of a file that still exists. `wingfoil memory add`
63
+ * copies the type's template verbatim (CLAUDE.md §5.1), and `wingfoil init` has already committed
64
+ * that template, so this edge is how every scaffolded element begins. Everything strictly older
65
+ * than it is the template's history, not the element's.
66
+ *
67
+ * Only the newest copy edge matters — it is the element's own creation; any older one belongs to
68
+ * whatever the source itself was copied from. `git log` prints newest first, so that is the first
69
+ * line.
70
+ *
71
+ * **Throws** — never returns `null` — when git itself fails. "git could not answer" and "this
72
+ * element was never copied from anything" are different answers, and collapsing the first into the
73
+ * second would silently restore the phantom entry; it is also why this cannot borrow
74
+ * `walkGitLogFields`, whose `catch` returns `[]` (`bug-072-oversized-git-log-becomes-empty-history`).
75
+ * {@link getMemoryHistory} calls this only once the main walk has already returned commits, so at
76
+ * that point the repository and the path are both known good and a failure here is genuinely
77
+ * exceptional.
78
+ *
79
+ * @param root - Absolute path of the repository to walk.
80
+ * @param relativePath - The element's root-relative path, as {@link getMemoryHistory} takes it.
81
+ * @returns The creation commit's full sha, or `null` when the chain has no copy edge.
82
+ */
83
+ function findElementCreationSha(root, relativePath) {
84
+ let stdout;
85
+ try {
86
+ stdout = (0, child_process_1.execFileSync)('git', ['-C', root, 'log', ...CREATION_PROBE_ARGS, '--', relativePath], {
87
+ encoding: 'utf-8',
88
+ });
89
+ }
90
+ catch (cause) {
91
+ throw new Error(`git log --follow --diff-filter=C failed for ${relativePath}: cannot establish where the element was created`, { cause });
92
+ }
93
+ const newestCopy = stdout.split('\n').find((line) => line.trim().length > 0);
94
+ return newestCopy === undefined ? null : newestCopy.trim();
95
+ }
96
+ /**
97
+ * Drop the part of an oldest-first walk that precedes the element's creation, keeping the creation
98
+ * commit itself — the ancestry `--follow` reached through a copy edge, which belongs to the file the
99
+ * element was copied from. `creationSha` of `null` (no copy edge: the document was authored in
100
+ * place) leaves the walk untouched.
101
+ *
102
+ * Pure: no git, no filesystem. Separated from {@link findElementCreationSha} so the truncation rule
103
+ * and the invariant below are exercised directly rather than through a repository fixture.
104
+ *
105
+ * **Throws** when `creationSha` is absent from `entries`. The two walks are the same walk — one is
106
+ * the other filtered by git — so a sha in the narrower one that is missing from the wider one is a
107
+ * broken invariant, not a case to absorb. Defaulting to "no truncation" there would report the
108
+ * phantom entry again while reporting success.
109
+ *
110
+ * @param entries - The full `--follow` walk, oldest first.
111
+ * @param creationSha - The element's creation commit, from {@link findElementCreationSha}.
112
+ * @returns `entries` from the creation commit onward (a new array; `entries` is not mutated).
113
+ */
114
+ function dropPreCreationAncestry(entries, creationSha) {
115
+ if (creationSha === null)
116
+ return [...entries];
117
+ const creationIndex = entries.findIndex((entry) => entry.sha === creationSha);
118
+ if (creationIndex === -1) {
119
+ throw new Error(`creation commit ${creationSha} is not present in the history walk it was derived from`);
120
+ }
121
+ return entries.slice(creationIndex);
122
+ }
123
+ /**
124
+ * The same `--follow` walk again, printing each commit's sha followed by its name-status line for
125
+ * the followed path. A third `git log` invocation for the same reason as {@link CREATION_PROBE_ARGS}
126
+ * and stated in full there: `--name-status` output is appended OUTSIDE the `--format` string, and
127
+ * `walkGitLogFields` recovers records by field arity over a stream of `<field>NUL` groups, so it
128
+ * would read those lines as the next record's first field (task-086).
129
+ *
130
+ * `core.quotePath=false` is set for the invocation (never written to the repository's config) so a
131
+ * path carrying non-ASCII bytes arrives as its own UTF-8 rather than as git's `"\303\251"` escape
132
+ * form — the parser would otherwise have to un-escape it to hand `git show` something that resolves.
133
+ */
134
+ const PATH_PROBE_ARGS = ['-c', 'core.quotePath=false'];
135
+ const PATH_PROBE_LOG_ARGS = ['--follow', '--name-status', '--format=%H'];
136
+ /** A full sha on a line of its own — git's `--format=%H` output, which carries nothing else. */
137
+ const SHA_LINE_RE = /^[0-9a-f]{40}$/;
138
+ /**
139
+ * Where `relativePath`'s document lived at each commit of its `--follow` walk, keyed by sha.
140
+ *
141
+ * `git log --follow --name-status` prints, per commit, the sha then that commit's status line for
142
+ * the followed path — `A <path>`, `M <path>`, `D <path>`, or `R<score> <old> <new>` at a rename. The
143
+ * path the file occupies **at** a commit is always the LAST tab-separated field of that line: the
144
+ * destination of a rename, the single path otherwise. Everything older than that rename then reports
145
+ * the old path, which is the whole point — it is what
146
+ * `git show <sha>:<path>` needs in order to resolve at all.
147
+ *
148
+ * A commit git reports no status line for (it shows no diff for a merge without `-m`) is simply
149
+ * absent from the map; {@link attachHistoricalPaths} decides what to do about that, so the rule is
150
+ * testable without a repository.
151
+ *
152
+ * **Throws** — never returns an empty map — when git itself fails, for the same reason
153
+ * {@link findElementCreationSha} does: "git could not answer" and "this element was never renamed"
154
+ * are different answers, and folding the first into the second silently reinstates `bug-080` by
155
+ * reading every commit at the current path again. {@link getMemoryHistory} calls this only once the
156
+ * main walk has returned commits, so the repository and the path are both known good by then.
157
+ *
158
+ * @param root - Absolute path of the repository to walk.
159
+ * @param relativePath - The element's current root-relative path, as the caller named it.
160
+ * @returns sha → the root-relative path the document occupied at that commit.
161
+ */
162
+ function collectHistoricalPaths(root, relativePath) {
163
+ let stdout;
164
+ try {
165
+ stdout = (0, child_process_1.execFileSync)('git', ['-C', root, ...PATH_PROBE_ARGS, 'log', ...PATH_PROBE_LOG_ARGS, '--', relativePath],
166
+ // Same `stdio` rule as `./audit`'s `readStatusAt`, for the same reason
167
+ // (`bug-071-read-status-at-leaks-git-stderr`): the failure is reported by the throw below, so
168
+ // git's own `fatal:` must land in a pipe this process owns rather than on the operator's
169
+ // terminal. A call added while closing that bug must not reopen it somewhere else.
170
+ { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });
171
+ }
172
+ catch (cause) {
173
+ throw new Error(`git log --follow --name-status failed for ${relativePath}: cannot establish where the element lived at each commit`, { cause });
174
+ }
175
+ const pathBySha = new Map();
176
+ let currentSha = null;
177
+ for (const line of stdout.split('\n')) {
178
+ if (SHA_LINE_RE.test(line)) {
179
+ currentSha = line;
180
+ continue;
181
+ }
182
+ if (currentSha === null || !line.includes('\t') || pathBySha.has(currentSha))
183
+ continue;
184
+ const fields = line.split('\t');
185
+ pathBySha.set(currentSha, fields[fields.length - 1]);
186
+ }
187
+ return pathBySha;
188
+ }
189
+ /**
190
+ * Stamp each walked commit with the path the element occupied at it, from
191
+ * {@link collectHistoricalPaths}' map.
192
+ *
193
+ * Pure: no git, no filesystem — separated from the probe for the same reason
194
+ * {@link dropPreCreationAncestry} is separated from {@link findElementCreationSha}, so the rule and
195
+ * its fallback are exercised directly rather than through a repository fixture.
196
+ *
197
+ * Falls back to `fallbackPath` (the path the caller named) for a sha the probe reported no diff for,
198
+ * rather than throwing: unlike the creation probe's invariant, an absent entry here is not evidence
199
+ * of a broken walk — git shows no diff for a merge commit — and the fallback is precisely the
200
+ * behaviour that shipped before this field existed, so it can degrade no further than the status quo.
201
+ *
202
+ * @param entries - The `--follow` walk, oldest first.
203
+ * @param pathBySha - sha → historical path, from {@link collectHistoricalPaths}.
204
+ * @param fallbackPath - The element's current root-relative path.
205
+ * @returns A new array; `entries` is not mutated.
206
+ */
207
+ function attachHistoricalPaths(entries, pathBySha, fallbackPath) {
208
+ return entries.map((entry) => ({ ...entry, path: pathBySha.get(entry.sha) ?? fallbackPath }));
209
+ }
210
+ /**
211
+ * Walk every commit that touched `relativePath`, oldest first (P1.10-memory-history.feature: "lists
212
+ * ... entries in chronological order") — `git log` itself returns newest-first, reversed by
213
+ * {@link walkGitLogFields} — and only those commits. The walk follows renames, so an element moved on
214
+ * disk keeps its history, but stops at the element's own creation rather than continuing into the
215
+ * template it was copied from ({@link findElementCreationSha}).
216
+ *
217
+ * Returns `[]`, rather than throwing, both when `root` has no commits touching the path at all and
218
+ * when `root` is not a git repository — "document not found" is a caller/feature-layer concern
219
+ * (task-021/026-style CLI error rendering), not this primitive's. That is also why the creation
220
+ * probe runs only on a non-empty walk: on an empty one there is nothing to truncate and nothing to
221
+ * conclude from git's silence — and the same for the path probe.
222
+ *
223
+ * Every returned entry carries the path the element occupied at its own commit
224
+ * ({@link MemoryHistoryEntry.path}), not the one the caller named. That is what makes this walk the
225
+ * single source of truth for "where was this file at this commit": a consumer that reads content per
226
+ * commit — `./audit`'s `reconstructMemoryTransitions`, which reads the frontmatter `status:` — must
227
+ * take the path from here rather than re-using its own argument (`bug-080`).
228
+ */
229
+ function getMemoryHistory(root, relativePath) {
230
+ const records = (0, git_log_1.walkGitLogFields)(root, LOG_FIELDS, [relativePath], ['--follow']);
231
+ // One field per slot, `%b` included. Two consequences of task-086's arity-based framing, both
232
+ // deliberate:
233
+ //
234
+ // - The body arrives WHOLE even when it carries a character that used to look like a delimiter.
235
+ // `%b` being LAST was the only thing that made a `0x1f` in a reason survive before, via an
236
+ // explicit `bodyParts.join(FIELD_SEP)` that undid the split it had just caused; that accident
237
+ // and the reassembly compensating for it are both gone (bug-050).
238
+ // - Every record has exactly `LOG_FIELDS.length` entries — `walkGitLogFields` emits whole groups
239
+ // or none — so the per-slot `= ''` defaults this used to carry could never fire. They are read
240
+ // as the cast below instead of kept as six permanently-unreachable branches.
241
+ const entries = records.map((record) => {
242
+ const [sha, authorName, authorEmail, date, subject, body] = record;
243
+ return { sha, authorName, authorEmail, date, subject, body: body.trim(), path: relativePath };
244
+ });
245
+ if (entries.length === 0)
246
+ return entries;
247
+ const located = attachHistoricalPaths(entries, collectHistoricalPaths(root, relativePath), relativePath);
248
+ return dropPreCreationAncestry(located, findElementCreationSha(root, relativePath));
249
+ }
250
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/memory/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * `memory` module — Project Memory pillar; git-backed documents with per-type state machines
3
+ * (P1.13). `memory.yaml`'s schema (spec-001-memory-yaml-schema) lives here — the pillar owns its own
4
+ * independent schema (REQ-SYS-02); `src/core`'s loader wires it through the shared validation
5
+ * pipeline. The transition-legality engine (REQ-SYS-04, task-005-per-type-state-machines) also lives
6
+ * here — it consumes the schema's already-validated `StateMachine` shape, it does not re-validate it.
7
+ * Further Memory behavior (per-type CLI verbs, frontmatter schema) lands in later tasks.
8
+ *
9
+ * task-008-dna-memory-query-latency adds the `memory search`/`memory history` query-path
10
+ * *primitives* (REQ-PERF-02) `./query` and `./history` — the performance-bearing foundation
11
+ * `task-021-implement-memory-search` (P1.5) and `task-049-memory-history` (P1.10) built their
12
+ * CLI/MCP surface on top of; see those modules' own doc comments and the task's Execution Notes for
13
+ * the foundation/feature scoping decision.
14
+ *
15
+ * task-015-complete-audit-trail adds `./audit` (REQ-SEC-02) — the audit/verification layer built on
16
+ * `./history`'s raw git-log walk: attribution auditing (0 "unknown author"), `Approver:`/`Reason:`
17
+ * commit-body parsing, full transition reconstruction, and the frontmatter-vs-commit-message
18
+ * consistency check. It is deliberately read-only/verification-only — write-time git-identity
19
+ * enforcement is task-014-git-identity-required's (REQ-SEC-01) separate concern.
20
+ *
21
+ * task-022-implement-memory-entries adds `./entry` (P1.11) — `writeMemoryEntry`, the reusable,
22
+ * throwing library primitive that composes `resolveConfinedMemoryPath` (task-017, REQ-SEC-06),
23
+ * `writeDocument`, and `commitPaths` (task-018) into the one "resolve confined path, write bytes,
24
+ * one commit" Memory-entry write path (REQ-SYS-01/REQ-SYS-03). `wingfoil memory add`/`submit`
25
+ * (task-020) wire this in behind a `CoreResult`; this module stays a plain, throwing composition,
26
+ * matching every other `src/storage` primitive it builds on.
27
+ *
28
+ * task-036-frontmatter-lifecycle-validation adds `validateFrontmatterState` (REQ-STATE-01,
29
+ * spec-010-memory-frontmatter-schema) to `./state-machine` — the per-type membership check on a
30
+ * document's frontmatter `status` value itself, independent of any transition attempt (distinct from
31
+ * `resolveTransitionTarget`'s verb-based transition legality). `task-045-memory-submit` (P1.6) is the
32
+ * first CLI-facing consumer.
33
+ *
34
+ * task-045-memory-submit adds the pieces every Memory transition verb shares — `resolveTypeTransition`
35
+ * (the `dl-032` illegal-transition contract), `./commit-message` (the one commit-message formatter) and
36
+ * `./frontmatter-edit` (byte-preserving field edits) — plus `./submit`, the submit-specific rules.
37
+ */
38
+ export declare const MODULE_NAME: "memory";
39
+ export { MemoryYaml, MemoryTypeEntry, StateMachine, TemplateConfig } from './schema';
40
+ export { ARCHIVED_STATUSES, DEFAULT_STATE_MACHINE, DEPRECATED_STATE, E_INVALID_STATE, E_INVALID_TRANSITION, isArchivedStatus, resolveStateMachine, resolveTransitionTarget, resolveTypeTransition, SUPERSEDED_STATE, validateFrontmatterState, } from './state-machine';
41
+ export type { TransitionOp } from './state-machine';
42
+ export { computeMemoryContentRoots, E_EMPTY_SEARCH_QUERY, findMemoryDocumentById, findMemoryDocumentByTypeAndId, listMemoryDocumentPaths, listMemoryDocumentsByType, loadMemoryDocumentSummary, searchMemoryDocuments, validateSearchQuery, } from './query';
43
+ export type { MemoryDocumentFrontmatterSummary, MemoryDocumentSummary, MemorySearchMatch, MemorySearchOptions, } from './query';
44
+ export { getMemoryHistory } from './history';
45
+ export type { MemoryHistoryEntry } from './history';
46
+ export { writeMemoryEntry } from './entry';
47
+ export type { MemoryEntryWrite } from './entry';
48
+ export { hasNumericToken, nextSequenceNumber, parseTags, renderAddDocument, resolveTypeDirectory, slugifyTitle, } from './add';
49
+ export type { AddDocumentFields } from './add';
50
+ export { formatMemoryCommitMessage, normalizeReason, parseApproverTrailerLine, parseReasonBlock, reasonDefect, reasonDefectMessage, } from './commit-message';
51
+ export type { CommitApprover, MemoryCommitMessageInput, ReasonDefect } from './commit-message';
52
+ export { describeDocumentChanges, removeFrontmatterField, setFrontmatterField, verifyDocumentEdit, verifyFrontmatterEdit, } from './frontmatter-edit';
53
+ export type { DocumentScope } from './frontmatter-edit';
54
+ export { missingRequiredFields, REJECTION_REASON_FIELD, renderSubmitDocument } from './submit';
55
+ export { renderRejectDocument } from './reject';
56
+ export { auditAttribution, isValidAttribution, parseApprovalMetadata, parseCommitReason, reconstructMemoryTransitions, verifyTransitionConsistency, } from './audit';
57
+ export type { AttributionEntry, ApprovalMetadata, MemoryTransition, ConsistencyMismatch } from './audit';
58
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,WAAW,EAAG,QAAiB,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACrF,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,yBAAyB,EACzB,oBAAoB,EACpB,sBAAsB,EACtB,6BAA6B,EAC7B,uBAAuB,EACvB,yBAAyB,EACzB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,gCAAgC,EAChC,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,SAAS,EACT,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,GACb,MAAM,OAAO,CAAC;AACf,YAAY,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,wBAAwB,EACxB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,cAAc,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidAttribution = exports.auditAttribution = exports.renderRejectDocument = exports.renderSubmitDocument = exports.REJECTION_REASON_FIELD = exports.missingRequiredFields = exports.verifyFrontmatterEdit = exports.verifyDocumentEdit = exports.setFrontmatterField = exports.removeFrontmatterField = exports.describeDocumentChanges = exports.reasonDefectMessage = exports.reasonDefect = exports.parseReasonBlock = exports.parseApproverTrailerLine = exports.normalizeReason = exports.formatMemoryCommitMessage = exports.slugifyTitle = exports.resolveTypeDirectory = exports.renderAddDocument = exports.parseTags = exports.nextSequenceNumber = exports.hasNumericToken = exports.writeMemoryEntry = exports.getMemoryHistory = exports.validateSearchQuery = exports.searchMemoryDocuments = exports.loadMemoryDocumentSummary = exports.listMemoryDocumentsByType = exports.listMemoryDocumentPaths = exports.findMemoryDocumentByTypeAndId = exports.findMemoryDocumentById = exports.E_EMPTY_SEARCH_QUERY = exports.computeMemoryContentRoots = exports.validateFrontmatterState = exports.SUPERSEDED_STATE = exports.resolveTypeTransition = exports.resolveTransitionTarget = exports.resolveStateMachine = exports.isArchivedStatus = exports.E_INVALID_TRANSITION = exports.E_INVALID_STATE = exports.DEPRECATED_STATE = exports.DEFAULT_STATE_MACHINE = exports.ARCHIVED_STATUSES = exports.TemplateConfig = exports.StateMachine = exports.MemoryTypeEntry = exports.MemoryYaml = exports.MODULE_NAME = void 0;
4
+ exports.verifyTransitionConsistency = exports.reconstructMemoryTransitions = exports.parseCommitReason = exports.parseApprovalMetadata = void 0;
5
+ /**
6
+ * `memory` module — Project Memory pillar; git-backed documents with per-type state machines
7
+ * (P1.13). `memory.yaml`'s schema (spec-001-memory-yaml-schema) lives here — the pillar owns its own
8
+ * independent schema (REQ-SYS-02); `src/core`'s loader wires it through the shared validation
9
+ * pipeline. The transition-legality engine (REQ-SYS-04, task-005-per-type-state-machines) also lives
10
+ * here — it consumes the schema's already-validated `StateMachine` shape, it does not re-validate it.
11
+ * Further Memory behavior (per-type CLI verbs, frontmatter schema) lands in later tasks.
12
+ *
13
+ * task-008-dna-memory-query-latency adds the `memory search`/`memory history` query-path
14
+ * *primitives* (REQ-PERF-02) `./query` and `./history` — the performance-bearing foundation
15
+ * `task-021-implement-memory-search` (P1.5) and `task-049-memory-history` (P1.10) built their
16
+ * CLI/MCP surface on top of; see those modules' own doc comments and the task's Execution Notes for
17
+ * the foundation/feature scoping decision.
18
+ *
19
+ * task-015-complete-audit-trail adds `./audit` (REQ-SEC-02) — the audit/verification layer built on
20
+ * `./history`'s raw git-log walk: attribution auditing (0 "unknown author"), `Approver:`/`Reason:`
21
+ * commit-body parsing, full transition reconstruction, and the frontmatter-vs-commit-message
22
+ * consistency check. It is deliberately read-only/verification-only — write-time git-identity
23
+ * enforcement is task-014-git-identity-required's (REQ-SEC-01) separate concern.
24
+ *
25
+ * task-022-implement-memory-entries adds `./entry` (P1.11) — `writeMemoryEntry`, the reusable,
26
+ * throwing library primitive that composes `resolveConfinedMemoryPath` (task-017, REQ-SEC-06),
27
+ * `writeDocument`, and `commitPaths` (task-018) into the one "resolve confined path, write bytes,
28
+ * one commit" Memory-entry write path (REQ-SYS-01/REQ-SYS-03). `wingfoil memory add`/`submit`
29
+ * (task-020) wire this in behind a `CoreResult`; this module stays a plain, throwing composition,
30
+ * matching every other `src/storage` primitive it builds on.
31
+ *
32
+ * task-036-frontmatter-lifecycle-validation adds `validateFrontmatterState` (REQ-STATE-01,
33
+ * spec-010-memory-frontmatter-schema) to `./state-machine` — the per-type membership check on a
34
+ * document's frontmatter `status` value itself, independent of any transition attempt (distinct from
35
+ * `resolveTransitionTarget`'s verb-based transition legality). `task-045-memory-submit` (P1.6) is the
36
+ * first CLI-facing consumer.
37
+ *
38
+ * task-045-memory-submit adds the pieces every Memory transition verb shares — `resolveTypeTransition`
39
+ * (the `dl-032` illegal-transition contract), `./commit-message` (the one commit-message formatter) and
40
+ * `./frontmatter-edit` (byte-preserving field edits) — plus `./submit`, the submit-specific rules.
41
+ */
42
+ exports.MODULE_NAME = 'memory';
43
+ var schema_1 = require("./schema");
44
+ Object.defineProperty(exports, "MemoryYaml", { enumerable: true, get: function () { return schema_1.MemoryYaml; } });
45
+ Object.defineProperty(exports, "MemoryTypeEntry", { enumerable: true, get: function () { return schema_1.MemoryTypeEntry; } });
46
+ Object.defineProperty(exports, "StateMachine", { enumerable: true, get: function () { return schema_1.StateMachine; } });
47
+ Object.defineProperty(exports, "TemplateConfig", { enumerable: true, get: function () { return schema_1.TemplateConfig; } });
48
+ var state_machine_1 = require("./state-machine");
49
+ Object.defineProperty(exports, "ARCHIVED_STATUSES", { enumerable: true, get: function () { return state_machine_1.ARCHIVED_STATUSES; } });
50
+ Object.defineProperty(exports, "DEFAULT_STATE_MACHINE", { enumerable: true, get: function () { return state_machine_1.DEFAULT_STATE_MACHINE; } });
51
+ Object.defineProperty(exports, "DEPRECATED_STATE", { enumerable: true, get: function () { return state_machine_1.DEPRECATED_STATE; } });
52
+ Object.defineProperty(exports, "E_INVALID_STATE", { enumerable: true, get: function () { return state_machine_1.E_INVALID_STATE; } });
53
+ Object.defineProperty(exports, "E_INVALID_TRANSITION", { enumerable: true, get: function () { return state_machine_1.E_INVALID_TRANSITION; } });
54
+ Object.defineProperty(exports, "isArchivedStatus", { enumerable: true, get: function () { return state_machine_1.isArchivedStatus; } });
55
+ Object.defineProperty(exports, "resolveStateMachine", { enumerable: true, get: function () { return state_machine_1.resolveStateMachine; } });
56
+ Object.defineProperty(exports, "resolveTransitionTarget", { enumerable: true, get: function () { return state_machine_1.resolveTransitionTarget; } });
57
+ Object.defineProperty(exports, "resolveTypeTransition", { enumerable: true, get: function () { return state_machine_1.resolveTypeTransition; } });
58
+ Object.defineProperty(exports, "SUPERSEDED_STATE", { enumerable: true, get: function () { return state_machine_1.SUPERSEDED_STATE; } });
59
+ Object.defineProperty(exports, "validateFrontmatterState", { enumerable: true, get: function () { return state_machine_1.validateFrontmatterState; } });
60
+ var query_1 = require("./query");
61
+ Object.defineProperty(exports, "computeMemoryContentRoots", { enumerable: true, get: function () { return query_1.computeMemoryContentRoots; } });
62
+ Object.defineProperty(exports, "E_EMPTY_SEARCH_QUERY", { enumerable: true, get: function () { return query_1.E_EMPTY_SEARCH_QUERY; } });
63
+ Object.defineProperty(exports, "findMemoryDocumentById", { enumerable: true, get: function () { return query_1.findMemoryDocumentById; } });
64
+ Object.defineProperty(exports, "findMemoryDocumentByTypeAndId", { enumerable: true, get: function () { return query_1.findMemoryDocumentByTypeAndId; } });
65
+ Object.defineProperty(exports, "listMemoryDocumentPaths", { enumerable: true, get: function () { return query_1.listMemoryDocumentPaths; } });
66
+ Object.defineProperty(exports, "listMemoryDocumentsByType", { enumerable: true, get: function () { return query_1.listMemoryDocumentsByType; } });
67
+ Object.defineProperty(exports, "loadMemoryDocumentSummary", { enumerable: true, get: function () { return query_1.loadMemoryDocumentSummary; } });
68
+ Object.defineProperty(exports, "searchMemoryDocuments", { enumerable: true, get: function () { return query_1.searchMemoryDocuments; } });
69
+ Object.defineProperty(exports, "validateSearchQuery", { enumerable: true, get: function () { return query_1.validateSearchQuery; } });
70
+ var history_1 = require("./history");
71
+ Object.defineProperty(exports, "getMemoryHistory", { enumerable: true, get: function () { return history_1.getMemoryHistory; } });
72
+ var entry_1 = require("./entry");
73
+ Object.defineProperty(exports, "writeMemoryEntry", { enumerable: true, get: function () { return entry_1.writeMemoryEntry; } });
74
+ var add_1 = require("./add");
75
+ Object.defineProperty(exports, "hasNumericToken", { enumerable: true, get: function () { return add_1.hasNumericToken; } });
76
+ Object.defineProperty(exports, "nextSequenceNumber", { enumerable: true, get: function () { return add_1.nextSequenceNumber; } });
77
+ Object.defineProperty(exports, "parseTags", { enumerable: true, get: function () { return add_1.parseTags; } });
78
+ Object.defineProperty(exports, "renderAddDocument", { enumerable: true, get: function () { return add_1.renderAddDocument; } });
79
+ Object.defineProperty(exports, "resolveTypeDirectory", { enumerable: true, get: function () { return add_1.resolveTypeDirectory; } });
80
+ Object.defineProperty(exports, "slugifyTitle", { enumerable: true, get: function () { return add_1.slugifyTitle; } });
81
+ var commit_message_1 = require("./commit-message");
82
+ Object.defineProperty(exports, "formatMemoryCommitMessage", { enumerable: true, get: function () { return commit_message_1.formatMemoryCommitMessage; } });
83
+ Object.defineProperty(exports, "normalizeReason", { enumerable: true, get: function () { return commit_message_1.normalizeReason; } });
84
+ Object.defineProperty(exports, "parseApproverTrailerLine", { enumerable: true, get: function () { return commit_message_1.parseApproverTrailerLine; } });
85
+ Object.defineProperty(exports, "parseReasonBlock", { enumerable: true, get: function () { return commit_message_1.parseReasonBlock; } });
86
+ Object.defineProperty(exports, "reasonDefect", { enumerable: true, get: function () { return commit_message_1.reasonDefect; } });
87
+ Object.defineProperty(exports, "reasonDefectMessage", { enumerable: true, get: function () { return commit_message_1.reasonDefectMessage; } });
88
+ var frontmatter_edit_1 = require("./frontmatter-edit");
89
+ Object.defineProperty(exports, "describeDocumentChanges", { enumerable: true, get: function () { return frontmatter_edit_1.describeDocumentChanges; } });
90
+ Object.defineProperty(exports, "removeFrontmatterField", { enumerable: true, get: function () { return frontmatter_edit_1.removeFrontmatterField; } });
91
+ Object.defineProperty(exports, "setFrontmatterField", { enumerable: true, get: function () { return frontmatter_edit_1.setFrontmatterField; } });
92
+ Object.defineProperty(exports, "verifyDocumentEdit", { enumerable: true, get: function () { return frontmatter_edit_1.verifyDocumentEdit; } });
93
+ Object.defineProperty(exports, "verifyFrontmatterEdit", { enumerable: true, get: function () { return frontmatter_edit_1.verifyFrontmatterEdit; } });
94
+ var submit_1 = require("./submit");
95
+ Object.defineProperty(exports, "missingRequiredFields", { enumerable: true, get: function () { return submit_1.missingRequiredFields; } });
96
+ Object.defineProperty(exports, "REJECTION_REASON_FIELD", { enumerable: true, get: function () { return submit_1.REJECTION_REASON_FIELD; } });
97
+ Object.defineProperty(exports, "renderSubmitDocument", { enumerable: true, get: function () { return submit_1.renderSubmitDocument; } });
98
+ var reject_1 = require("./reject");
99
+ Object.defineProperty(exports, "renderRejectDocument", { enumerable: true, get: function () { return reject_1.renderRejectDocument; } });
100
+ var audit_1 = require("./audit");
101
+ Object.defineProperty(exports, "auditAttribution", { enumerable: true, get: function () { return audit_1.auditAttribution; } });
102
+ Object.defineProperty(exports, "isValidAttribution", { enumerable: true, get: function () { return audit_1.isValidAttribution; } });
103
+ Object.defineProperty(exports, "parseApprovalMetadata", { enumerable: true, get: function () { return audit_1.parseApprovalMetadata; } });
104
+ Object.defineProperty(exports, "parseCommitReason", { enumerable: true, get: function () { return audit_1.parseCommitReason; } });
105
+ Object.defineProperty(exports, "reconstructMemoryTransitions", { enumerable: true, get: function () { return audit_1.reconstructMemoryTransitions; } });
106
+ Object.defineProperty(exports, "verifyTransitionConsistency", { enumerable: true, get: function () { return audit_1.verifyTransitionConsistency; } });
107
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":";;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACU,QAAA,WAAW,GAAG,QAAiB,CAAC;AAE7C,mCAAqF;AAA5E,oGAAA,UAAU,OAAA;AAAE,yGAAA,eAAe,OAAA;AAAE,sGAAA,YAAY,OAAA;AAAE,wGAAA,cAAc,OAAA;AAClE,iDAYyB;AAXvB,kHAAA,iBAAiB,OAAA;AACjB,sHAAA,qBAAqB,OAAA;AACrB,iHAAA,gBAAgB,OAAA;AAChB,gHAAA,eAAe,OAAA;AACf,qHAAA,oBAAoB,OAAA;AACpB,iHAAA,gBAAgB,OAAA;AAChB,oHAAA,mBAAmB,OAAA;AACnB,wHAAA,uBAAuB,OAAA;AACvB,sHAAA,qBAAqB,OAAA;AACrB,iHAAA,gBAAgB,OAAA;AAChB,yHAAA,wBAAwB,OAAA;AAG1B,iCAUiB;AATf,kHAAA,yBAAyB,OAAA;AACzB,6GAAA,oBAAoB,OAAA;AACpB,+GAAA,sBAAsB,OAAA;AACtB,sHAAA,6BAA6B,OAAA;AAC7B,gHAAA,uBAAuB,OAAA;AACvB,kHAAA,yBAAyB,OAAA;AACzB,kHAAA,yBAAyB,OAAA;AACzB,8GAAA,qBAAqB,OAAA;AACrB,4GAAA,mBAAmB,OAAA;AAQrB,qCAA6C;AAApC,2GAAA,gBAAgB,OAAA;AAEzB,iCAA2C;AAAlC,yGAAA,gBAAgB,OAAA;AAEzB,6BAOe;AANb,sGAAA,eAAe,OAAA;AACf,yGAAA,kBAAkB,OAAA;AAClB,gGAAA,SAAS,OAAA;AACT,wGAAA,iBAAiB,OAAA;AACjB,2GAAA,oBAAoB,OAAA;AACpB,mGAAA,YAAY,OAAA;AAGd,mDAO0B;AANxB,2HAAA,yBAAyB,OAAA;AACzB,iHAAA,eAAe,OAAA;AACf,0HAAA,wBAAwB,OAAA;AACxB,kHAAA,gBAAgB,OAAA;AAChB,8GAAA,YAAY,OAAA;AACZ,qHAAA,mBAAmB,OAAA;AAGrB,uDAM4B;AAL1B,2HAAA,uBAAuB,OAAA;AACvB,0HAAA,sBAAsB,OAAA;AACtB,uHAAA,mBAAmB,OAAA;AACnB,sHAAA,kBAAkB,OAAA;AAClB,yHAAA,qBAAqB,OAAA;AAGvB,mCAA+F;AAAtF,+GAAA,qBAAqB,OAAA;AAAE,gHAAA,sBAAsB,OAAA;AAAE,8GAAA,oBAAoB,OAAA;AAC5E,mCAAgD;AAAvC,8GAAA,oBAAoB,OAAA;AAC7B,iCAOiB;AANf,yGAAA,gBAAgB,OAAA;AAChB,2GAAA,kBAAkB,OAAA;AAClB,8GAAA,qBAAqB,OAAA;AACrB,0GAAA,iBAAiB,OAAA;AACjB,qHAAA,4BAA4B,OAAA;AAC5B,oHAAA,2BAA2B,OAAA"}
@@ -0,0 +1,150 @@
1
+ import type { MemoryYaml } from './schema';
2
+ /**
3
+ * Derive the minimal set of root-relative directories a scan needs to walk to see every Memory
4
+ * document declared by `memoryYaml`'s types (spec-011: path-pattern predictability, not a full-repo
5
+ * walk). A directory already covered by another (shorter) directory in the set is dropped, so the
6
+ * result never contains redundant, nested roots.
7
+ */
8
+ export declare function computeMemoryContentRoots(memoryYaml: MemoryYaml): string[];
9
+ /**
10
+ * List every Memory document under `root`, as root-relative POSIX paths, sorted lexicographically
11
+ * (REQ-SYS-07 — deterministic, no unordered iteration). Scans only the directories
12
+ * {@link computeMemoryContentRoots} derives from `memoryYaml`, never the whole project tree.
13
+ */
14
+ export declare function listMemoryDocumentPaths(root: string, memoryYaml: MemoryYaml): string[];
15
+ /** A Memory document's parsed frontmatter (loose — no Zod schema validation, see module doc) + body. */
16
+ export interface MemoryDocumentSummary {
17
+ readonly path: string;
18
+ readonly frontmatter: Record<string, unknown>;
19
+ readonly body: string;
20
+ }
21
+ /**
22
+ * Read one Memory document and split it into its parsed frontmatter and body text, without running
23
+ * it through any type's Zod schema — `memory search`/`history` must handle documents of every type
24
+ * and any (even structurally imperfect) state, so this is a read, never a validation.
25
+ */
26
+ export declare function loadMemoryDocumentSummary(root: string, relativePath: string): MemoryDocumentSummary;
27
+ /**
28
+ * Resolve a single Memory document by its `id` frontmatter value alone — REQ-PERF-04 /
29
+ * task-009-mcp-resource-fetch-latency's Acceptance Criteria, which name a `wingfoil://memory/{id}`
30
+ * benchmark fetch. This is NOT spec-004-mcp-surface-contract §2.1's Resource addressing: spec-004's
31
+ * actual scheme is `wingfoil://memory/{type}` (collection listing) and `wingfoil://memory/{type}/{id}`
32
+ * (single document) — there is no bare, single-segment `wingfoil://memory/{id}` form there, and this
33
+ * `{id}` segment would collide with spec-004's `{type}` segment. task-011-mcp-resources-read-only has
34
+ * since replaced the `wingfoil://memory/{id}` *Resource* this primitive originally backed with the
35
+ * conformant `wingfoil://memory/{type}/{id}` form (see {@link findMemoryDocumentByTypeAndId}) — this
36
+ * bare-id primitive itself is left in place (still covered by its own `test/memory/query.test.ts`
37
+ * unit tests and REQ-PERF-04's ported benchmark) as a generic, type-agnostic lookup; nothing in
38
+ * `src/mcp` calls it anymore.
39
+ *
40
+ * A linear scan over every document {@link listMemoryDocumentPaths} returns, in its
41
+ * already-deterministic sorted order, stopping at the first document whose frontmatter `id` matches
42
+ * *exactly* (never a substring — that remains `searchMemoryDocuments`'/task-021's keyword-search
43
+ * surface, not this primitive's). Returns `undefined` — never throws — when no document matches;
44
+ * turning that into a protocol-level "resource not found" failure is the MCP Resource adapter's job
45
+ * (spec-004 §2.2's general unresolvable-URI contract), not this primitive's.
46
+ */
47
+ export declare function findMemoryDocumentById(root: string, memoryYaml: MemoryYaml, id: string): MemoryDocumentSummary | undefined;
48
+ /** A Memory document's frontmatter-only summary — spec-004 §2.1's collection-listing shape
49
+ * (id, title, status, tags), deliberately omitting body content to keep listing calls cheap. */
50
+ export interface MemoryDocumentFrontmatterSummary {
51
+ readonly path: string;
52
+ readonly id?: string;
53
+ readonly title?: string;
54
+ readonly status?: string;
55
+ readonly tags: readonly string[];
56
+ }
57
+ /**
58
+ * List every Memory document whose frontmatter `type:` field equals `type` (a `memory.yaml` `types:`
59
+ * key), as frontmatter-only summaries — spec-004 §2.1's `wingfoil://memory/{type}` collection
60
+ * addressing (task-011-mcp-resources-read-only, REQ-INT-01). Sorted by `id` (falling back to `path`
61
+ * when a document has no `id`) ascending (REQ-SYS-07 — deterministic, no unordered iteration).
62
+ *
63
+ * Membership is decided by each document's own frontmatter `type:` field, not by which directory it
64
+ * lives in: several types' `path` patterns collapse to the *same* static directory prefix (e.g.
65
+ * `release`/`release-line` both resolve to `docs/04_memory/planning`; `task`'s own pattern collapses
66
+ * all the way to `docs/04_memory` itself — see {@link computeMemoryContentRoots}'s doc comment), so a
67
+ * directory-only filter would wrongly fold sibling types' documents into this type's collection.
68
+ */
69
+ export declare function listMemoryDocumentsByType(root: string, memoryYaml: MemoryYaml, type: string): MemoryDocumentFrontmatterSummary[];
70
+ /**
71
+ * Resolve a single Memory document by (`type`, `id`) — spec-004 §2.1's `wingfoil://memory/{type}/{id}`
72
+ * single-document addressing (task-011-mcp-resources-read-only, REQ-INT-01), the conformant
73
+ * replacement for task-009's bare-`{id}` `findMemoryDocumentById` Resource usage. Both `type` and `id`
74
+ * must match a document's own frontmatter — same directory-collision reasoning as
75
+ * {@link listMemoryDocumentsByType} — so this never returns a document of a *different* type merely
76
+ * because that type's path pattern happens to also resolve under the same directory. Returns
77
+ * `undefined` — never throws — when nothing matches; surfacing that as a protocol-level "resource not
78
+ * found" failure is the MCP Resource adapter's job (spec-004 §2.2), not this primitive's.
79
+ */
80
+ export declare function findMemoryDocumentByTypeAndId(root: string, memoryYaml: MemoryYaml, type: string, id: string): MemoryDocumentSummary | undefined;
81
+ /** Optional filters/refinements for {@link searchMemoryDocuments}. */
82
+ export interface MemorySearchOptions {
83
+ /** Only include documents whose `tags:` frontmatter contains this exact tag. */
84
+ readonly tag?: string;
85
+ /**
86
+ * Opt back into archived documents (`status: deprecated` or `superseded` — `ARCHIVED_STATUSES`,
87
+ * ratified by `dl-028-archived-states-excluded-from-context`) appearing in the result.
88
+ * REQ-STATE-06 excludes them by default — "default … results" in the Fit Criterion. Set this only
89
+ * for an explicit, intentional request to see archived documents (e.g. an `--status deprecated` or
90
+ * `--status superseded` narrow); never as the default for a general keyword/tag search.
91
+ * Defaults to `false`.
92
+ */
93
+ readonly includeArchived?: boolean;
94
+ }
95
+ /** One ranked search result — enough for a future CLI/MCP surface to render without re-reading the file. */
96
+ export interface MemorySearchMatch {
97
+ readonly path: string;
98
+ readonly id?: string;
99
+ readonly title?: string;
100
+ readonly tags: readonly string[];
101
+ readonly status?: string;
102
+ /** The document's frontmatter `type:` field (spec-010-memory-frontmatter-schema base field) —
103
+ * projected here (task-021-implement-memory-search) alongside `status`/`tags` so `memorySearch`'s
104
+ * `--type` filter can narrow an already-ranked result without a second file read per match. */
105
+ readonly type?: string;
106
+ /** Query matched the title, id, or a tag (P1.12: ranks above a body-only match). */
107
+ readonly metadataMatch: boolean;
108
+ /** Query matched somewhere in the document body. */
109
+ readonly bodyMatch: boolean;
110
+ }
111
+ /** `E_EMPTY_SEARCH_QUERY` field-level code (spec-009-validation-strategy §3) for a rejected empty
112
+ * or whitespace-only `wingfoil memory search` query. */
113
+ export declare const E_EMPTY_SEARCH_QUERY = "E_EMPTY_SEARCH_QUERY";
114
+ /**
115
+ * Reject an empty or whitespace-only search query (P1.12 BDD Scenario "Error - empty query string":
116
+ * "no search is performed" and exit code 2, message "empty search query"). Mirrors
117
+ * `resolveTransitionTarget`'s `ValidationError.semantic` pattern (`./state-machine.ts`) so the shared
118
+ * exit-code mapping (spec-009 §3) surfaces this as exit 2 without a bespoke error path; task-021's
119
+ * `wingfoil memory search` CLI/MCP surface calls this on the user-supplied query string before it
120
+ * ever reaches {@link searchMemoryDocuments}.
121
+ *
122
+ * Deliberately a separate guard, not a change to `searchMemoryDocuments`'s own signature/behavior:
123
+ * `searchMemoryDocuments(root, memoryYaml, '', { tag })` remains a legitimate "browse by tag alone,
124
+ * no keyword" call (task-008's own characterization test) — the empty-query rejection is this task's
125
+ * (P1.12's) algorithm-level validation concern, applied at the point a *user-facing* query string is
126
+ * about to be searched, not baked into the lower-level scan primitive that also serves tag-only
127
+ * listing.
128
+ */
129
+ export declare function validateSearchQuery(query: string): void;
130
+ /**
131
+ * Deterministic keyword/frontmatter search over every Memory document `memoryYaml` declares
132
+ * (P1.5/P1.12): case-insensitive substring matching against title/id/tags (metadata) and body text,
133
+ * optionally narrowed to one exact `tag`. A query that matches nothing returns `[]` — a successful,
134
+ * empty result, never a thrown error (that "no documents matched" outcome is a CLI/MCP-surface
135
+ * concern, task-021's, not this primitive's).
136
+ *
137
+ * Ordering is a total, deterministic order (REQ-SYS-07): metadata matches before body-only matches,
138
+ * then by `id` (falling back to `path` when a document has no `id`) ascending — so calling this
139
+ * twice against unchanged state always returns the exact same array.
140
+ *
141
+ * **REQ-STATE-06:** a document whose frontmatter `status` is archived — `deprecated` or `superseded`
142
+ * (`isArchivedStatus`, `dl-028`) — is excluded by default, so it never appears in these "default
143
+ * `memory search` results", matching the Fit Criterion verbatim, while the file itself is untouched on
144
+ * disk and in git history (`memory deprecate`, P1.9, never deletes it; `superseded` is reached by an
145
+ * ordinary `approve`). Pass `options.includeArchived: true` for the one legitimate exception: an
146
+ * explicit, intentional request to see archived documents too. `draft` documents are NOT excluded
147
+ * here — see this module's header for why the search set and the context set differ.
148
+ */
149
+ export declare function searchMemoryDocuments(root: string, memoryYaml: MemoryYaml, query: string, options?: MemorySearchOptions): MemorySearchMatch[];
150
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/memory/query.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAkB3C;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,CAQ1E;AAuBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,CAMtF;AAED,wGAAwG;AACxG,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,qBAAqB,CAYnG;AAUD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,qBAAqB,GAAG,SAAS,CAMnC;AAED;gGACgG;AAChG,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,GACX,gCAAgC,EAAE,CAkBpC;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,qBAAqB,GAAG,SAAS,CAMnC;AAED,sEAAsE;AACtE,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,4GAA4G;AAC5G,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;mGAE+F;IAC/F,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,oFAAoF;IACpF,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED;wDACwD;AACxD,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMvD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,mBAAwB,GAChC,iBAAiB,EAAE,CAqCrB"}