@isaacriehm/cairn 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 (562) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/backprop/id.d.ts +14 -0
  5. package/dist/backprop/id.js +40 -0
  6. package/dist/backprop/id.js.map +1 -0
  7. package/dist/backprop/index.d.ts +23 -0
  8. package/dist/backprop/index.js +21 -0
  9. package/dist/backprop/index.js.map +1 -0
  10. package/dist/backprop/prompt.d.ts +16 -0
  11. package/dist/backprop/prompt.js +101 -0
  12. package/dist/backprop/prompt.js.map +1 -0
  13. package/dist/backprop/runner.d.ts +18 -0
  14. package/dist/backprop/runner.js +95 -0
  15. package/dist/backprop/runner.js.map +1 -0
  16. package/dist/backprop/schema.d.ts +61 -0
  17. package/dist/backprop/schema.js +55 -0
  18. package/dist/backprop/schema.js.map +1 -0
  19. package/dist/backprop/types.d.ts +101 -0
  20. package/dist/backprop/types.js +24 -0
  21. package/dist/backprop/types.js.map +1 -0
  22. package/dist/backprop/writer.d.ts +27 -0
  23. package/dist/backprop/writer.js +301 -0
  24. package/dist/backprop/writer.js.map +1 -0
  25. package/dist/claude/error.d.ts +33 -0
  26. package/dist/claude/error.js +58 -0
  27. package/dist/claude/error.js.map +1 -0
  28. package/dist/claude/index.d.ts +3 -0
  29. package/dist/claude/index.js +3 -0
  30. package/dist/claude/index.js.map +1 -0
  31. package/dist/claude/runner.d.ts +11 -0
  32. package/dist/claude/runner.js +132 -0
  33. package/dist/claude/runner.js.map +1 -0
  34. package/dist/claude/types.d.ts +52 -0
  35. package/dist/claude/types.js +14 -0
  36. package/dist/claude/types.js.map +1 -0
  37. package/dist/cli/attention.d.ts +11 -0
  38. package/dist/cli/attention.js +234 -0
  39. package/dist/cli/attention.js.map +1 -0
  40. package/dist/cli/daemon.d.ts +54 -0
  41. package/dist/cli/daemon.js +351 -0
  42. package/dist/cli/daemon.js.map +1 -0
  43. package/dist/cli/doctor.d.ts +8 -0
  44. package/dist/cli/doctor.js +116 -0
  45. package/dist/cli/doctor.js.map +1 -0
  46. package/dist/cli/gc.d.ts +15 -0
  47. package/dist/cli/gc.js +139 -0
  48. package/dist/cli/gc.js.map +1 -0
  49. package/dist/cli/hook.d.ts +18 -0
  50. package/dist/cli/hook.js +57 -0
  51. package/dist/cli/hook.js.map +1 -0
  52. package/dist/cli/index.d.ts +2 -0
  53. package/dist/cli/index.js +127 -0
  54. package/dist/cli/index.js.map +1 -0
  55. package/dist/cli/init.d.ts +1 -0
  56. package/dist/cli/init.js +77 -0
  57. package/dist/cli/init.js.map +1 -0
  58. package/dist/cli/install.d.ts +52 -0
  59. package/dist/cli/install.js +308 -0
  60. package/dist/cli/install.js.map +1 -0
  61. package/dist/cli/join.d.ts +1 -0
  62. package/dist/cli/join.js +84 -0
  63. package/dist/cli/join.js.map +1 -0
  64. package/dist/cli/mcp.d.ts +1 -0
  65. package/dist/cli/mcp.js +62 -0
  66. package/dist/cli/mcp.js.map +1 -0
  67. package/dist/cli/mirror.d.ts +1 -0
  68. package/dist/cli/mirror.js +97 -0
  69. package/dist/cli/mirror.js.map +1 -0
  70. package/dist/cli/run.d.ts +1 -0
  71. package/dist/cli/run.js +174 -0
  72. package/dist/cli/run.js.map +1 -0
  73. package/dist/cli/scope.d.ts +8 -0
  74. package/dist/cli/scope.js +65 -0
  75. package/dist/cli/scope.js.map +1 -0
  76. package/dist/cli/task.d.ts +18 -0
  77. package/dist/cli/task.js +137 -0
  78. package/dist/cli/task.js.map +1 -0
  79. package/dist/cli/watch.d.ts +1 -0
  80. package/dist/cli/watch.js +73 -0
  81. package/dist/cli/watch.js.map +1 -0
  82. package/dist/decision-capture/capture.d.ts +57 -0
  83. package/dist/decision-capture/capture.js +186 -0
  84. package/dist/decision-capture/capture.js.map +1 -0
  85. package/dist/decision-capture/extractor.d.ts +20 -0
  86. package/dist/decision-capture/extractor.js +103 -0
  87. package/dist/decision-capture/extractor.js.map +1 -0
  88. package/dist/decision-capture/id.d.ts +14 -0
  89. package/dist/decision-capture/id.js +44 -0
  90. package/dist/decision-capture/id.js.map +1 -0
  91. package/dist/decision-capture/index.d.ts +25 -0
  92. package/dist/decision-capture/index.js +21 -0
  93. package/dist/decision-capture/index.js.map +1 -0
  94. package/dist/decision-capture/prompt.d.ts +15 -0
  95. package/dist/decision-capture/prompt.js +68 -0
  96. package/dist/decision-capture/prompt.js.map +1 -0
  97. package/dist/decision-capture/refinement-prompt.d.ts +25 -0
  98. package/dist/decision-capture/refinement-prompt.js +146 -0
  99. package/dist/decision-capture/refinement-prompt.js.map +1 -0
  100. package/dist/decision-capture/refinement-schema.d.ts +52 -0
  101. package/dist/decision-capture/refinement-schema.js +61 -0
  102. package/dist/decision-capture/refinement-schema.js.map +1 -0
  103. package/dist/decision-capture/refinement.d.ts +60 -0
  104. package/dist/decision-capture/refinement.js +439 -0
  105. package/dist/decision-capture/refinement.js.map +1 -0
  106. package/dist/decision-capture/schema.d.ts +70 -0
  107. package/dist/decision-capture/schema.js +71 -0
  108. package/dist/decision-capture/schema.js.map +1 -0
  109. package/dist/decision-capture/types.d.ts +201 -0
  110. package/dist/decision-capture/types.js +20 -0
  111. package/dist/decision-capture/types.js.map +1 -0
  112. package/dist/decision-capture/writer.d.ts +90 -0
  113. package/dist/decision-capture/writer.js +267 -0
  114. package/dist/decision-capture/writer.js.map +1 -0
  115. package/dist/frontend/discord/acl.d.ts +6 -0
  116. package/dist/frontend/discord/acl.js +19 -0
  117. package/dist/frontend/discord/acl.js.map +1 -0
  118. package/dist/frontend/discord/channels.d.ts +29 -0
  119. package/dist/frontend/discord/channels.js +58 -0
  120. package/dist/frontend/discord/channels.js.map +1 -0
  121. package/dist/frontend/discord/classifier.d.ts +16 -0
  122. package/dist/frontend/discord/classifier.js +29 -0
  123. package/dist/frontend/discord/classifier.js.map +1 -0
  124. package/dist/frontend/discord/index.d.ts +118 -0
  125. package/dist/frontend/discord/index.js +1104 -0
  126. package/dist/frontend/discord/index.js.map +1 -0
  127. package/dist/frontend/discord/slash.d.ts +18 -0
  128. package/dist/frontend/discord/slash.js +90 -0
  129. package/dist/frontend/discord/slash.js.map +1 -0
  130. package/dist/frontend/inbox.d.ts +17 -0
  131. package/dist/frontend/inbox.js +30 -0
  132. package/dist/frontend/inbox.js.map +1 -0
  133. package/dist/frontend/index.d.ts +8 -0
  134. package/dist/frontend/index.js +6 -0
  135. package/dist/frontend/index.js.map +1 -0
  136. package/dist/frontend/stub/index.d.ts +58 -0
  137. package/dist/frontend/stub/index.js +144 -0
  138. package/dist/frontend/stub/index.js.map +1 -0
  139. package/dist/frontend/types.d.ts +247 -0
  140. package/dist/frontend/types.js +15 -0
  141. package/dist/frontend/types.js.map +1 -0
  142. package/dist/gc/apply.d.ts +26 -0
  143. package/dist/gc/apply.js +48 -0
  144. package/dist/gc/apply.js.map +1 -0
  145. package/dist/gc/canary.d.ts +42 -0
  146. package/dist/gc/canary.js +134 -0
  147. package/dist/gc/canary.js.map +1 -0
  148. package/dist/gc/classify.d.ts +25 -0
  149. package/dist/gc/classify.js +89 -0
  150. package/dist/gc/classify.js.map +1 -0
  151. package/dist/gc/doc-gardening.d.ts +29 -0
  152. package/dist/gc/doc-gardening.js +146 -0
  153. package/dist/gc/doc-gardening.js.map +1 -0
  154. package/dist/gc/frontmatter.d.ts +35 -0
  155. package/dist/gc/frontmatter.js +111 -0
  156. package/dist/gc/frontmatter.js.map +1 -0
  157. package/dist/gc/generator-drift.d.ts +28 -0
  158. package/dist/gc/generator-drift.js +53 -0
  159. package/dist/gc/generator-drift.js.map +1 -0
  160. package/dist/gc/index.d.ts +35 -0
  161. package/dist/gc/index.js +26 -0
  162. package/dist/gc/index.js.map +1 -0
  163. package/dist/gc/quality-update.d.ts +23 -0
  164. package/dist/gc/quality-update.js +69 -0
  165. package/dist/gc/quality-update.js.map +1 -0
  166. package/dist/gc/stub-hits.d.ts +31 -0
  167. package/dist/gc/stub-hits.js +125 -0
  168. package/dist/gc/stub-hits.js.map +1 -0
  169. package/dist/gc/sweep.d.ts +56 -0
  170. package/dist/gc/sweep.js +178 -0
  171. package/dist/gc/sweep.js.map +1 -0
  172. package/dist/gc/types.d.ts +129 -0
  173. package/dist/gc/types.js +26 -0
  174. package/dist/gc/types.js.map +1 -0
  175. package/dist/ground/drift.d.ts +8 -0
  176. package/dist/ground/drift.js +23 -0
  177. package/dist/ground/drift.js.map +1 -0
  178. package/dist/ground/frontmatter.d.ts +20 -0
  179. package/dist/ground/frontmatter.js +49 -0
  180. package/dist/ground/frontmatter.js.map +1 -0
  181. package/dist/ground/glob.d.ts +10 -0
  182. package/dist/ground/glob.js +46 -0
  183. package/dist/ground/glob.js.map +1 -0
  184. package/dist/ground/index.d.ts +14 -0
  185. package/dist/ground/index.js +10 -0
  186. package/dist/ground/index.js.map +1 -0
  187. package/dist/ground/ledgers.d.ts +18 -0
  188. package/dist/ground/ledgers.js +103 -0
  189. package/dist/ground/ledgers.js.map +1 -0
  190. package/dist/ground/manifest.d.ts +10 -0
  191. package/dist/ground/manifest.js +88 -0
  192. package/dist/ground/manifest.js.map +1 -0
  193. package/dist/ground/paths.d.ts +20 -0
  194. package/dist/ground/paths.js +61 -0
  195. package/dist/ground/paths.js.map +1 -0
  196. package/dist/ground/quality-grades.d.ts +11 -0
  197. package/dist/ground/quality-grades.js +98 -0
  198. package/dist/ground/quality-grades.js.map +1 -0
  199. package/dist/ground/schemas.d.ts +306 -0
  200. package/dist/ground/schemas.js +188 -0
  201. package/dist/ground/schemas.js.map +1 -0
  202. package/dist/ground/walk.d.ts +7 -0
  203. package/dist/ground/walk.js +53 -0
  204. package/dist/ground/walk.js.map +1 -0
  205. package/dist/index.d.ts +8 -0
  206. package/dist/index.js +9 -0
  207. package/dist/index.js.map +1 -0
  208. package/dist/init/detect.d.ts +25 -0
  209. package/dist/init/detect.js +336 -0
  210. package/dist/init/detect.js.map +1 -0
  211. package/dist/init/index.d.ts +14 -0
  212. package/dist/init/index.js +9 -0
  213. package/dist/init/index.js.map +1 -0
  214. package/dist/init/init.d.ts +68 -0
  215. package/dist/init/init.js +673 -0
  216. package/dist/init/init.js.map +1 -0
  217. package/dist/init/mapper.d.ts +160 -0
  218. package/dist/init/mapper.js +248 -0
  219. package/dist/init/mapper.js.map +1 -0
  220. package/dist/init/prompts.d.ts +70 -0
  221. package/dist/init/prompts.js +80 -0
  222. package/dist/init/prompts.js.map +1 -0
  223. package/dist/init/secrets.d.ts +18 -0
  224. package/dist/init/secrets.js +76 -0
  225. package/dist/init/secrets.js.map +1 -0
  226. package/dist/init/seed.d.ts +21 -0
  227. package/dist/init/seed.js +75 -0
  228. package/dist/init/seed.js.map +1 -0
  229. package/dist/init/setup-runners.d.ts +17 -0
  230. package/dist/init/setup-runners.js +70 -0
  231. package/dist/init/setup-runners.js.map +1 -0
  232. package/dist/init/types.d.ts +59 -0
  233. package/dist/init/types.js +10 -0
  234. package/dist/init/types.js.map +1 -0
  235. package/dist/init/walker.d.ts +53 -0
  236. package/dist/init/walker.js +460 -0
  237. package/dist/init/walker.js.map +1 -0
  238. package/dist/init/workflow-block.d.ts +34 -0
  239. package/dist/init/workflow-block.js +110 -0
  240. package/dist/init/workflow-block.js.map +1 -0
  241. package/dist/logger.d.ts +3 -0
  242. package/dist/logger.js +23 -0
  243. package/dist/logger.js.map +1 -0
  244. package/dist/mcp/context.d.ts +16 -0
  245. package/dist/mcp/context.js +8 -0
  246. package/dist/mcp/context.js.map +1 -0
  247. package/dist/mcp/errors.d.ts +17 -0
  248. package/dist/mcp/errors.js +23 -0
  249. package/dist/mcp/errors.js.map +1 -0
  250. package/dist/mcp/index.d.ts +10 -0
  251. package/dist/mcp/index.js +7 -0
  252. package/dist/mcp/index.js.map +1 -0
  253. package/dist/mcp/path-allowlist.d.ts +25 -0
  254. package/dist/mcp/path-allowlist.js +66 -0
  255. package/dist/mcp/path-allowlist.js.map +1 -0
  256. package/dist/mcp/result.d.ts +8 -0
  257. package/dist/mcp/result.js +18 -0
  258. package/dist/mcp/result.js.map +1 -0
  259. package/dist/mcp/schemas.d.ts +153 -0
  260. package/dist/mcp/schemas.js +135 -0
  261. package/dist/mcp/schemas.js.map +1 -0
  262. package/dist/mcp/server.d.ts +11 -0
  263. package/dist/mcp/server.js +58 -0
  264. package/dist/mcp/server.js.map +1 -0
  265. package/dist/mcp/telemetry.d.ts +15 -0
  266. package/dist/mcp/telemetry.js +13 -0
  267. package/dist/mcp/telemetry.js.map +1 -0
  268. package/dist/mcp/tools/append.d.ts +8 -0
  269. package/dist/mcp/tools/append.js +33 -0
  270. package/dist/mcp/tools/append.js.map +1 -0
  271. package/dist/mcp/tools/archive.d.ts +8 -0
  272. package/dist/mcp/tools/archive.js +49 -0
  273. package/dist/mcp/tools/archive.js.map +1 -0
  274. package/dist/mcp/tools/ask-operator.d.ts +34 -0
  275. package/dist/mcp/tools/ask-operator.js +93 -0
  276. package/dist/mcp/tools/ask-operator.js.map +1 -0
  277. package/dist/mcp/tools/canonical-for-topic.d.ts +6 -0
  278. package/dist/mcp/tools/canonical-for-topic.js +40 -0
  279. package/dist/mcp/tools/canonical-for-topic.js.map +1 -0
  280. package/dist/mcp/tools/decision-get.d.ts +6 -0
  281. package/dist/mcp/tools/decision-get.js +49 -0
  282. package/dist/mcp/tools/decision-get.js.map +1 -0
  283. package/dist/mcp/tools/decisions-for-symbol.d.ts +7 -0
  284. package/dist/mcp/tools/decisions-for-symbol.js +42 -0
  285. package/dist/mcp/tools/decisions-for-symbol.js.map +1 -0
  286. package/dist/mcp/tools/decisions-in-scope.d.ts +7 -0
  287. package/dist/mcp/tools/decisions-in-scope.js +47 -0
  288. package/dist/mcp/tools/decisions-in-scope.js.map +1 -0
  289. package/dist/mcp/tools/drop-task.d.ts +12 -0
  290. package/dist/mcp/tools/drop-task.js +47 -0
  291. package/dist/mcp/tools/drop-task.js.map +1 -0
  292. package/dist/mcp/tools/get-full.d.ts +7 -0
  293. package/dist/mcp/tools/get-full.js +46 -0
  294. package/dist/mcp/tools/get-full.js.map +1 -0
  295. package/dist/mcp/tools/ground-get.d.ts +7 -0
  296. package/dist/mcp/tools/ground-get.js +80 -0
  297. package/dist/mcp/tools/ground-get.js.map +1 -0
  298. package/dist/mcp/tools/index.d.ts +3 -0
  299. package/dist/mcp/tools/index.js +44 -0
  300. package/dist/mcp/tools/index.js.map +1 -0
  301. package/dist/mcp/tools/invariant-get.d.ts +6 -0
  302. package/dist/mcp/tools/invariant-get.js +49 -0
  303. package/dist/mcp/tools/invariant-get.js.map +1 -0
  304. package/dist/mcp/tools/invariants-in-scope.d.ts +7 -0
  305. package/dist/mcp/tools/invariants-in-scope.js +65 -0
  306. package/dist/mcp/tools/invariants-in-scope.js.map +1 -0
  307. package/dist/mcp/tools/query-history.d.ts +9 -0
  308. package/dist/mcp/tools/query-history.js +33 -0
  309. package/dist/mcp/tools/query-history.js.map +1 -0
  310. package/dist/mcp/tools/record-decision.d.ts +14 -0
  311. package/dist/mcp/tools/record-decision.js +101 -0
  312. package/dist/mcp/tools/record-decision.js.map +1 -0
  313. package/dist/mcp/tools/record-run-event.d.ts +10 -0
  314. package/dist/mcp/tools/record-run-event.js +28 -0
  315. package/dist/mcp/tools/record-run-event.js.map +1 -0
  316. package/dist/mcp/tools/search.d.ts +9 -0
  317. package/dist/mcp/tools/search.js +165 -0
  318. package/dist/mcp/tools/search.js.map +1 -0
  319. package/dist/mcp/tools/supersedes-chain.d.ts +6 -0
  320. package/dist/mcp/tools/supersedes-chain.js +66 -0
  321. package/dist/mcp/tools/supersedes-chain.js.map +1 -0
  322. package/dist/mcp/tools/timeline.d.ts +9 -0
  323. package/dist/mcp/tools/timeline.js +65 -0
  324. package/dist/mcp/tools/timeline.js.map +1 -0
  325. package/dist/mcp/tools/types.d.ts +9 -0
  326. package/dist/mcp/tools/types.js +2 -0
  327. package/dist/mcp/tools/types.js.map +1 -0
  328. package/dist/mirror/clone.d.ts +6 -0
  329. package/dist/mirror/clone.js +48 -0
  330. package/dist/mirror/clone.js.map +1 -0
  331. package/dist/mirror/dirty-overlap.d.ts +13 -0
  332. package/dist/mirror/dirty-overlap.js +77 -0
  333. package/dist/mirror/dirty-overlap.js.map +1 -0
  334. package/dist/mirror/index.d.ts +7 -0
  335. package/dist/mirror/index.js +7 -0
  336. package/dist/mirror/index.js.map +1 -0
  337. package/dist/mirror/paths.d.ts +18 -0
  338. package/dist/mirror/paths.js +45 -0
  339. package/dist/mirror/paths.js.map +1 -0
  340. package/dist/mirror/push.d.ts +9 -0
  341. package/dist/mirror/push.js +27 -0
  342. package/dist/mirror/push.js.map +1 -0
  343. package/dist/mirror/state.d.ts +4 -0
  344. package/dist/mirror/state.js +36 -0
  345. package/dist/mirror/state.js.map +1 -0
  346. package/dist/mirror/sync.d.ts +9 -0
  347. package/dist/mirror/sync.js +33 -0
  348. package/dist/mirror/sync.js.map +1 -0
  349. package/dist/mirror/types.d.ts +77 -0
  350. package/dist/mirror/types.js +2 -0
  351. package/dist/mirror/types.js.map +1 -0
  352. package/dist/orchestrator/activity-summarizer.d.ts +33 -0
  353. package/dist/orchestrator/activity-summarizer.js +120 -0
  354. package/dist/orchestrator/activity-summarizer.js.map +1 -0
  355. package/dist/orchestrator/inbox.d.ts +78 -0
  356. package/dist/orchestrator/inbox.js +115 -0
  357. package/dist/orchestrator/inbox.js.map +1 -0
  358. package/dist/orchestrator/index.d.ts +9 -0
  359. package/dist/orchestrator/index.js +7 -0
  360. package/dist/orchestrator/index.js.map +1 -0
  361. package/dist/orchestrator/orchestrator.d.ts +154 -0
  362. package/dist/orchestrator/orchestrator.js +2437 -0
  363. package/dist/orchestrator/orchestrator.js.map +1 -0
  364. package/dist/orchestrator/prompt.d.ts +19 -0
  365. package/dist/orchestrator/prompt.js +50 -0
  366. package/dist/orchestrator/prompt.js.map +1 -0
  367. package/dist/orchestrator/queue.d.ts +21 -0
  368. package/dist/orchestrator/queue.js +80 -0
  369. package/dist/orchestrator/queue.js.map +1 -0
  370. package/dist/orchestrator/run-log.d.ts +53 -0
  371. package/dist/orchestrator/run-log.js +92 -0
  372. package/dist/orchestrator/run-log.js.map +1 -0
  373. package/dist/orchestrator/runner.d.ts +56 -0
  374. package/dist/orchestrator/runner.js +172 -0
  375. package/dist/orchestrator/runner.js.map +1 -0
  376. package/dist/orchestrator/tool-digest.d.ts +35 -0
  377. package/dist/orchestrator/tool-digest.js +116 -0
  378. package/dist/orchestrator/tool-digest.js.map +1 -0
  379. package/dist/orchestrator/types.d.ts +263 -0
  380. package/dist/orchestrator/types.js +2 -0
  381. package/dist/orchestrator/types.js.map +1 -0
  382. package/dist/orchestrator/workspace.d.ts +21 -0
  383. package/dist/orchestrator/workspace.js +31 -0
  384. package/dist/orchestrator/workspace.js.map +1 -0
  385. package/dist/profiles/index.d.ts +3 -0
  386. package/dist/profiles/index.js +3 -0
  387. package/dist/profiles/index.js.map +1 -0
  388. package/dist/profiles/registry.d.ts +5 -0
  389. package/dist/profiles/registry.js +31 -0
  390. package/dist/profiles/registry.js.map +1 -0
  391. package/dist/profiles/types.d.ts +48 -0
  392. package/dist/profiles/types.js +11 -0
  393. package/dist/profiles/types.js.map +1 -0
  394. package/dist/profiles/unknown.d.ts +9 -0
  395. package/dist/profiles/unknown.js +17 -0
  396. package/dist/profiles/unknown.js.map +1 -0
  397. package/dist/reviewer/index.d.ts +6 -0
  398. package/dist/reviewer/index.js +5 -0
  399. package/dist/reviewer/index.js.map +1 -0
  400. package/dist/reviewer/prompt.d.ts +11 -0
  401. package/dist/reviewer/prompt.js +132 -0
  402. package/dist/reviewer/prompt.js.map +1 -0
  403. package/dist/reviewer/remediation.d.ts +15 -0
  404. package/dist/reviewer/remediation.js +61 -0
  405. package/dist/reviewer/remediation.js.map +1 -0
  406. package/dist/reviewer/reviewer.d.ts +9 -0
  407. package/dist/reviewer/reviewer.js +89 -0
  408. package/dist/reviewer/reviewer.js.map +1 -0
  409. package/dist/reviewer/schema.d.ts +45 -0
  410. package/dist/reviewer/schema.js +43 -0
  411. package/dist/reviewer/schema.js.map +1 -0
  412. package/dist/reviewer/types.d.ts +74 -0
  413. package/dist/reviewer/types.js +14 -0
  414. package/dist/reviewer/types.js.map +1 -0
  415. package/dist/sensors/attestation.d.ts +44 -0
  416. package/dist/sensors/attestation.js +262 -0
  417. package/dist/sensors/attestation.js.map +1 -0
  418. package/dist/sensors/catalog.d.ts +41 -0
  419. package/dist/sensors/catalog.js +123 -0
  420. package/dist/sensors/catalog.js.map +1 -0
  421. package/dist/sensors/decisions.d.ts +30 -0
  422. package/dist/sensors/decisions.js +393 -0
  423. package/dist/sensors/decisions.js.map +1 -0
  424. package/dist/sensors/diff.d.ts +27 -0
  425. package/dist/sensors/diff.js +148 -0
  426. package/dist/sensors/diff.js.map +1 -0
  427. package/dist/sensors/index.d.ts +13 -0
  428. package/dist/sensors/index.js +9 -0
  429. package/dist/sensors/index.js.map +1 -0
  430. package/dist/sensors/remediation.d.ts +20 -0
  431. package/dist/sensors/remediation.js +65 -0
  432. package/dist/sensors/remediation.js.map +1 -0
  433. package/dist/sensors/runner.d.ts +44 -0
  434. package/dist/sensors/runner.js +95 -0
  435. package/dist/sensors/runner.js.map +1 -0
  436. package/dist/sensors/structural.d.ts +30 -0
  437. package/dist/sensors/structural.js +204 -0
  438. package/dist/sensors/structural.js.map +1 -0
  439. package/dist/sensors/stub-catalog.d.ts +39 -0
  440. package/dist/sensors/stub-catalog.js +115 -0
  441. package/dist/sensors/stub-catalog.js.map +1 -0
  442. package/dist/sensors/types.d.ts +135 -0
  443. package/dist/sensors/types.js +14 -0
  444. package/dist/sensors/types.js.map +1 -0
  445. package/dist/tier0/classify.d.ts +5 -0
  446. package/dist/tier0/classify.js +91 -0
  447. package/dist/tier0/classify.js.map +1 -0
  448. package/dist/tier0/index.d.ts +3 -0
  449. package/dist/tier0/index.js +3 -0
  450. package/dist/tier0/index.js.map +1 -0
  451. package/dist/tier0/ollama.d.ts +22 -0
  452. package/dist/tier0/ollama.js +63 -0
  453. package/dist/tier0/ollama.js.map +1 -0
  454. package/dist/tier0/types.d.ts +24 -0
  455. package/dist/tier0/types.js +7 -0
  456. package/dist/tier0/types.js.map +1 -0
  457. package/dist/tightener/index.d.ts +4 -0
  458. package/dist/tightener/index.js +4 -0
  459. package/dist/tightener/index.js.map +1 -0
  460. package/dist/tightener/prompt.d.ts +3 -0
  461. package/dist/tightener/prompt.js +67 -0
  462. package/dist/tightener/prompt.js.map +1 -0
  463. package/dist/tightener/schema.d.ts +68 -0
  464. package/dist/tightener/schema.js +44 -0
  465. package/dist/tightener/schema.js.map +1 -0
  466. package/dist/tightener/tighten.d.ts +2 -0
  467. package/dist/tightener/tighten.js +66 -0
  468. package/dist/tightener/tighten.js.map +1 -0
  469. package/dist/tightener/types.d.ts +74 -0
  470. package/dist/tightener/types.js +6 -0
  471. package/dist/tightener/types.js.map +1 -0
  472. package/dist/uat/bundle.d.ts +68 -0
  473. package/dist/uat/bundle.js +168 -0
  474. package/dist/uat/bundle.js.map +1 -0
  475. package/dist/uat/index.d.ts +15 -0
  476. package/dist/uat/index.js +10 -0
  477. package/dist/uat/index.js.map +1 -0
  478. package/dist/uat/persistent.d.ts +64 -0
  479. package/dist/uat/persistent.js +206 -0
  480. package/dist/uat/persistent.js.map +1 -0
  481. package/dist/uat/probes/cli.d.ts +11 -0
  482. package/dist/uat/probes/cli.js +107 -0
  483. package/dist/uat/probes/cli.js.map +1 -0
  484. package/dist/uat/probes/http.d.ts +12 -0
  485. package/dist/uat/probes/http.js +139 -0
  486. package/dist/uat/probes/http.js.map +1 -0
  487. package/dist/uat/probes/index.d.ts +21 -0
  488. package/dist/uat/probes/index.js +30 -0
  489. package/dist/uat/probes/index.js.map +1 -0
  490. package/dist/uat/probes/integration.d.ts +18 -0
  491. package/dist/uat/probes/integration.js +188 -0
  492. package/dist/uat/probes/integration.js.map +1 -0
  493. package/dist/uat/probes/sql/config.d.ts +14 -0
  494. package/dist/uat/probes/sql/config.js +57 -0
  495. package/dist/uat/probes/sql/config.js.map +1 -0
  496. package/dist/uat/probes/sql/index.d.ts +29 -0
  497. package/dist/uat/probes/sql/index.js +43 -0
  498. package/dist/uat/probes/sql/index.js.map +1 -0
  499. package/dist/uat/probes/sql/mysql.d.ts +12 -0
  500. package/dist/uat/probes/sql/mysql.js +96 -0
  501. package/dist/uat/probes/sql/mysql.js.map +1 -0
  502. package/dist/uat/probes/sql/pg.d.ts +20 -0
  503. package/dist/uat/probes/sql/pg.js +102 -0
  504. package/dist/uat/probes/sql/pg.js.map +1 -0
  505. package/dist/uat/probes/sql/sqlite.d.ts +9 -0
  506. package/dist/uat/probes/sql/sqlite.js +58 -0
  507. package/dist/uat/probes/sql/sqlite.js.map +1 -0
  508. package/dist/uat/probes/sql/types.d.ts +46 -0
  509. package/dist/uat/probes/sql/types.js +10 -0
  510. package/dist/uat/probes/sql/types.js.map +1 -0
  511. package/dist/uat/probes/sql.d.ts +9 -0
  512. package/dist/uat/probes/sql.js +119 -0
  513. package/dist/uat/probes/sql.js.map +1 -0
  514. package/dist/uat/probes/ui.d.ts +19 -0
  515. package/dist/uat/probes/ui.js +244 -0
  516. package/dist/uat/probes/ui.js.map +1 -0
  517. package/dist/uat/prompt.d.ts +10 -0
  518. package/dist/uat/prompt.js +85 -0
  519. package/dist/uat/prompt.js.map +1 -0
  520. package/dist/uat/question.d.ts +50 -0
  521. package/dist/uat/question.js +139 -0
  522. package/dist/uat/question.js.map +1 -0
  523. package/dist/uat/rejection.d.ts +58 -0
  524. package/dist/uat/rejection.js +163 -0
  525. package/dist/uat/rejection.js.map +1 -0
  526. package/dist/uat/runner.d.ts +6 -0
  527. package/dist/uat/runner.js +96 -0
  528. package/dist/uat/runner.js.map +1 -0
  529. package/dist/uat/schema.d.ts +322 -0
  530. package/dist/uat/schema.js +189 -0
  531. package/dist/uat/schema.js.map +1 -0
  532. package/dist/uat/types.d.ts +268 -0
  533. package/dist/uat/types.js +18 -0
  534. package/dist/uat/types.js.map +1 -0
  535. package/dist/uat/uat.d.ts +89 -0
  536. package/dist/uat/uat.js +256 -0
  537. package/dist/uat/uat.js.map +1 -0
  538. package/dist/voice/index.d.ts +4 -0
  539. package/dist/voice/index.js +4 -0
  540. package/dist/voice/index.js.map +1 -0
  541. package/dist/voice/model.d.ts +23 -0
  542. package/dist/voice/model.js +46 -0
  543. package/dist/voice/model.js.map +1 -0
  544. package/dist/voice/pipe.d.ts +9 -0
  545. package/dist/voice/pipe.js +47 -0
  546. package/dist/voice/pipe.js.map +1 -0
  547. package/dist/voice/transcribe.d.ts +3 -0
  548. package/dist/voice/transcribe.js +43 -0
  549. package/dist/voice/transcribe.js.map +1 -0
  550. package/dist/voice/types.d.ts +26 -0
  551. package/dist/voice/types.js +9 -0
  552. package/dist/voice/types.js.map +1 -0
  553. package/dist/watch/daemon.d.ts +21 -0
  554. package/dist/watch/daemon.js +143 -0
  555. package/dist/watch/daemon.js.map +1 -0
  556. package/dist/watch/index.d.ts +4 -0
  557. package/dist/watch/index.js +3 -0
  558. package/dist/watch/index.js.map +1 -0
  559. package/dist/watch/regenerate.d.ts +25 -0
  560. package/dist/watch/regenerate.js +51 -0
  561. package/dist/watch/regenerate.js.map +1 -0
  562. package/package.json +75 -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
+ ".harness/config/workflow.md",
26
+ ".harness/config/sensors.yaml",
27
+ ".harness/config/stub-patterns.yaml",
28
+ ".harness/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,111 @@
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 { stringify as stringifyYaml } from "yaml";
20
+ import { evaluateFreshness, parseFrontmatter } from "../ground/frontmatter.js";
21
+ import { walkCanonical } from "../ground/walk.js";
22
+ const PASS_ID = "frontmatter-freshness";
23
+ export function runFrontmatterFreshness(opts) {
24
+ const warnDays = opts.warnDays ?? 30;
25
+ const blockDays = opts.blockDays ?? 60;
26
+ const now = opts.now ?? new Date();
27
+ const findings = [];
28
+ const refreshes = [];
29
+ const files = walkCanonical(opts.repoRoot);
30
+ for (const rel of files) {
31
+ if (!rel.endsWith(".md"))
32
+ continue;
33
+ const abs = resolve(opts.repoRoot, rel);
34
+ const source = readFileSync(abs, "utf8");
35
+ const parsed = parseFrontmatter(source);
36
+ if (!parsed.frontmatter)
37
+ continue;
38
+ const verdict = evaluateFreshness(parsed.frontmatter, warnDays, blockDays, now);
39
+ if (verdict.status === "fresh" || verdict.status === "unknown")
40
+ continue;
41
+ findings.push({
42
+ pass: PASS_ID,
43
+ kind: "frontmatter_stale",
44
+ path: rel,
45
+ detail: verdict.status === "block"
46
+ ? `verified-at is ${verdict.ageDays}d old (>=${blockDays}d block threshold) — re-verify before relying`
47
+ : `verified-at is ${verdict.ageDays}d old (>=${warnDays}d warn threshold)`,
48
+ severity: verdict.status === "block" ? "block" : "warn",
49
+ ...(verdict.ageDays !== null ? { age_days: verdict.ageDays } : {}),
50
+ });
51
+ if (opts.forceRefresh) {
52
+ const refreshed = bumpVerifiedAt(source, parsed.raw, now);
53
+ refreshes.push({ path: rel, content: refreshed });
54
+ }
55
+ }
56
+ const proposals = [];
57
+ if (refreshes.length > 0) {
58
+ const patch = {};
59
+ for (const r of refreshes)
60
+ patch[r.path] = r.content;
61
+ const paths = refreshes.map((r) => r.path).sort();
62
+ proposals.push({
63
+ pass: PASS_ID,
64
+ class: "safe",
65
+ paths,
66
+ patch,
67
+ commit_message: composeCommitMessage(paths.length, now),
68
+ findings: findings.filter((f) => paths.includes(f.path)),
69
+ });
70
+ }
71
+ return { findings, proposals };
72
+ }
73
+ /**
74
+ * Rewrite the frontmatter block with verified-at bumped to `now`. Preserves
75
+ * key order by replacing only the `verified-at:` line (or inserting it
76
+ * directly after `generated:` when missing).
77
+ */
78
+ function bumpVerifiedAt(source, rawBlock, now) {
79
+ const iso = now.toISOString();
80
+ // Frontmatter is fenced by `---` lines at the top of the file; replace the
81
+ // first `verified-at:` line in the fence region. If none, insert it after
82
+ // `generated:` if present, else at the end of the fence block.
83
+ const fenceEndIdx = source.indexOf("\n---", 3);
84
+ if (fenceEndIdx === -1)
85
+ return source;
86
+ const fenceText = source.slice(0, fenceEndIdx);
87
+ const restText = source.slice(fenceEndIdx);
88
+ const verifiedAtRe = /^verified-at:.*$/m;
89
+ if (verifiedAtRe.test(fenceText)) {
90
+ return fenceText.replace(verifiedAtRe, `verified-at: ${iso}`) + restText;
91
+ }
92
+ // Insert after generated: line if present.
93
+ const generatedRe = /^(generated:.*)$/m;
94
+ if (generatedRe.test(fenceText)) {
95
+ return fenceText.replace(generatedRe, `$1\nverified-at: ${iso}`) + restText;
96
+ }
97
+ // Fallback: append before fence close.
98
+ // rawBlock parsing is unused beyond detection; keep stringifyYaml import for
99
+ // future "rewrite the whole block" mode.
100
+ void stringifyYaml;
101
+ void rawBlock;
102
+ return fenceText + `\nverified-at: ${iso}` + restText;
103
+ }
104
+ function composeCommitMessage(count, now) {
105
+ const ymd = now.toISOString().slice(0, 10);
106
+ const subject = `chore(gc): refresh frontmatter verified-at on ${count} doc${count === 1 ? "" : "s"} (${ymd})`;
107
+ const body = "GC frontmatter-freshness pass — content unchanged; bumping verified-at to today.\n" +
108
+ "Auto-applied as safe-class per L16 (PRIMER §12.2).\n";
109
+ return `${subject}\n\n${body}`;
110
+ }
111
+ //# 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 L16 (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,sDAAsD;YACxD,QAAQ,EAAE,CAAC,OAAO,CAAC;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,35 @@
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 (`harness gc run`) and the smoke test
14
+ * (`harness/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 { classifyAutoMerge } from "./classify.js";
23
+ export type { ClassifyArgs } from "./classify.js";
24
+ export { runDocGardening } from "./doc-gardening.js";
25
+ export type { DocGardeningOptions, DocGardeningResult, } from "./doc-gardening.js";
26
+ export { runFrontmatterFreshness, } from "./frontmatter.js";
27
+ export type { FrontmatterFreshnessOptions, FrontmatterFreshnessResult, } from "./frontmatter.js";
28
+ export { runGeneratorDrift } from "./generator-drift.js";
29
+ export type { GeneratorDriftOptions, GeneratorDriftResult, } from "./generator-drift.js";
30
+ export { runQualityGradesUpdate } from "./quality-update.js";
31
+ export type { QualityUpdateOptions, QualityUpdateResult, } from "./quality-update.js";
32
+ export { runStubCatalogHits } from "./stub-hits.js";
33
+ export type { StubCatalogHitsOptions, StubCatalogHitsResult, } from "./stub-hits.js";
34
+ export { runGcBatch, runGcSweep } from "./sweep.js";
35
+ export type { RunGcBatchOptions, RunGcSweepOptions, } from "./sweep.js";
@@ -0,0 +1,26 @@
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 (`harness gc run`) and the smoke test
14
+ * (`harness/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 { classifyAutoMerge } from "./classify.js";
20
+ export { runDocGardening } from "./doc-gardening.js";
21
+ export { runFrontmatterFreshness, } from "./frontmatter.js";
22
+ export { runGeneratorDrift } from "./generator-drift.js";
23
+ export { runQualityGradesUpdate } from "./quality-update.js";
24
+ export { runStubCatalogHits } from "./stub-hits.js";
25
+ export { runGcBatch, runGcSweep } from "./sweep.js";
26
+ //# 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,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,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,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAKpD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * GC pass 5 — quality grades update.
3
+ *
4
+ * Rebuilds `.harness/ground/quality-grades.yaml` from terminal-run history at
5
+ * `.harness/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 `.harness/ground/quality-grades.yaml` from terminal-run history at
5
+ * `.harness/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 = ".harness/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 .harness/runs/terminal/.\n` +
51
+ `Auto-applied as safe-class per L16 (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,31 @@
1
+ /**
2
+ * GC pass 3 — stub-catalog hits (full-tree scan).
3
+ *
4
+ * Layer A in `harness/src/sensors/stub-catalog.ts` only flags genuinely-NEW
5
+ * stubs (added lines per diff). That keeps per-task feedback tight and avoids
6
+ * paying for pre-existing debt over and over.
7
+ *
8
+ * GC closes the loop on accumulated debt: walks the canonical zone and runs
9
+ * the same regex catalog against every file's CURRENT content. Hits become
10
+ * findings the operator can triage. Phase 12 v1 surfaces only — opening a
11
+ * targeted refactor commit (per spec) requires generating a diff that actually
12
+ * fixes the stub, which needs an agent. That belongs in Phase 14+.
13
+ */
14
+ import type { SensorLanguage, StubCatalog } from "../sensors/types.js";
15
+ import type { GcFinding } from "./types.js";
16
+ export interface StubCatalogHitsOptions {
17
+ repoRoot: string;
18
+ /** Languages active for this profile. Filters which patterns run. */
19
+ languages?: readonly SensorLanguage[];
20
+ /** Pre-loaded catalog (smoke convenience). Otherwise loaded from project. */
21
+ catalog?: StubCatalog;
22
+ /**
23
+ * Cap on file size to scan (bytes). Files larger than this are skipped to
24
+ * keep the pass cheap on big artifacts. Default 256 KB.
25
+ */
26
+ maxFileBytes?: number;
27
+ }
28
+ export interface StubCatalogHitsResult {
29
+ findings: GcFinding[];
30
+ }
31
+ export declare function runStubCatalogHits(opts: StubCatalogHitsOptions): StubCatalogHitsResult;