@isaacriehm/cairn-core 0.1.0

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 (616) hide show
  1. package/LICENSE +21 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/claude/error.d.ts +33 -0
  4. package/dist/claude/error.js +58 -0
  5. package/dist/claude/error.js.map +1 -0
  6. package/dist/claude/index.d.ts +3 -0
  7. package/dist/claude/index.js +3 -0
  8. package/dist/claude/index.js.map +1 -0
  9. package/dist/claude/runner.d.ts +11 -0
  10. package/dist/claude/runner.js +132 -0
  11. package/dist/claude/runner.js.map +1 -0
  12. package/dist/claude/types.d.ts +52 -0
  13. package/dist/claude/types.js +14 -0
  14. package/dist/claude/types.js.map +1 -0
  15. package/dist/context/checkpoint.d.ts +10 -0
  16. package/dist/context/checkpoint.js +29 -0
  17. package/dist/context/checkpoint.js.map +1 -0
  18. package/dist/context/handoff-builder.d.ts +11 -0
  19. package/dist/context/handoff-builder.js +268 -0
  20. package/dist/context/handoff-builder.js.map +1 -0
  21. package/dist/context/index.d.ts +11 -0
  22. package/dist/context/index.js +11 -0
  23. package/dist/context/index.js.map +1 -0
  24. package/dist/context/spec-delta.d.ts +47 -0
  25. package/dist/context/spec-delta.js +237 -0
  26. package/dist/context/spec-delta.js.map +1 -0
  27. package/dist/decision-capture/capture.d.ts +57 -0
  28. package/dist/decision-capture/capture.js +186 -0
  29. package/dist/decision-capture/capture.js.map +1 -0
  30. package/dist/decision-capture/extractor.d.ts +20 -0
  31. package/dist/decision-capture/extractor.js +103 -0
  32. package/dist/decision-capture/extractor.js.map +1 -0
  33. package/dist/decision-capture/id.d.ts +21 -0
  34. package/dist/decision-capture/id.js +60 -0
  35. package/dist/decision-capture/id.js.map +1 -0
  36. package/dist/decision-capture/index.d.ts +25 -0
  37. package/dist/decision-capture/index.js +21 -0
  38. package/dist/decision-capture/index.js.map +1 -0
  39. package/dist/decision-capture/prompt.d.ts +15 -0
  40. package/dist/decision-capture/prompt.js +68 -0
  41. package/dist/decision-capture/prompt.js.map +1 -0
  42. package/dist/decision-capture/refinement-prompt.d.ts +25 -0
  43. package/dist/decision-capture/refinement-prompt.js +146 -0
  44. package/dist/decision-capture/refinement-prompt.js.map +1 -0
  45. package/dist/decision-capture/refinement-schema.d.ts +52 -0
  46. package/dist/decision-capture/refinement-schema.js +61 -0
  47. package/dist/decision-capture/refinement-schema.js.map +1 -0
  48. package/dist/decision-capture/refinement.d.ts +60 -0
  49. package/dist/decision-capture/refinement.js +439 -0
  50. package/dist/decision-capture/refinement.js.map +1 -0
  51. package/dist/decision-capture/schema.d.ts +70 -0
  52. package/dist/decision-capture/schema.js +71 -0
  53. package/dist/decision-capture/schema.js.map +1 -0
  54. package/dist/decision-capture/types.d.ts +201 -0
  55. package/dist/decision-capture/types.js +20 -0
  56. package/dist/decision-capture/types.js.map +1 -0
  57. package/dist/decision-capture/writer.d.ts +90 -0
  58. package/dist/decision-capture/writer.js +267 -0
  59. package/dist/decision-capture/writer.js.map +1 -0
  60. package/dist/doctor/index.d.ts +48 -0
  61. package/dist/doctor/index.js +460 -0
  62. package/dist/doctor/index.js.map +1 -0
  63. package/dist/events/index.d.ts +15 -0
  64. package/dist/events/index.js +14 -0
  65. package/dist/events/index.js.map +1 -0
  66. package/dist/events/paths.d.ts +2 -0
  67. package/dist/events/paths.js +6 -0
  68. package/dist/events/paths.js.map +1 -0
  69. package/dist/events/reader.d.ts +40 -0
  70. package/dist/events/reader.js +139 -0
  71. package/dist/events/reader.js.map +1 -0
  72. package/dist/events/writer.d.ts +61 -0
  73. package/dist/events/writer.js +68 -0
  74. package/dist/events/writer.js.map +1 -0
  75. package/dist/frontend-types.d.ts +243 -0
  76. package/dist/frontend-types.js +15 -0
  77. package/dist/frontend-types.js.map +1 -0
  78. package/dist/gc/apply.d.ts +26 -0
  79. package/dist/gc/apply.js +48 -0
  80. package/dist/gc/apply.js.map +1 -0
  81. package/dist/gc/canary.d.ts +42 -0
  82. package/dist/gc/canary.js +134 -0
  83. package/dist/gc/canary.js.map +1 -0
  84. package/dist/gc/citation-integrity.d.ts +24 -0
  85. package/dist/gc/citation-integrity.js +151 -0
  86. package/dist/gc/citation-integrity.js.map +1 -0
  87. package/dist/gc/classify.d.ts +25 -0
  88. package/dist/gc/classify.js +89 -0
  89. package/dist/gc/classify.js.map +1 -0
  90. package/dist/gc/completion-integrity.d.ts +22 -0
  91. package/dist/gc/completion-integrity.js +165 -0
  92. package/dist/gc/completion-integrity.js.map +1 -0
  93. package/dist/gc/doc-gardening.d.ts +29 -0
  94. package/dist/gc/doc-gardening.js +146 -0
  95. package/dist/gc/doc-gardening.js.map +1 -0
  96. package/dist/gc/frontmatter.d.ts +35 -0
  97. package/dist/gc/frontmatter.js +105 -0
  98. package/dist/gc/frontmatter.js.map +1 -0
  99. package/dist/gc/generator-drift.d.ts +28 -0
  100. package/dist/gc/generator-drift.js +53 -0
  101. package/dist/gc/generator-drift.js.map +1 -0
  102. package/dist/gc/index.d.ts +42 -0
  103. package/dist/gc/index.js +30 -0
  104. package/dist/gc/index.js.map +1 -0
  105. package/dist/gc/quality-update.d.ts +23 -0
  106. package/dist/gc/quality-update.js +69 -0
  107. package/dist/gc/quality-update.js.map +1 -0
  108. package/dist/gc/scope-coverage.d.ts +20 -0
  109. package/dist/gc/scope-coverage.js +70 -0
  110. package/dist/gc/scope-coverage.js.map +1 -0
  111. package/dist/gc/stub-hits.d.ts +31 -0
  112. package/dist/gc/stub-hits.js +78 -0
  113. package/dist/gc/stub-hits.js.map +1 -0
  114. package/dist/gc/sweep.d.ts +56 -0
  115. package/dist/gc/sweep.js +205 -0
  116. package/dist/gc/sweep.js.map +1 -0
  117. package/dist/gc/types.d.ts +129 -0
  118. package/dist/gc/types.js +26 -0
  119. package/dist/gc/types.js.map +1 -0
  120. package/dist/gc/walk-source.d.ts +14 -0
  121. package/dist/gc/walk-source.js +59 -0
  122. package/dist/gc/walk-source.js.map +1 -0
  123. package/dist/ground/drift.d.ts +8 -0
  124. package/dist/ground/drift.js +23 -0
  125. package/dist/ground/drift.js.map +1 -0
  126. package/dist/ground/frontmatter.d.ts +20 -0
  127. package/dist/ground/frontmatter.js +49 -0
  128. package/dist/ground/frontmatter.js.map +1 -0
  129. package/dist/ground/glob.d.ts +10 -0
  130. package/dist/ground/glob.js +46 -0
  131. package/dist/ground/glob.js.map +1 -0
  132. package/dist/ground/index.d.ts +16 -0
  133. package/dist/ground/index.js +11 -0
  134. package/dist/ground/index.js.map +1 -0
  135. package/dist/ground/ledgers.d.ts +18 -0
  136. package/dist/ground/ledgers.js +103 -0
  137. package/dist/ground/ledgers.js.map +1 -0
  138. package/dist/ground/manifest.d.ts +10 -0
  139. package/dist/ground/manifest.js +88 -0
  140. package/dist/ground/manifest.js.map +1 -0
  141. package/dist/ground/paths.d.ts +20 -0
  142. package/dist/ground/paths.js +61 -0
  143. package/dist/ground/paths.js.map +1 -0
  144. package/dist/ground/quality-grades.d.ts +11 -0
  145. package/dist/ground/quality-grades.js +98 -0
  146. package/dist/ground/quality-grades.js.map +1 -0
  147. package/dist/ground/schemas.d.ts +306 -0
  148. package/dist/ground/schemas.js +188 -0
  149. package/dist/ground/schemas.js.map +1 -0
  150. package/dist/ground/scope-index.d.ts +48 -0
  151. package/dist/ground/scope-index.js +120 -0
  152. package/dist/ground/scope-index.js.map +1 -0
  153. package/dist/ground/walk.d.ts +7 -0
  154. package/dist/ground/walk.js +53 -0
  155. package/dist/ground/walk.js.map +1 -0
  156. package/dist/hooks/bypass-detection.d.ts +28 -0
  157. package/dist/hooks/bypass-detection.js +106 -0
  158. package/dist/hooks/bypass-detection.js.map +1 -0
  159. package/dist/hooks/index.d.ts +12 -0
  160. package/dist/hooks/index.js +13 -0
  161. package/dist/hooks/index.js.map +1 -0
  162. package/dist/hooks/post-tool-use/allowlist-reader.d.ts +14 -0
  163. package/dist/hooks/post-tool-use/allowlist-reader.js +69 -0
  164. package/dist/hooks/post-tool-use/allowlist-reader.js.map +1 -0
  165. package/dist/hooks/post-tool-use/citation-scanner.d.ts +23 -0
  166. package/dist/hooks/post-tool-use/citation-scanner.js +59 -0
  167. package/dist/hooks/post-tool-use/citation-scanner.js.map +1 -0
  168. package/dist/hooks/post-tool-use/copy-scanner.d.ts +25 -0
  169. package/dist/hooks/post-tool-use/copy-scanner.js +192 -0
  170. package/dist/hooks/post-tool-use/copy-scanner.js.map +1 -0
  171. package/dist/hooks/post-tool-use/index.d.ts +19 -0
  172. package/dist/hooks/post-tool-use/index.js +15 -0
  173. package/dist/hooks/post-tool-use/index.js.map +1 -0
  174. package/dist/hooks/post-tool-use/ledger-cache.d.ts +32 -0
  175. package/dist/hooks/post-tool-use/ledger-cache.js +236 -0
  176. package/dist/hooks/post-tool-use/ledger-cache.js.map +1 -0
  177. package/dist/hooks/post-tool-use/legend-builder.d.ts +15 -0
  178. package/dist/hooks/post-tool-use/legend-builder.js +84 -0
  179. package/dist/hooks/post-tool-use/legend-builder.js.map +1 -0
  180. package/dist/hooks/post-tool-use/read-enricher.d.ts +13 -0
  181. package/dist/hooks/post-tool-use/read-enricher.js +157 -0
  182. package/dist/hooks/post-tool-use/read-enricher.js.map +1 -0
  183. package/dist/hooks/post-tool-use/write-guardian.d.ts +17 -0
  184. package/dist/hooks/post-tool-use/write-guardian.js +176 -0
  185. package/dist/hooks/post-tool-use/write-guardian.js.map +1 -0
  186. package/dist/hooks/read-enrich.d.ts +6 -0
  187. package/dist/hooks/read-enrich.js +11 -0
  188. package/dist/hooks/read-enrich.js.map +1 -0
  189. package/dist/hooks/runners/index.d.ts +12 -0
  190. package/dist/hooks/runners/index.js +11 -0
  191. package/dist/hooks/runners/index.js.map +1 -0
  192. package/dist/hooks/runners/payload.d.ts +32 -0
  193. package/dist/hooks/runners/payload.js +70 -0
  194. package/dist/hooks/runners/payload.js.map +1 -0
  195. package/dist/hooks/runners/session-end.d.ts +7 -0
  196. package/dist/hooks/runners/session-end.js +42 -0
  197. package/dist/hooks/runners/session-end.js.map +1 -0
  198. package/dist/hooks/runners/session-start.d.ts +10 -0
  199. package/dist/hooks/runners/session-start.js +167 -0
  200. package/dist/hooks/runners/session-start.js.map +1 -0
  201. package/dist/hooks/runners/stop.d.ts +18 -0
  202. package/dist/hooks/runners/stop.js +165 -0
  203. package/dist/hooks/runners/stop.js.map +1 -0
  204. package/dist/hooks/session-end.d.ts +5 -0
  205. package/dist/hooks/session-end.js +10 -0
  206. package/dist/hooks/session-end.js.map +1 -0
  207. package/dist/hooks/session-start.d.ts +7 -0
  208. package/dist/hooks/session-start.js +12 -0
  209. package/dist/hooks/session-start.js.map +1 -0
  210. package/dist/hooks/stop.d.ts +5 -0
  211. package/dist/hooks/stop.js +10 -0
  212. package/dist/hooks/stop.js.map +1 -0
  213. package/dist/hooks/write-guard.d.ts +6 -0
  214. package/dist/hooks/write-guard.js +11 -0
  215. package/dist/hooks/write-guard.js.map +1 -0
  216. package/dist/inbox.d.ts +17 -0
  217. package/dist/inbox.js +30 -0
  218. package/dist/inbox.js.map +1 -0
  219. package/dist/index.d.ts +33 -0
  220. package/dist/index.js +32 -0
  221. package/dist/index.js.map +1 -0
  222. package/dist/init/baseline-audit.d.ts +71 -0
  223. package/dist/init/baseline-audit.js +377 -0
  224. package/dist/init/baseline-audit.js.map +1 -0
  225. package/dist/init/brand-setup.d.ts +44 -0
  226. package/dist/init/brand-setup.js +201 -0
  227. package/dist/init/brand-setup.js.map +1 -0
  228. package/dist/init/daemon-autostart.d.ts +16 -0
  229. package/dist/init/daemon-autostart.js +95 -0
  230. package/dist/init/daemon-autostart.js.map +1 -0
  231. package/dist/init/detect.d.ts +25 -0
  232. package/dist/init/detect.js +319 -0
  233. package/dist/init/detect.js.map +1 -0
  234. package/dist/init/index.d.ts +32 -0
  235. package/dist/init/index.js +18 -0
  236. package/dist/init/index.js.map +1 -0
  237. package/dist/init/ingest-docs.d.ts +74 -0
  238. package/dist/init/ingest-docs.js +499 -0
  239. package/dist/init/ingest-docs.js.map +1 -0
  240. package/dist/init/init.d.ts +165 -0
  241. package/dist/init/init.js +1166 -0
  242. package/dist/init/init.js.map +1 -0
  243. package/dist/init/mapper-legacy.d.ts +148 -0
  244. package/dist/init/mapper-legacy.js +238 -0
  245. package/dist/init/mapper-legacy.js.map +1 -0
  246. package/dist/init/mapper-merge.d.ts +38 -0
  247. package/dist/init/mapper-merge.js +238 -0
  248. package/dist/init/mapper-merge.js.map +1 -0
  249. package/dist/init/mapper-parallel.d.ts +48 -0
  250. package/dist/init/mapper-parallel.js +409 -0
  251. package/dist/init/mapper-parallel.js.map +1 -0
  252. package/dist/init/mapper-prompts.d.ts +135 -0
  253. package/dist/init/mapper-prompts.js +189 -0
  254. package/dist/init/mapper-prompts.js.map +1 -0
  255. package/dist/init/mapper.d.ts +211 -0
  256. package/dist/init/mapper.js +151 -0
  257. package/dist/init/mapper.js.map +1 -0
  258. package/dist/init/module-slicer.d.ts +39 -0
  259. package/dist/init/module-slicer.js +809 -0
  260. package/dist/init/module-slicer.js.map +1 -0
  261. package/dist/init/multi-dev/index.d.ts +2 -0
  262. package/dist/init/multi-dev/index.js +2 -0
  263. package/dist/init/multi-dev/index.js.map +1 -0
  264. package/dist/init/multi-dev/install.d.ts +40 -0
  265. package/dist/init/multi-dev/install.js +139 -0
  266. package/dist/init/multi-dev/install.js.map +1 -0
  267. package/dist/init/preflight-guards.d.ts +42 -0
  268. package/dist/init/preflight-guards.js +108 -0
  269. package/dist/init/preflight-guards.js.map +1 -0
  270. package/dist/init/prompts.d.ts +61 -0
  271. package/dist/init/prompts.js +66 -0
  272. package/dist/init/prompts.js.map +1 -0
  273. package/dist/init/rules-merge/discover.d.ts +21 -0
  274. package/dist/init/rules-merge/discover.js +78 -0
  275. package/dist/init/rules-merge/discover.js.map +1 -0
  276. package/dist/init/rules-merge/index.d.ts +10 -0
  277. package/dist/init/rules-merge/index.js +6 -0
  278. package/dist/init/rules-merge/index.js.map +1 -0
  279. package/dist/init/rules-merge/ingest.d.ts +56 -0
  280. package/dist/init/rules-merge/ingest.js +336 -0
  281. package/dist/init/rules-merge/ingest.js.map +1 -0
  282. package/dist/init/rules-merge/keep-markers.d.ts +39 -0
  283. package/dist/init/rules-merge/keep-markers.js +97 -0
  284. package/dist/init/rules-merge/keep-markers.js.map +1 -0
  285. package/dist/init/rules-merge/parse-sections.d.ts +24 -0
  286. package/dist/init/rules-merge/parse-sections.js +71 -0
  287. package/dist/init/rules-merge/parse-sections.js.map +1 -0
  288. package/dist/init/rules-merge/regenerate.d.ts +33 -0
  289. package/dist/init/rules-merge/regenerate.js +163 -0
  290. package/dist/init/rules-merge/regenerate.js.map +1 -0
  291. package/dist/init/secrets.d.ts +18 -0
  292. package/dist/init/secrets.js +76 -0
  293. package/dist/init/secrets.js.map +1 -0
  294. package/dist/init/seed.d.ts +21 -0
  295. package/dist/init/seed.js +96 -0
  296. package/dist/init/seed.js.map +1 -0
  297. package/dist/init/setup-runners.d.ts +15 -0
  298. package/dist/init/setup-runners.js +143 -0
  299. package/dist/init/setup-runners.js.map +1 -0
  300. package/dist/init/source-comments/classify.d.ts +98 -0
  301. package/dist/init/source-comments/classify.js +244 -0
  302. package/dist/init/source-comments/classify.js.map +1 -0
  303. package/dist/init/source-comments/index.d.ts +8 -0
  304. package/dist/init/source-comments/index.js +5 -0
  305. package/dist/init/source-comments/index.js.map +1 -0
  306. package/dist/init/source-comments/ingest.d.ts +51 -0
  307. package/dist/init/source-comments/ingest.js +236 -0
  308. package/dist/init/source-comments/ingest.js.map +1 -0
  309. package/dist/init/source-comments/strip-replace.d.ts +106 -0
  310. package/dist/init/source-comments/strip-replace.js +284 -0
  311. package/dist/init/source-comments/strip-replace.js.map +1 -0
  312. package/dist/init/source-comments/walker.d.ts +65 -0
  313. package/dist/init/source-comments/walker.js +777 -0
  314. package/dist/init/source-comments/walker.js.map +1 -0
  315. package/dist/init/submodules.d.ts +48 -0
  316. package/dist/init/submodules.js +149 -0
  317. package/dist/init/submodules.js.map +1 -0
  318. package/dist/init/types.d.ts +55 -0
  319. package/dist/init/types.js +10 -0
  320. package/dist/init/types.js.map +1 -0
  321. package/dist/init/visual.d.ts +69 -0
  322. package/dist/init/visual.js +265 -0
  323. package/dist/init/visual.js.map +1 -0
  324. package/dist/init/walker.d.ts +82 -0
  325. package/dist/init/walker.js +585 -0
  326. package/dist/init/walker.js.map +1 -0
  327. package/dist/init/workflow-block.d.ts +34 -0
  328. package/dist/init/workflow-block.js +110 -0
  329. package/dist/init/workflow-block.js.map +1 -0
  330. package/dist/join/index.d.ts +67 -0
  331. package/dist/join/index.js +256 -0
  332. package/dist/join/index.js.map +1 -0
  333. package/dist/lock.d.ts +39 -0
  334. package/dist/lock.js +129 -0
  335. package/dist/lock.js.map +1 -0
  336. package/dist/logger.d.ts +13 -0
  337. package/dist/logger.js +78 -0
  338. package/dist/logger.js.map +1 -0
  339. package/dist/mcp/bootstrap-guard.d.ts +29 -0
  340. package/dist/mcp/bootstrap-guard.js +47 -0
  341. package/dist/mcp/bootstrap-guard.js.map +1 -0
  342. package/dist/mcp/context.d.ts +23 -0
  343. package/dist/mcp/context.js +9 -0
  344. package/dist/mcp/context.js.map +1 -0
  345. package/dist/mcp/errors.d.ts +17 -0
  346. package/dist/mcp/errors.js +23 -0
  347. package/dist/mcp/errors.js.map +1 -0
  348. package/dist/mcp/history/index.d.ts +6 -0
  349. package/dist/mcp/history/index.js +5 -0
  350. package/dist/mcp/history/index.js.map +1 -0
  351. package/dist/mcp/history/prompt.d.ts +32 -0
  352. package/dist/mcp/history/prompt.js +99 -0
  353. package/dist/mcp/history/prompt.js.map +1 -0
  354. package/dist/mcp/history/schema.d.ts +58 -0
  355. package/dist/mcp/history/schema.js +41 -0
  356. package/dist/mcp/history/schema.js.map +1 -0
  357. package/dist/mcp/history/summarizer.d.ts +81 -0
  358. package/dist/mcp/history/summarizer.js +196 -0
  359. package/dist/mcp/history/summarizer.js.map +1 -0
  360. package/dist/mcp/history/walker.d.ts +57 -0
  361. package/dist/mcp/history/walker.js +156 -0
  362. package/dist/mcp/history/walker.js.map +1 -0
  363. package/dist/mcp/index.d.ts +13 -0
  364. package/dist/mcp/index.js +9 -0
  365. package/dist/mcp/index.js.map +1 -0
  366. package/dist/mcp/path-allowlist.d.ts +29 -0
  367. package/dist/mcp/path-allowlist.js +71 -0
  368. package/dist/mcp/path-allowlist.js.map +1 -0
  369. package/dist/mcp/result.d.ts +8 -0
  370. package/dist/mcp/result.js +18 -0
  371. package/dist/mcp/result.js.map +1 -0
  372. package/dist/mcp/schemas.d.ts +192 -0
  373. package/dist/mcp/schemas.js +174 -0
  374. package/dist/mcp/schemas.js.map +1 -0
  375. package/dist/mcp/serve.d.ts +15 -0
  376. package/dist/mcp/serve.js +71 -0
  377. package/dist/mcp/serve.js.map +1 -0
  378. package/dist/mcp/server.d.ts +11 -0
  379. package/dist/mcp/server.js +58 -0
  380. package/dist/mcp/server.js.map +1 -0
  381. package/dist/mcp/telemetry.d.ts +15 -0
  382. package/dist/mcp/telemetry.js +13 -0
  383. package/dist/mcp/telemetry.js.map +1 -0
  384. package/dist/mcp/tools/append-run-note.d.ts +18 -0
  385. package/dist/mcp/tools/append-run-note.js +47 -0
  386. package/dist/mcp/tools/append-run-note.js.map +1 -0
  387. package/dist/mcp/tools/append.d.ts +8 -0
  388. package/dist/mcp/tools/append.js +37 -0
  389. package/dist/mcp/tools/append.js.map +1 -0
  390. package/dist/mcp/tools/archive.d.ts +8 -0
  391. package/dist/mcp/tools/archive.js +72 -0
  392. package/dist/mcp/tools/archive.js.map +1 -0
  393. package/dist/mcp/tools/ask-operator.d.ts +34 -0
  394. package/dist/mcp/tools/ask-operator.js +97 -0
  395. package/dist/mcp/tools/ask-operator.js.map +1 -0
  396. package/dist/mcp/tools/canonical-for-topic.d.ts +6 -0
  397. package/dist/mcp/tools/canonical-for-topic.js +40 -0
  398. package/dist/mcp/tools/canonical-for-topic.js.map +1 -0
  399. package/dist/mcp/tools/decision-get.d.ts +6 -0
  400. package/dist/mcp/tools/decision-get.js +49 -0
  401. package/dist/mcp/tools/decision-get.js.map +1 -0
  402. package/dist/mcp/tools/decisions-for-symbol.d.ts +7 -0
  403. package/dist/mcp/tools/decisions-for-symbol.js +42 -0
  404. package/dist/mcp/tools/decisions-for-symbol.js.map +1 -0
  405. package/dist/mcp/tools/decisions-in-scope.d.ts +7 -0
  406. package/dist/mcp/tools/decisions-in-scope.js +47 -0
  407. package/dist/mcp/tools/decisions-in-scope.js.map +1 -0
  408. package/dist/mcp/tools/drop-task.d.ts +12 -0
  409. package/dist/mcp/tools/drop-task.js +68 -0
  410. package/dist/mcp/tools/drop-task.js.map +1 -0
  411. package/dist/mcp/tools/get-full.d.ts +7 -0
  412. package/dist/mcp/tools/get-full.js +46 -0
  413. package/dist/mcp/tools/get-full.js.map +1 -0
  414. package/dist/mcp/tools/ground-get.d.ts +7 -0
  415. package/dist/mcp/tools/ground-get.js +77 -0
  416. package/dist/mcp/tools/ground-get.js.map +1 -0
  417. package/dist/mcp/tools/index.d.ts +3 -0
  418. package/dist/mcp/tools/index.js +40 -0
  419. package/dist/mcp/tools/index.js.map +1 -0
  420. package/dist/mcp/tools/invariant-get.d.ts +6 -0
  421. package/dist/mcp/tools/invariant-get.js +49 -0
  422. package/dist/mcp/tools/invariant-get.js.map +1 -0
  423. package/dist/mcp/tools/invariants-in-scope.d.ts +7 -0
  424. package/dist/mcp/tools/invariants-in-scope.js +62 -0
  425. package/dist/mcp/tools/invariants-in-scope.js.map +1 -0
  426. package/dist/mcp/tools/query-history.d.ts +20 -0
  427. package/dist/mcp/tools/query-history.js +51 -0
  428. package/dist/mcp/tools/query-history.js.map +1 -0
  429. package/dist/mcp/tools/record-decision.d.ts +14 -0
  430. package/dist/mcp/tools/record-decision.js +98 -0
  431. package/dist/mcp/tools/record-decision.js.map +1 -0
  432. package/dist/mcp/tools/record-run-event.d.ts +10 -0
  433. package/dist/mcp/tools/record-run-event.js +32 -0
  434. package/dist/mcp/tools/record-run-event.js.map +1 -0
  435. package/dist/mcp/tools/resolve-attention.d.ts +31 -0
  436. package/dist/mcp/tools/resolve-attention.js +191 -0
  437. package/dist/mcp/tools/resolve-attention.js.map +1 -0
  438. package/dist/mcp/tools/search.d.ts +9 -0
  439. package/dist/mcp/tools/search.js +164 -0
  440. package/dist/mcp/tools/search.js.map +1 -0
  441. package/dist/mcp/tools/supersedes-chain.d.ts +6 -0
  442. package/dist/mcp/tools/supersedes-chain.js +66 -0
  443. package/dist/mcp/tools/supersedes-chain.js.map +1 -0
  444. package/dist/mcp/tools/timeline.d.ts +9 -0
  445. package/dist/mcp/tools/timeline.js +65 -0
  446. package/dist/mcp/tools/timeline.js.map +1 -0
  447. package/dist/mcp/tools/types.d.ts +9 -0
  448. package/dist/mcp/tools/types.js +2 -0
  449. package/dist/mcp/tools/types.js.map +1 -0
  450. package/dist/mirror/clone.d.ts +6 -0
  451. package/dist/mirror/clone.js +48 -0
  452. package/dist/mirror/clone.js.map +1 -0
  453. package/dist/mirror/dirty-overlap.d.ts +13 -0
  454. package/dist/mirror/dirty-overlap.js +42 -0
  455. package/dist/mirror/dirty-overlap.js.map +1 -0
  456. package/dist/mirror/index.d.ts +7 -0
  457. package/dist/mirror/index.js +7 -0
  458. package/dist/mirror/index.js.map +1 -0
  459. package/dist/mirror/paths.d.ts +18 -0
  460. package/dist/mirror/paths.js +45 -0
  461. package/dist/mirror/paths.js.map +1 -0
  462. package/dist/mirror/push.d.ts +9 -0
  463. package/dist/mirror/push.js +27 -0
  464. package/dist/mirror/push.js.map +1 -0
  465. package/dist/mirror/state.d.ts +4 -0
  466. package/dist/mirror/state.js +36 -0
  467. package/dist/mirror/state.js.map +1 -0
  468. package/dist/mirror/sync.d.ts +9 -0
  469. package/dist/mirror/sync.js +33 -0
  470. package/dist/mirror/sync.js.map +1 -0
  471. package/dist/mirror/types.d.ts +77 -0
  472. package/dist/mirror/types.js +2 -0
  473. package/dist/mirror/types.js.map +1 -0
  474. package/dist/paths/index.d.ts +23 -0
  475. package/dist/paths/index.js +50 -0
  476. package/dist/paths/index.js.map +1 -0
  477. package/dist/profiles/index.d.ts +3 -0
  478. package/dist/profiles/index.js +3 -0
  479. package/dist/profiles/index.js.map +1 -0
  480. package/dist/profiles/registry.d.ts +5 -0
  481. package/dist/profiles/registry.js +31 -0
  482. package/dist/profiles/registry.js.map +1 -0
  483. package/dist/profiles/types.d.ts +48 -0
  484. package/dist/profiles/types.js +11 -0
  485. package/dist/profiles/types.js.map +1 -0
  486. package/dist/profiles/unknown.d.ts +9 -0
  487. package/dist/profiles/unknown.js +17 -0
  488. package/dist/profiles/unknown.js.map +1 -0
  489. package/dist/prompt.d.ts +19 -0
  490. package/dist/prompt.js +50 -0
  491. package/dist/prompt.js.map +1 -0
  492. package/dist/sensors/attestation.d.ts +44 -0
  493. package/dist/sensors/attestation.js +262 -0
  494. package/dist/sensors/attestation.js.map +1 -0
  495. package/dist/sensors/catalog.d.ts +41 -0
  496. package/dist/sensors/catalog.js +123 -0
  497. package/dist/sensors/catalog.js.map +1 -0
  498. package/dist/sensors/decisions.d.ts +30 -0
  499. package/dist/sensors/decisions.js +393 -0
  500. package/dist/sensors/decisions.js.map +1 -0
  501. package/dist/sensors/diff.d.ts +27 -0
  502. package/dist/sensors/diff.js +148 -0
  503. package/dist/sensors/diff.js.map +1 -0
  504. package/dist/sensors/index.d.ts +13 -0
  505. package/dist/sensors/index.js +9 -0
  506. package/dist/sensors/index.js.map +1 -0
  507. package/dist/sensors/remediation.d.ts +20 -0
  508. package/dist/sensors/remediation.js +65 -0
  509. package/dist/sensors/remediation.js.map +1 -0
  510. package/dist/sensors/runner.d.ts +44 -0
  511. package/dist/sensors/runner.js +95 -0
  512. package/dist/sensors/runner.js.map +1 -0
  513. package/dist/sensors/structural.d.ts +30 -0
  514. package/dist/sensors/structural.js +204 -0
  515. package/dist/sensors/structural.js.map +1 -0
  516. package/dist/sensors/stub-catalog.d.ts +39 -0
  517. package/dist/sensors/stub-catalog.js +115 -0
  518. package/dist/sensors/stub-catalog.js.map +1 -0
  519. package/dist/sensors/types.d.ts +135 -0
  520. package/dist/sensors/types.js +14 -0
  521. package/dist/sensors/types.js.map +1 -0
  522. package/dist/session/events-marker.d.ts +39 -0
  523. package/dist/session/events-marker.js +74 -0
  524. package/dist/session/events-marker.js.map +1 -0
  525. package/dist/session/id.d.ts +83 -0
  526. package/dist/session/id.js +166 -0
  527. package/dist/session/id.js.map +1 -0
  528. package/dist/session/index.d.ts +14 -0
  529. package/dist/session/index.js +13 -0
  530. package/dist/session/index.js.map +1 -0
  531. package/dist/session-start/build.d.ts +53 -0
  532. package/dist/session-start/build.js +645 -0
  533. package/dist/session-start/build.js.map +1 -0
  534. package/dist/session-start/index.d.ts +18 -0
  535. package/dist/session-start/index.js +18 -0
  536. package/dist/session-start/index.js.map +1 -0
  537. package/dist/session-start/templates.d.ts +6 -0
  538. package/dist/session-start/templates.js +38 -0
  539. package/dist/session-start/templates.js.map +1 -0
  540. package/dist/status-line/format.d.ts +14 -0
  541. package/dist/status-line/format.js +40 -0
  542. package/dist/status-line/format.js.map +1 -0
  543. package/dist/status-line/index.d.ts +29 -0
  544. package/dist/status-line/index.js +14 -0
  545. package/dist/status-line/index.js.map +1 -0
  546. package/dist/status-line/reader.d.ts +13 -0
  547. package/dist/status-line/reader.js +76 -0
  548. package/dist/status-line/reader.js.map +1 -0
  549. package/dist/status-line/writer.d.ts +33 -0
  550. package/dist/status-line/writer.js +72 -0
  551. package/dist/status-line/writer.js.map +1 -0
  552. package/dist/tier0/classify.d.ts +10 -0
  553. package/dist/tier0/classify.js +110 -0
  554. package/dist/tier0/classify.js.map +1 -0
  555. package/dist/tier0/index.d.ts +2 -0
  556. package/dist/tier0/index.js +2 -0
  557. package/dist/tier0/index.js.map +1 -0
  558. package/dist/tier0/ollama.d.ts +22 -0
  559. package/dist/tier0/ollama.js +63 -0
  560. package/dist/tier0/ollama.js.map +1 -0
  561. package/dist/tier0/types.d.ts +24 -0
  562. package/dist/tier0/types.js +9 -0
  563. package/dist/tier0/types.js.map +1 -0
  564. package/dist/tightener/index.d.ts +4 -0
  565. package/dist/tightener/index.js +4 -0
  566. package/dist/tightener/index.js.map +1 -0
  567. package/dist/tightener/prompt.d.ts +3 -0
  568. package/dist/tightener/prompt.js +67 -0
  569. package/dist/tightener/prompt.js.map +1 -0
  570. package/dist/tightener/schema.d.ts +68 -0
  571. package/dist/tightener/schema.js +44 -0
  572. package/dist/tightener/schema.js.map +1 -0
  573. package/dist/tightener/tighten.d.ts +2 -0
  574. package/dist/tightener/tighten.js +66 -0
  575. package/dist/tightener/tighten.js.map +1 -0
  576. package/dist/tightener/types.d.ts +74 -0
  577. package/dist/tightener/types.js +6 -0
  578. package/dist/tightener/types.js.map +1 -0
  579. package/dist/voice/index.d.ts +4 -0
  580. package/dist/voice/index.js +4 -0
  581. package/dist/voice/index.js.map +1 -0
  582. package/dist/voice/model.d.ts +23 -0
  583. package/dist/voice/model.js +46 -0
  584. package/dist/voice/model.js.map +1 -0
  585. package/dist/voice/pipe.d.ts +9 -0
  586. package/dist/voice/pipe.js +47 -0
  587. package/dist/voice/pipe.js.map +1 -0
  588. package/dist/voice/transcribe.d.ts +3 -0
  589. package/dist/voice/transcribe.js +43 -0
  590. package/dist/voice/transcribe.js.map +1 -0
  591. package/dist/voice/types.d.ts +26 -0
  592. package/dist/voice/types.js +9 -0
  593. package/dist/voice/types.js.map +1 -0
  594. package/package.json +54 -0
  595. package/templates/.archive/README.md +67 -0
  596. package/templates/.cairn/JOIN.md +87 -0
  597. package/templates/.cairn/config/sensors.yaml +185 -0
  598. package/templates/.cairn/config/stub-patterns.yaml +231 -0
  599. package/templates/.cairn/config/trust-policy.yaml +95 -0
  600. package/templates/.cairn/config/workflow.md +230 -0
  601. package/templates/.cairn/git-hooks/commit-msg +17 -0
  602. package/templates/.cairn/git-hooks/post-commit +28 -0
  603. package/templates/.cairn/git-hooks/pre-commit +24 -0
  604. package/templates/.cairn/ground/brand/overview.md +24 -0
  605. package/templates/.cairn/ground/brand/voice.md +20 -0
  606. package/templates/.cairn/ground/canonical-map/topics.yaml +54 -0
  607. package/templates/.cairn/ground/capabilities/mcp-tools.yaml +4 -0
  608. package/templates/.cairn/ground/capabilities/skills.yaml +3 -0
  609. package/templates/.cairn/ground/capabilities/snippets.yaml +3 -0
  610. package/templates/.cairn/ground/manifest.yaml +16 -0
  611. package/templates/.cairn/ground/product/personas.yaml +4 -0
  612. package/templates/.cairn/ground/product/positioning.md +21 -0
  613. package/templates/.claude/settings.json +57 -0
  614. package/templates/.github/workflows/cairn-check.yml +31 -0
  615. package/templates/.mcp.json +8 -0
  616. package/templates/README.md +24 -0
@@ -0,0 +1,29 @@
1
+ /**
2
+ * GC pass 4 — doc gardening.
3
+ *
4
+ * Walks every markdown in the canonical zone and surfaces:
5
+ * - broken-link findings: `[text](relative/path.md)` whose target doesn't exist
6
+ * under repoRoot. Absolute URLs (https://...) are skipped.
7
+ * - orphan-path findings: markdown files that are not referenced by any other
8
+ * markdown in the canonical zone. Orientation files (AGENTS.md, CLAUDE.md,
9
+ * README.md, RESUME_PROMPT.md) and explicitly-allowed roots are excluded.
10
+ *
11
+ * Phase 12 v1 surfaces only — moving orphans to `.archive/` per the original
12
+ * spec needs operator confirmation (it's a non-trivial canonical-zone change).
13
+ * The proposal type is set up so a future revision can attach an archive-move
14
+ * commit when the operator opts in.
15
+ */
16
+ import type { GcFinding } from "./types.js";
17
+ export interface DocGardeningOptions {
18
+ repoRoot: string;
19
+ /**
20
+ * Additional repo-relative paths to treat as orphan-allowed roots. Useful
21
+ * for project-specific entry-point docs that nothing links to (e.g. wiki
22
+ * landing pages).
23
+ */
24
+ orphanExcludes?: readonly string[];
25
+ }
26
+ export interface DocGardeningResult {
27
+ findings: GcFinding[];
28
+ }
29
+ export declare function runDocGardening(opts: DocGardeningOptions): DocGardeningResult;
@@ -0,0 +1,146 @@
1
+ /**
2
+ * GC pass 4 — doc gardening.
3
+ *
4
+ * Walks every markdown in the canonical zone and surfaces:
5
+ * - broken-link findings: `[text](relative/path.md)` whose target doesn't exist
6
+ * under repoRoot. Absolute URLs (https://...) are skipped.
7
+ * - orphan-path findings: markdown files that are not referenced by any other
8
+ * markdown in the canonical zone. Orientation files (AGENTS.md, CLAUDE.md,
9
+ * README.md, RESUME_PROMPT.md) and explicitly-allowed roots are excluded.
10
+ *
11
+ * Phase 12 v1 surfaces only — moving orphans to `.archive/` per the original
12
+ * spec needs operator confirmation (it's a non-trivial canonical-zone change).
13
+ * The proposal type is set up so a future revision can attach an archive-move
14
+ * commit when the operator opts in.
15
+ */
16
+ import { existsSync, readFileSync, statSync } from "node:fs";
17
+ import { dirname, posix, resolve } from "node:path";
18
+ import { walkCanonical } from "../ground/walk.js";
19
+ const PASS_ID = "doc-gardening";
20
+ const ORPHAN_ROOT_EXCLUDES = [
21
+ "AGENTS.md",
22
+ "CLAUDE.md",
23
+ "README.md",
24
+ "RESUME_PROMPT.md",
25
+ ".cairn/config/workflow.md",
26
+ ".cairn/config/sensors.yaml",
27
+ ".cairn/config/stub-patterns.yaml",
28
+ ".cairn/config/trust-policy.yaml",
29
+ ];
30
+ export function runDocGardening(opts) {
31
+ const findings = [];
32
+ const allFiles = walkCanonical(opts.repoRoot);
33
+ const mdFiles = allFiles.filter((p) => p.endsWith(".md"));
34
+ const referenced = new Set();
35
+ for (const rel of mdFiles) {
36
+ const abs = resolve(opts.repoRoot, rel);
37
+ let source;
38
+ try {
39
+ source = readFileSync(abs, "utf8");
40
+ }
41
+ catch {
42
+ continue;
43
+ }
44
+ const links = extractMarkdownLinks(source);
45
+ for (const link of links) {
46
+ if (link.url.length === 0)
47
+ continue;
48
+ if (isExternalUrl(link.url))
49
+ continue;
50
+ if (link.url.startsWith("#"))
51
+ continue; // intra-page anchor
52
+ const target = resolveLinkTarget(opts.repoRoot, rel, link.url);
53
+ if (target === null)
54
+ continue;
55
+ if (!fileExists(opts.repoRoot, target)) {
56
+ findings.push({
57
+ pass: PASS_ID,
58
+ kind: "broken_link",
59
+ path: rel,
60
+ detail: `${rel}:${link.line} → \`${link.url}\` (target ${target} missing)`,
61
+ severity: "warn",
62
+ line: link.line,
63
+ matched_text: link.url,
64
+ });
65
+ }
66
+ else if (target.endsWith(".md")) {
67
+ referenced.add(target);
68
+ }
69
+ }
70
+ }
71
+ // Orphan detection — markdowns not referenced by any other markdown.
72
+ const allowOrphan = new Set([
73
+ ...ORPHAN_ROOT_EXCLUDES,
74
+ ...(opts.orphanExcludes ?? []),
75
+ ]);
76
+ for (const rel of mdFiles) {
77
+ if (allowOrphan.has(rel))
78
+ continue;
79
+ if (!referenced.has(rel)) {
80
+ findings.push({
81
+ pass: PASS_ID,
82
+ kind: "orphan_path",
83
+ path: rel,
84
+ detail: `${rel} is not referenced by any other markdown in the canonical zone — candidate for .archive/ move`,
85
+ severity: "warn",
86
+ });
87
+ }
88
+ }
89
+ return { findings };
90
+ }
91
+ function extractMarkdownLinks(source) {
92
+ // Match ](url) part of an inline link. Allow spaces inside text. Skip
93
+ // images (preceded by `!`) and reference-style links.
94
+ const out = [];
95
+ // Build line-index map.
96
+ const re = /(!?)\[([^\]\n]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
97
+ let m;
98
+ while ((m = re.exec(source)) !== null) {
99
+ const isImage = m[1] === "!";
100
+ const text = m[2] ?? "";
101
+ const url = m[3] ?? "";
102
+ if (isImage)
103
+ continue;
104
+ out.push({ text, url, line: lineOf(source, m.index) });
105
+ }
106
+ return out;
107
+ }
108
+ function isExternalUrl(url) {
109
+ return /^[a-z]+:\/\//i.test(url) || url.startsWith("mailto:");
110
+ }
111
+ function resolveLinkTarget(repoRoot, fromRel, url) {
112
+ // Strip fragment.
113
+ const hashIdx = url.indexOf("#");
114
+ const cleanUrl = hashIdx === -1 ? url : url.slice(0, hashIdx);
115
+ if (cleanUrl.length === 0)
116
+ return null;
117
+ // Absolute paths inside the repo (rare, but tolerated).
118
+ if (cleanUrl.startsWith("/")) {
119
+ return cleanUrl.replace(/^\/+/, "");
120
+ }
121
+ const fromDir = dirname(fromRel);
122
+ const joined = posix.normalize(posix.join(fromDir, cleanUrl));
123
+ if (joined.startsWith(".."))
124
+ return null; // escapes repo root
125
+ return joined;
126
+ }
127
+ function fileExists(repoRoot, rel) {
128
+ const abs = resolve(repoRoot, rel);
129
+ if (!existsSync(abs))
130
+ return false;
131
+ try {
132
+ return statSync(abs).isFile() || statSync(abs).isDirectory();
133
+ }
134
+ catch {
135
+ return false;
136
+ }
137
+ }
138
+ function lineOf(text, charIndex) {
139
+ let line = 1;
140
+ for (let i = 0; i < charIndex && i < text.length; i++) {
141
+ if (text.charCodeAt(i) === 10 /* \n */)
142
+ line += 1;
143
+ }
144
+ return line;
145
+ }
146
+ //# sourceMappingURL=doc-gardening.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc-gardening.js","sourceRoot":"","sources":["../../src/gc/doc-gardening.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * GC pass 1 — frontmatter freshness.
3
+ *
4
+ * Walks the canonical zone via `walkCanonical`, parses each markdown's
5
+ * provenance frontmatter, and surfaces docs whose `verified-at` exceeds the
6
+ * configured warn (30d) / block (60d) thresholds.
7
+ *
8
+ * Phase 12 v1 surfaces only — it does NOT auto-bump verified-at, because a
9
+ * timestamp bump without re-verification is a lie. Future revisions may add
10
+ * an opt-in "refresh-and-bump" proposal for safe-class docs whose content
11
+ * sha hasn't changed since the last verified-at, but that's out of v1 scope.
12
+ *
13
+ * Exception: when `forceRefresh: true` is passed (smoke / dev only), the pass
14
+ * proposes a frontmatter-only verified-at bump as a safe-class commit. The
15
+ * smoke uses this path to exercise the auto-merge end-to-end.
16
+ */
17
+ import type { GcCommitProposal, GcFinding } from "./types.js";
18
+ export interface FrontmatterFreshnessOptions {
19
+ repoRoot: string;
20
+ warnDays?: number;
21
+ blockDays?: number;
22
+ /** Default = new Date(); injected for tests. */
23
+ now?: Date;
24
+ /**
25
+ * When true, produce a frontmatter-only safe-class commit proposal that
26
+ * bumps verified-at to `now` for every stale doc. Off by default — see
27
+ * module header. Smoke uses this.
28
+ */
29
+ forceRefresh?: boolean;
30
+ }
31
+ export interface FrontmatterFreshnessResult {
32
+ findings: GcFinding[];
33
+ proposals: GcCommitProposal[];
34
+ }
35
+ export declare function runFrontmatterFreshness(opts: FrontmatterFreshnessOptions): FrontmatterFreshnessResult;
@@ -0,0 +1,105 @@
1
+ /**
2
+ * GC pass 1 — frontmatter freshness.
3
+ *
4
+ * Walks the canonical zone via `walkCanonical`, parses each markdown's
5
+ * provenance frontmatter, and surfaces docs whose `verified-at` exceeds the
6
+ * configured warn (30d) / block (60d) thresholds.
7
+ *
8
+ * Phase 12 v1 surfaces only — it does NOT auto-bump verified-at, because a
9
+ * timestamp bump without re-verification is a lie. Future revisions may add
10
+ * an opt-in "refresh-and-bump" proposal for safe-class docs whose content
11
+ * sha hasn't changed since the last verified-at, but that's out of v1 scope.
12
+ *
13
+ * Exception: when `forceRefresh: true` is passed (smoke / dev only), the pass
14
+ * proposes a frontmatter-only verified-at bump as a safe-class commit. The
15
+ * smoke uses this path to exercise the auto-merge end-to-end.
16
+ */
17
+ import { readFileSync } from "node:fs";
18
+ import { resolve } from "node:path";
19
+ import { evaluateFreshness, parseFrontmatter } from "../ground/frontmatter.js";
20
+ import { walkCanonical } from "../ground/walk.js";
21
+ const PASS_ID = "frontmatter-freshness";
22
+ export function runFrontmatterFreshness(opts) {
23
+ const warnDays = opts.warnDays ?? 30;
24
+ const blockDays = opts.blockDays ?? 60;
25
+ const now = opts.now ?? new Date();
26
+ const findings = [];
27
+ const refreshes = [];
28
+ const files = walkCanonical(opts.repoRoot);
29
+ for (const rel of files) {
30
+ if (!rel.endsWith(".md"))
31
+ continue;
32
+ const abs = resolve(opts.repoRoot, rel);
33
+ const source = readFileSync(abs, "utf8");
34
+ const parsed = parseFrontmatter(source);
35
+ if (!parsed.frontmatter)
36
+ continue;
37
+ const verdict = evaluateFreshness(parsed.frontmatter, warnDays, blockDays, now);
38
+ if (verdict.status === "fresh" || verdict.status === "unknown")
39
+ continue;
40
+ findings.push({
41
+ pass: PASS_ID,
42
+ kind: "frontmatter_stale",
43
+ path: rel,
44
+ detail: verdict.status === "block"
45
+ ? `verified-at is ${verdict.ageDays}d old (>=${blockDays}d block threshold) — re-verify before relying`
46
+ : `verified-at is ${verdict.ageDays}d old (>=${warnDays}d warn threshold)`,
47
+ severity: verdict.status === "block" ? "block" : "warn",
48
+ ...(verdict.ageDays !== null ? { age_days: verdict.ageDays } : {}),
49
+ });
50
+ if (opts.forceRefresh) {
51
+ const refreshed = bumpVerifiedAt(source, now);
52
+ refreshes.push({ path: rel, content: refreshed });
53
+ }
54
+ }
55
+ const proposals = [];
56
+ if (refreshes.length > 0) {
57
+ const patch = {};
58
+ for (const r of refreshes)
59
+ patch[r.path] = r.content;
60
+ const paths = refreshes.map((r) => r.path).sort();
61
+ proposals.push({
62
+ pass: PASS_ID,
63
+ class: "safe",
64
+ paths,
65
+ patch,
66
+ commit_message: composeCommitMessage(paths.length, now),
67
+ findings: findings.filter((f) => paths.includes(f.path)),
68
+ });
69
+ }
70
+ return { findings, proposals };
71
+ }
72
+ /**
73
+ * Rewrite the frontmatter block with verified-at bumped to `now`. Preserves
74
+ * key order by replacing only the `verified-at:` line (or inserting it
75
+ * directly after `generated:` when missing).
76
+ */
77
+ function bumpVerifiedAt(source, now) {
78
+ const iso = now.toISOString();
79
+ // Frontmatter is fenced by `---` lines at the top of the file; replace the
80
+ // first `verified-at:` line in the fence region. If none, insert it after
81
+ // `generated:` if present, else at the end of the fence block.
82
+ const fenceEndIdx = source.indexOf("\n---", 3);
83
+ if (fenceEndIdx === -1)
84
+ return source;
85
+ const fenceText = source.slice(0, fenceEndIdx);
86
+ const restText = source.slice(fenceEndIdx);
87
+ const verifiedAtRe = /^verified-at:.*$/m;
88
+ if (verifiedAtRe.test(fenceText)) {
89
+ return fenceText.replace(verifiedAtRe, `verified-at: ${iso}`) + restText;
90
+ }
91
+ // Insert after generated: line if present.
92
+ const generatedRe = /^(generated:.*)$/m;
93
+ if (generatedRe.test(fenceText)) {
94
+ return fenceText.replace(generatedRe, `$1\nverified-at: ${iso}`) + restText;
95
+ }
96
+ return fenceText + `\nverified-at: ${iso}` + restText;
97
+ }
98
+ function composeCommitMessage(count, now) {
99
+ const ymd = now.toISOString().slice(0, 10);
100
+ const subject = `chore(gc): refresh frontmatter verified-at on ${count} doc${count === 1 ? "" : "s"} (${ymd})`;
101
+ const body = "GC frontmatter-freshness pass — content unchanged; bumping verified-at to today.\n" +
102
+ "Auto-applied as safe-class per L16 (PRIMER §12.2).\n";
103
+ return `${subject}\n\n${body}`;
104
+ }
105
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/gc/frontmatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * GC pass 2 — generator drift.
3
+ *
4
+ * Iterates every `Profile.extractors` and re-runs them. For each extractor:
5
+ * - run(ctx) → newContent | null
6
+ * - read existing file at outputRelPath → currentContent
7
+ * - if differ → emit a finding + a safe-class commit proposal that
8
+ * overwrites outputRelPath with newContent.
9
+ *
10
+ * Per spec: "auto-regenerate; commit `chore(gc): regenerate <artifact>` if no
11
+ * source change required". A regenerated artifact whose deterministic output
12
+ * matches the spec but doesn't match disk is exactly drift — replace it.
13
+ *
14
+ * The unknown profile has zero extractors, so on a vanilla repo this pass is
15
+ * a no-op. Future profiles (typescript-next-nest, etc.) wire their extractors
16
+ * via `registerProfile()` and they show up here automatically.
17
+ */
18
+ import type { Profile } from "../profiles/types.js";
19
+ import type { GcCommitProposal, GcFinding } from "./types.js";
20
+ export interface GeneratorDriftOptions {
21
+ repoRoot: string;
22
+ profile: Profile;
23
+ }
24
+ export interface GeneratorDriftResult {
25
+ findings: GcFinding[];
26
+ proposals: GcCommitProposal[];
27
+ }
28
+ export declare function runGeneratorDrift(opts: GeneratorDriftOptions): Promise<GeneratorDriftResult>;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * GC pass 2 — generator drift.
3
+ *
4
+ * Iterates every `Profile.extractors` and re-runs them. For each extractor:
5
+ * - run(ctx) → newContent | null
6
+ * - read existing file at outputRelPath → currentContent
7
+ * - if differ → emit a finding + a safe-class commit proposal that
8
+ * overwrites outputRelPath with newContent.
9
+ *
10
+ * Per spec: "auto-regenerate; commit `chore(gc): regenerate <artifact>` if no
11
+ * source change required". A regenerated artifact whose deterministic output
12
+ * matches the spec but doesn't match disk is exactly drift — replace it.
13
+ *
14
+ * The unknown profile has zero extractors, so on a vanilla repo this pass is
15
+ * a no-op. Future profiles (typescript-next-nest, etc.) wire their extractors
16
+ * via `registerProfile()` and they show up here automatically.
17
+ */
18
+ import { existsSync, readFileSync } from "node:fs";
19
+ import { resolve } from "node:path";
20
+ const PASS_ID = "generator-drift";
21
+ export async function runGeneratorDrift(opts) {
22
+ const findings = [];
23
+ const proposals = [];
24
+ for (const extractor of opts.profile.extractors) {
25
+ const newContent = await extractor.run({ repoRoot: opts.repoRoot });
26
+ if (newContent === null)
27
+ continue; // extractor opted to skip
28
+ const outAbs = resolve(opts.repoRoot, extractor.outputRelPath);
29
+ const currentContent = existsSync(outAbs) ? readFileSync(outAbs, "utf8") : "";
30
+ if (currentContent === newContent)
31
+ continue;
32
+ const finding = {
33
+ pass: PASS_ID,
34
+ kind: "generator_drift",
35
+ path: extractor.outputRelPath,
36
+ detail: `extractor \`${extractor.id}\` produces output that differs from on-disk content (${currentContent.length === 0 ? "missing" : "stale"}) — regenerating`,
37
+ severity: "warn",
38
+ };
39
+ findings.push(finding);
40
+ proposals.push({
41
+ pass: PASS_ID,
42
+ class: "safe",
43
+ paths: [extractor.outputRelPath],
44
+ patch: { [extractor.outputRelPath]: newContent },
45
+ commit_message: `chore(gc): regenerate ${extractor.outputRelPath}\n\n` +
46
+ `GC generator-drift pass — extractor \`${extractor.id}\` produces output that differs from on-disk.\n` +
47
+ `Auto-applied as safe-class per PRIMER §12.2.\n`,
48
+ findings: [finding],
49
+ });
50
+ }
51
+ return { findings, proposals };
52
+ }
53
+ //# sourceMappingURL=generator-drift.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator-drift.js","sourceRoot":"","sources":["../../src/gc/generator-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,OAAO,GAAG,iBAA0B,CAAC;AAY3C,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAA2B;IAE3B,MAAM,QAAQ,GAAgB,EAAE,CAAC;IACjC,MAAM,SAAS,GAAuB,EAAE,CAAC;IAEzC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAChD,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpE,IAAI,UAAU,KAAK,IAAI;YAAE,SAAS,CAAC,0BAA0B;QAE7D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;QAC/D,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE9E,IAAI,cAAc,KAAK,UAAU;YAAE,SAAS;QAE5C,MAAM,OAAO,GAAc;YACzB,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,SAAS,CAAC,aAAa;YAC7B,MAAM,EAAE,eAAe,SAAS,CAAC,EAAE,yDACjC,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAC5C,kBAAkB;YAClB,QAAQ,EAAE,MAAM;SACjB,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEvB,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC;YAChC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE;YAChD,cAAc,EACZ,yBAAyB,SAAS,CAAC,aAAa,MAAM;gBACtD,yCAAyC,SAAS,CAAC,EAAE,iDAAiD;gBACtG,gDAAgD;YAClD,QAAQ,EAAE,CAAC,OAAO,CAAC;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Phase 12 — garbage collection cadence.
3
+ *
4
+ * Public surface:
5
+ * - runGcSweep(opts) → composes all five passes
6
+ * - runGcBatch(opts) → sweep + classify + apply + canary
7
+ * - applyCommit(opts) → apply a single proposal
8
+ * - verifyBatchCanary(opts) → standalone canary check
9
+ * - classifyAutoMerge(args) → safe | code | high-stakes
10
+ * - runFrontmatterFreshness, runGeneratorDrift, runStubCatalogHits,
11
+ * runDocGardening, runQualityGradesUpdate — direct pass entry points
12
+ *
13
+ * Used by the CLI (`cairn gc run`) and the smoke test
14
+ * (`cairn/scripts/smoke-gc.ts`). Future cron / `/loop` integration consumes
15
+ * the same surface.
16
+ */
17
+ export type { GcAutoMergeClass, GcBatchResult, GcCommitProposal, GcFinding, GcFindingKind, GcPassId, GcSweepResult, CanarySyntheticContext, } from "./types.js";
18
+ export { applyCommit } from "./apply.js";
19
+ export type { ApplyCommitOptions, ApplyCommitResult } from "./apply.js";
20
+ export { verifyBatchCanary, buildSyntheticContext, } from "./canary.js";
21
+ export type { BatchCanaryResult, BatchCanaryOptions, } from "./canary.js";
22
+ export { runCitationIntegrity } from "./citation-integrity.js";
23
+ export type { CitationIntegrityOptions, CitationIntegrityResult, } from "./citation-integrity.js";
24
+ export { classifyAutoMerge } from "./classify.js";
25
+ export type { ClassifyArgs } from "./classify.js";
26
+ export { runCompletionIntegrity } from "./completion-integrity.js";
27
+ export type { CompletionIntegrityOptions, CompletionIntegrityResult, } from "./completion-integrity.js";
28
+ export { runDocGardening } from "./doc-gardening.js";
29
+ export type { DocGardeningOptions, DocGardeningResult, } from "./doc-gardening.js";
30
+ export { runFrontmatterFreshness, } from "./frontmatter.js";
31
+ export type { FrontmatterFreshnessOptions, FrontmatterFreshnessResult, } from "./frontmatter.js";
32
+ export { runGeneratorDrift } from "./generator-drift.js";
33
+ export type { GeneratorDriftOptions, GeneratorDriftResult, } from "./generator-drift.js";
34
+ export { runQualityGradesUpdate } from "./quality-update.js";
35
+ export type { QualityUpdateOptions, QualityUpdateResult, } from "./quality-update.js";
36
+ export { runScopeCoverage } from "./scope-coverage.js";
37
+ export type { ScopeCoverageOptions, ScopeCoverageResult, } from "./scope-coverage.js";
38
+ export { runStubCatalogHits } from "./stub-hits.js";
39
+ export type { StubCatalogHitsOptions, StubCatalogHitsResult, } from "./stub-hits.js";
40
+ export { runGcBatch, runGcSweep } from "./sweep.js";
41
+ export type { RunGcBatchOptions, RunGcSweepOptions, } from "./sweep.js";
42
+ export { walkSourceTree, SOURCE_TREE_SKIP_DIRS } from "./walk-source.js";
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Phase 12 — garbage collection cadence.
3
+ *
4
+ * Public surface:
5
+ * - runGcSweep(opts) → composes all five passes
6
+ * - runGcBatch(opts) → sweep + classify + apply + canary
7
+ * - applyCommit(opts) → apply a single proposal
8
+ * - verifyBatchCanary(opts) → standalone canary check
9
+ * - classifyAutoMerge(args) → safe | code | high-stakes
10
+ * - runFrontmatterFreshness, runGeneratorDrift, runStubCatalogHits,
11
+ * runDocGardening, runQualityGradesUpdate — direct pass entry points
12
+ *
13
+ * Used by the CLI (`cairn gc run`) and the smoke test
14
+ * (`cairn/scripts/smoke-gc.ts`). Future cron / `/loop` integration consumes
15
+ * the same surface.
16
+ */
17
+ export { applyCommit } from "./apply.js";
18
+ export { verifyBatchCanary, buildSyntheticContext, } from "./canary.js";
19
+ export { runCitationIntegrity } from "./citation-integrity.js";
20
+ export { classifyAutoMerge } from "./classify.js";
21
+ export { runCompletionIntegrity } from "./completion-integrity.js";
22
+ export { runDocGardening } from "./doc-gardening.js";
23
+ export { runFrontmatterFreshness, } from "./frontmatter.js";
24
+ export { runGeneratorDrift } from "./generator-drift.js";
25
+ export { runQualityGradesUpdate } from "./quality-update.js";
26
+ export { runScopeCoverage } from "./scope-coverage.js";
27
+ export { runStubCatalogHits } from "./stub-hits.js";
28
+ export { runGcBatch, runGcSweep } from "./sweep.js";
29
+ export { walkSourceTree, SOURCE_TREE_SKIP_DIRS } from "./walk-source.js";
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAaH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EACL,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAK/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAKnE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAKrD,OAAO,EACL,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAKzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAK7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAKvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAKpD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKpD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * GC pass 5 — quality grades update.
3
+ *
4
+ * Rebuilds `.cairn/ground/quality-grades.yaml` from terminal-run history at
5
+ * `.cairn/runs/terminal/*`. The grounding daemon also writes this file on
6
+ * watch events, so GC's job is to ensure a fresh write lands on the GC cron
7
+ * and that any drift between the file's content and the latest reality is
8
+ * captured as a safe-class commit.
9
+ *
10
+ * Implementation: build the grades structure in-memory, compare against the
11
+ * file currently on disk (modules array as JSON, ignoring `generated:`
12
+ * timestamp churn), and emit a commit proposal only when content differs.
13
+ */
14
+ import type { GcCommitProposal, GcFinding } from "./types.js";
15
+ export interface QualityUpdateOptions {
16
+ repoRoot: string;
17
+ recentRunCount?: number;
18
+ }
19
+ export interface QualityUpdateResult {
20
+ findings: GcFinding[];
21
+ proposals: GcCommitProposal[];
22
+ }
23
+ export declare function runQualityGradesUpdate(opts: QualityUpdateOptions): QualityUpdateResult;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * GC pass 5 — quality grades update.
3
+ *
4
+ * Rebuilds `.cairn/ground/quality-grades.yaml` from terminal-run history at
5
+ * `.cairn/runs/terminal/*`. The grounding daemon also writes this file on
6
+ * watch events, so GC's job is to ensure a fresh write lands on the GC cron
7
+ * and that any drift between the file's content and the latest reality is
8
+ * captured as a safe-class commit.
9
+ *
10
+ * Implementation: build the grades structure in-memory, compare against the
11
+ * file currently on disk (modules array as JSON, ignoring `generated:`
12
+ * timestamp churn), and emit a commit proposal only when content differs.
13
+ */
14
+ import { existsSync, readFileSync } from "node:fs";
15
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
16
+ import { buildQualityGrades } from "../ground/quality-grades.js";
17
+ import { qualityGradesPath } from "../ground/paths.js";
18
+ const PASS_ID = "quality-grades";
19
+ export function runQualityGradesUpdate(opts) {
20
+ const findings = [];
21
+ const proposals = [];
22
+ const grades = buildQualityGrades({
23
+ repoRoot: opts.repoRoot,
24
+ ...(opts.recentRunCount !== undefined ? { recentRunCount: opts.recentRunCount } : {}),
25
+ });
26
+ const newContent = stringifyYaml(grades);
27
+ const filePath = qualityGradesPath(opts.repoRoot);
28
+ const relPath = ".cairn/ground/quality-grades.yaml";
29
+ const existing = existsSync(filePath) ? readFileSync(filePath, "utf8") : "";
30
+ const existingModules = existing.length > 0 ? safeParseModules(existing) : [];
31
+ const existingModulesJson = JSON.stringify(existingModules);
32
+ const newModulesJson = JSON.stringify(grades.modules);
33
+ if (existingModulesJson === newModulesJson) {
34
+ return { findings, proposals };
35
+ }
36
+ const finding = {
37
+ pass: PASS_ID,
38
+ kind: "quality_update",
39
+ path: relPath,
40
+ detail: `quality-grades.yaml modules changed (${grades.modules.length} module${grades.modules.length === 1 ? "" : "s"} graded)`,
41
+ severity: "info",
42
+ };
43
+ findings.push(finding);
44
+ proposals.push({
45
+ pass: PASS_ID,
46
+ class: "safe",
47
+ paths: [relPath],
48
+ patch: { [relPath]: newContent },
49
+ commit_message: `chore(gc): refresh quality-grades.yaml (${grades.modules.length} modules)\n\n` +
50
+ `GC quality-grades pass — recomputed from .cairn/runs/terminal/.\n` +
51
+ `Auto-applied as safe-class per PRIMER §12.2.\n`,
52
+ findings: [finding],
53
+ });
54
+ return { findings, proposals };
55
+ }
56
+ function safeParseModules(text) {
57
+ try {
58
+ const parsed = parseYaml(text);
59
+ if (typeof parsed === "object" && parsed !== null) {
60
+ const m = parsed.modules;
61
+ return Array.isArray(m) ? m : [];
62
+ }
63
+ }
64
+ catch {
65
+ // fall through
66
+ }
67
+ return [];
68
+ }
69
+ //# sourceMappingURL=quality-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-update.js","sourceRoot":"","sources":["../../src/gc/quality-update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * GC pass — scope-coverage.
3
+ *
4
+ * Surfaces drift between the source tree and `.cairn/ground/scope-index.yaml`:
5
+ * 1. Source files with no scope-index entry → `scope_uncovered`.
6
+ * 2. Index entries pointing at paths that no longer exist → `scope_drift_orphan`.
7
+ *
8
+ * If the scope-index file itself is missing, emits a single
9
+ * `scope_index_missing` finding telling the operator to rebuild it.
10
+ *
11
+ * Spec: docs/DOCS_SPEC.md §3.8.
12
+ */
13
+ import type { GcFinding } from "./types.js";
14
+ export interface ScopeCoverageOptions {
15
+ repoRoot: string;
16
+ }
17
+ export interface ScopeCoverageResult {
18
+ findings: GcFinding[];
19
+ }
20
+ export declare function runScopeCoverage(opts: ScopeCoverageOptions): ScopeCoverageResult;