ctxr-cli 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 (390) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +25 -0
  3. package/dist/adapter.d.ts +18 -0
  4. package/dist/adapter.d.ts.map +1 -0
  5. package/dist/adapter.js +4 -0
  6. package/dist/adapter.js.map +1 -0
  7. package/dist/adapters/builtin/index.d.ts +10 -0
  8. package/dist/adapters/builtin/index.d.ts.map +1 -0
  9. package/dist/adapters/builtin/index.js +11 -0
  10. package/dist/adapters/builtin/index.js.map +1 -0
  11. package/dist/adapters/forge/github.d.ts +9 -0
  12. package/dist/adapters/forge/github.d.ts.map +1 -0
  13. package/dist/adapters/forge/github.js +36 -0
  14. package/dist/adapters/forge/github.js.map +1 -0
  15. package/dist/adapters/forge/types.d.ts +23 -0
  16. package/dist/adapters/forge/types.d.ts.map +1 -0
  17. package/dist/adapters/forge/types.js +2 -0
  18. package/dist/adapters/forge/types.js.map +1 -0
  19. package/dist/adapters/harness/claude-code.d.ts +9 -0
  20. package/dist/adapters/harness/claude-code.d.ts.map +1 -0
  21. package/dist/adapters/harness/claude-code.js +42 -0
  22. package/dist/adapters/harness/claude-code.js.map +1 -0
  23. package/dist/adapters/identity/claude-code.d.ts +11 -0
  24. package/dist/adapters/identity/claude-code.d.ts.map +1 -0
  25. package/dist/adapters/identity/claude-code.js +18 -0
  26. package/dist/adapters/identity/claude-code.js.map +1 -0
  27. package/dist/adapters/registry.d.ts +16 -0
  28. package/dist/adapters/registry.d.ts.map +1 -0
  29. package/dist/adapters/registry.js +29 -0
  30. package/dist/adapters/registry.js.map +1 -0
  31. package/dist/adapters/types.d.ts +65 -0
  32. package/dist/adapters/types.d.ts.map +1 -0
  33. package/dist/adapters/types.js +12 -0
  34. package/dist/adapters/types.js.map +1 -0
  35. package/dist/bin.d.ts +3 -0
  36. package/dist/bin.d.ts.map +1 -0
  37. package/dist/bin.js +6 -0
  38. package/dist/bin.js.map +1 -0
  39. package/dist/commands/adapters-generate.d.ts +23 -0
  40. package/dist/commands/adapters-generate.d.ts.map +1 -0
  41. package/dist/commands/adapters-generate.js +59 -0
  42. package/dist/commands/adapters-generate.js.map +1 -0
  43. package/dist/commands/archive.d.ts +28 -0
  44. package/dist/commands/archive.d.ts.map +1 -0
  45. package/dist/commands/archive.js +66 -0
  46. package/dist/commands/archive.js.map +1 -0
  47. package/dist/commands/catalog-build.d.ts +7 -0
  48. package/dist/commands/catalog-build.d.ts.map +1 -0
  49. package/dist/commands/catalog-build.js +15 -0
  50. package/dist/commands/catalog-build.js.map +1 -0
  51. package/dist/commands/catalog-check.d.ts +22 -0
  52. package/dist/commands/catalog-check.d.ts.map +1 -0
  53. package/dist/commands/catalog-check.js +49 -0
  54. package/dist/commands/catalog-check.js.map +1 -0
  55. package/dist/commands/catalog-show.d.ts +13 -0
  56. package/dist/commands/catalog-show.d.ts.map +1 -0
  57. package/dist/commands/catalog-show.js +19 -0
  58. package/dist/commands/catalog-show.js.map +1 -0
  59. package/dist/commands/check.d.ts +22 -0
  60. package/dist/commands/check.d.ts.map +1 -0
  61. package/dist/commands/check.js +43 -0
  62. package/dist/commands/check.js.map +1 -0
  63. package/dist/commands/doctor.d.ts +27 -0
  64. package/dist/commands/doctor.d.ts.map +1 -0
  65. package/dist/commands/doctor.js +53 -0
  66. package/dist/commands/doctor.js.map +1 -0
  67. package/dist/commands/graph-build.d.ts +24 -0
  68. package/dist/commands/graph-build.d.ts.map +1 -0
  69. package/dist/commands/graph-build.js +36 -0
  70. package/dist/commands/graph-build.js.map +1 -0
  71. package/dist/commands/graph-query.d.ts +41 -0
  72. package/dist/commands/graph-query.d.ts.map +1 -0
  73. package/dist/commands/graph-query.js +63 -0
  74. package/dist/commands/graph-query.js.map +1 -0
  75. package/dist/commands/ingest.d.ts +28 -0
  76. package/dist/commands/ingest.d.ts.map +1 -0
  77. package/dist/commands/ingest.js +60 -0
  78. package/dist/commands/ingest.js.map +1 -0
  79. package/dist/commands/init.d.ts +28 -0
  80. package/dist/commands/init.d.ts.map +1 -0
  81. package/dist/commands/init.js +203 -0
  82. package/dist/commands/init.js.map +1 -0
  83. package/dist/commands/lint.d.ts +30 -0
  84. package/dist/commands/lint.d.ts.map +1 -0
  85. package/dist/commands/lint.js +48 -0
  86. package/dist/commands/lint.js.map +1 -0
  87. package/dist/commands/migrate.d.ts +30 -0
  88. package/dist/commands/migrate.d.ts.map +1 -0
  89. package/dist/commands/migrate.js +56 -0
  90. package/dist/commands/migrate.js.map +1 -0
  91. package/dist/commands/note-resolve.d.ts +14 -0
  92. package/dist/commands/note-resolve.d.ts.map +1 -0
  93. package/dist/commands/note-resolve.js +24 -0
  94. package/dist/commands/note-resolve.js.map +1 -0
  95. package/dist/commands/rollup-gather.d.ts +21 -0
  96. package/dist/commands/rollup-gather.d.ts.map +1 -0
  97. package/dist/commands/rollup-gather.js +40 -0
  98. package/dist/commands/rollup-gather.js.map +1 -0
  99. package/dist/commands/rollup-write.d.ts +25 -0
  100. package/dist/commands/rollup-write.d.ts.map +1 -0
  101. package/dist/commands/rollup-write.js +43 -0
  102. package/dist/commands/rollup-write.js.map +1 -0
  103. package/dist/commands/session-abandon.d.ts +13 -0
  104. package/dist/commands/session-abandon.d.ts.map +1 -0
  105. package/dist/commands/session-abandon.js +22 -0
  106. package/dist/commands/session-abandon.js.map +1 -0
  107. package/dist/commands/session-list.d.ts +14 -0
  108. package/dist/commands/session-list.d.ts.map +1 -0
  109. package/dist/commands/session-list.js +19 -0
  110. package/dist/commands/session-list.js.map +1 -0
  111. package/dist/commands/session-reap.d.ts +22 -0
  112. package/dist/commands/session-reap.d.ts.map +1 -0
  113. package/dist/commands/session-reap.js +47 -0
  114. package/dist/commands/session-reap.js.map +1 -0
  115. package/dist/commands/session-start.d.ts +18 -0
  116. package/dist/commands/session-start.d.ts.map +1 -0
  117. package/dist/commands/session-start.js +36 -0
  118. package/dist/commands/session-start.js.map +1 -0
  119. package/dist/commands/session-submit.d.ts +27 -0
  120. package/dist/commands/session-submit.d.ts.map +1 -0
  121. package/dist/commands/session-submit.js +68 -0
  122. package/dist/commands/session-submit.js.map +1 -0
  123. package/dist/commands/source-check.d.ts +21 -0
  124. package/dist/commands/source-check.d.ts.map +1 -0
  125. package/dist/commands/source-check.js +54 -0
  126. package/dist/commands/source-check.js.map +1 -0
  127. package/dist/commands/source-hash.d.ts +14 -0
  128. package/dist/commands/source-hash.d.ts.map +1 -0
  129. package/dist/commands/source-hash.js +34 -0
  130. package/dist/commands/source-hash.js.map +1 -0
  131. package/dist/commands/update.d.ts +17 -0
  132. package/dist/commands/update.d.ts.map +1 -0
  133. package/dist/commands/update.js +25 -0
  134. package/dist/commands/update.js.map +1 -0
  135. package/dist/commands/verify.d.ts +23 -0
  136. package/dist/commands/verify.d.ts.map +1 -0
  137. package/dist/commands/verify.js +126 -0
  138. package/dist/commands/verify.js.map +1 -0
  139. package/dist/config/defaults.d.ts +69 -0
  140. package/dist/config/defaults.d.ts.map +1 -0
  141. package/dist/config/defaults.js +71 -0
  142. package/dist/config/defaults.js.map +1 -0
  143. package/dist/config/load.d.ts +11 -0
  144. package/dist/config/load.d.ts.map +1 -0
  145. package/dist/config/load.js +49 -0
  146. package/dist/config/load.js.map +1 -0
  147. package/dist/config/render.d.ts +9 -0
  148. package/dist/config/render.d.ts.map +1 -0
  149. package/dist/config/render.js +15 -0
  150. package/dist/config/render.js.map +1 -0
  151. package/dist/config/schema.d.ts +124 -0
  152. package/dist/config/schema.d.ts.map +1 -0
  153. package/dist/config/schema.js +142 -0
  154. package/dist/config/schema.js.map +1 -0
  155. package/dist/core/agents-doc.d.ts +80 -0
  156. package/dist/core/agents-doc.d.ts.map +1 -0
  157. package/dist/core/agents-doc.js +207 -0
  158. package/dist/core/agents-doc.js.map +1 -0
  159. package/dist/core/catalog/build.d.ts +49 -0
  160. package/dist/core/catalog/build.d.ts.map +1 -0
  161. package/dist/core/catalog/build.js +113 -0
  162. package/dist/core/catalog/build.js.map +1 -0
  163. package/dist/core/catalog/model.d.ts +33 -0
  164. package/dist/core/catalog/model.d.ts.map +1 -0
  165. package/dist/core/catalog/model.js +58 -0
  166. package/dist/core/catalog/model.js.map +1 -0
  167. package/dist/core/checks/catalog-checks.d.ts +4 -0
  168. package/dist/core/checks/catalog-checks.d.ts.map +1 -0
  169. package/dist/core/checks/catalog-checks.js +65 -0
  170. package/dist/core/checks/catalog-checks.js.map +1 -0
  171. package/dist/core/checks/identity-checks.d.ts +11 -0
  172. package/dist/core/checks/identity-checks.d.ts.map +1 -0
  173. package/dist/core/checks/identity-checks.js +39 -0
  174. package/dist/core/checks/identity-checks.js.map +1 -0
  175. package/dist/core/checks/integrity-checks.d.ts +23 -0
  176. package/dist/core/checks/integrity-checks.d.ts.map +1 -0
  177. package/dist/core/checks/integrity-checks.js +132 -0
  178. package/dist/core/checks/integrity-checks.js.map +1 -0
  179. package/dist/core/checks/manifest.d.ts +7 -0
  180. package/dist/core/checks/manifest.d.ts.map +1 -0
  181. package/dist/core/checks/manifest.js +20 -0
  182. package/dist/core/checks/manifest.js.map +1 -0
  183. package/dist/core/checks/organize-checks.d.ts +18 -0
  184. package/dist/core/checks/organize-checks.d.ts.map +1 -0
  185. package/dist/core/checks/organize-checks.js +97 -0
  186. package/dist/core/checks/organize-checks.js.map +1 -0
  187. package/dist/core/checks/registry.d.ts +24 -0
  188. package/dist/core/checks/registry.d.ts.map +1 -0
  189. package/dist/core/checks/registry.js +33 -0
  190. package/dist/core/checks/registry.js.map +1 -0
  191. package/dist/core/checks/types.d.ts +72 -0
  192. package/dist/core/checks/types.d.ts.map +1 -0
  193. package/dist/core/checks/types.js +4 -0
  194. package/dist/core/checks/types.js.map +1 -0
  195. package/dist/core/checks/write-lifecycle-checks.d.ts +24 -0
  196. package/dist/core/checks/write-lifecycle-checks.d.ts.map +1 -0
  197. package/dist/core/checks/write-lifecycle-checks.js +205 -0
  198. package/dist/core/checks/write-lifecycle-checks.js.map +1 -0
  199. package/dist/core/command.d.ts +23 -0
  200. package/dist/core/command.d.ts.map +1 -0
  201. package/dist/core/command.js +2 -0
  202. package/dist/core/command.js.map +1 -0
  203. package/dist/core/content/canonicalize.d.ts +14 -0
  204. package/dist/core/content/canonicalize.d.ts.map +1 -0
  205. package/dist/core/content/canonicalize.js +34 -0
  206. package/dist/core/content/canonicalize.js.map +1 -0
  207. package/dist/core/conventions.d.ts +21 -0
  208. package/dist/core/conventions.d.ts.map +1 -0
  209. package/dist/core/conventions.js +73 -0
  210. package/dist/core/conventions.js.map +1 -0
  211. package/dist/core/disclosure/model.d.ts +18 -0
  212. package/dist/core/disclosure/model.d.ts.map +1 -0
  213. package/dist/core/disclosure/model.js +45 -0
  214. package/dist/core/disclosure/model.js.map +1 -0
  215. package/dist/core/env.d.ts +40 -0
  216. package/dist/core/env.d.ts.map +1 -0
  217. package/dist/core/env.js +24 -0
  218. package/dist/core/env.js.map +1 -0
  219. package/dist/core/envelope.d.ts +46 -0
  220. package/dist/core/envelope.d.ts.map +1 -0
  221. package/dist/core/envelope.js +21 -0
  222. package/dist/core/envelope.js.map +1 -0
  223. package/dist/core/errors.d.ts +96 -0
  224. package/dist/core/errors.d.ts.map +1 -0
  225. package/dist/core/errors.js +267 -0
  226. package/dist/core/errors.js.map +1 -0
  227. package/dist/core/exit-codes.d.ts +32 -0
  228. package/dist/core/exit-codes.d.ts.map +1 -0
  229. package/dist/core/exit-codes.js +31 -0
  230. package/dist/core/exit-codes.js.map +1 -0
  231. package/dist/core/fs/atomic.d.ts +10 -0
  232. package/dist/core/fs/atomic.d.ts.map +1 -0
  233. package/dist/core/fs/atomic.js +31 -0
  234. package/dist/core/fs/atomic.js.map +1 -0
  235. package/dist/core/fs/fenced-region.d.ts +47 -0
  236. package/dist/core/fs/fenced-region.d.ts.map +1 -0
  237. package/dist/core/fs/fenced-region.js +122 -0
  238. package/dist/core/fs/fenced-region.js.map +1 -0
  239. package/dist/core/git/exec.d.ts +28 -0
  240. package/dist/core/git/exec.d.ts.map +1 -0
  241. package/dist/core/git/exec.js +21 -0
  242. package/dist/core/git/exec.js.map +1 -0
  243. package/dist/core/git/repo.d.ts +63 -0
  244. package/dist/core/git/repo.d.ts.map +1 -0
  245. package/dist/core/git/repo.js +91 -0
  246. package/dist/core/git/repo.js.map +1 -0
  247. package/dist/core/git/staged.d.ts +10 -0
  248. package/dist/core/git/staged.d.ts.map +1 -0
  249. package/dist/core/git/staged.js +49 -0
  250. package/dist/core/git/staged.js.map +1 -0
  251. package/dist/core/git/worktree.d.ts +29 -0
  252. package/dist/core/git/worktree.d.ts.map +1 -0
  253. package/dist/core/git/worktree.js +61 -0
  254. package/dist/core/git/worktree.js.map +1 -0
  255. package/dist/core/graph/model.d.ts +43 -0
  256. package/dist/core/graph/model.d.ts.map +1 -0
  257. package/dist/core/graph/model.js +60 -0
  258. package/dist/core/graph/model.js.map +1 -0
  259. package/dist/core/graph/persist.d.ts +7 -0
  260. package/dist/core/graph/persist.d.ts.map +1 -0
  261. package/dist/core/graph/persist.js +23 -0
  262. package/dist/core/graph/persist.js.map +1 -0
  263. package/dist/core/graph/query.d.ts +16 -0
  264. package/dist/core/graph/query.d.ts.map +1 -0
  265. package/dist/core/graph/query.js +91 -0
  266. package/dist/core/graph/query.js.map +1 -0
  267. package/dist/core/graph/visibility-filter.d.ts +13 -0
  268. package/dist/core/graph/visibility-filter.d.ts.map +1 -0
  269. package/dist/core/graph/visibility-filter.js +26 -0
  270. package/dist/core/graph/visibility-filter.js.map +1 -0
  271. package/dist/core/hooks.d.ts +34 -0
  272. package/dist/core/hooks.d.ts.map +1 -0
  273. package/dist/core/hooks.js +89 -0
  274. package/dist/core/hooks.js.map +1 -0
  275. package/dist/core/identity.d.ts +14 -0
  276. package/dist/core/identity.d.ts.map +1 -0
  277. package/dist/core/identity.js +36 -0
  278. package/dist/core/identity.js.map +1 -0
  279. package/dist/core/ingest/identity.d.ts +15 -0
  280. package/dist/core/ingest/identity.d.ts.map +1 -0
  281. package/dist/core/ingest/identity.js +17 -0
  282. package/dist/core/ingest/identity.js.map +1 -0
  283. package/dist/core/ingest/model.d.ts +17 -0
  284. package/dist/core/ingest/model.d.ts.map +1 -0
  285. package/dist/core/ingest/model.js +24 -0
  286. package/dist/core/ingest/model.js.map +1 -0
  287. package/dist/core/json-config-merge.d.ts +13 -0
  288. package/dist/core/json-config-merge.d.ts.map +1 -0
  289. package/dist/core/json-config-merge.js +43 -0
  290. package/dist/core/json-config-merge.js.map +1 -0
  291. package/dist/core/markers.d.ts +17 -0
  292. package/dist/core/markers.d.ts.map +1 -0
  293. package/dist/core/markers.js +16 -0
  294. package/dist/core/markers.js.map +1 -0
  295. package/dist/core/migrations/registry.d.ts +6 -0
  296. package/dist/core/migrations/registry.d.ts.map +1 -0
  297. package/dist/core/migrations/registry.js +8 -0
  298. package/dist/core/migrations/registry.js.map +1 -0
  299. package/dist/core/migrations/rename-visibility-field.d.ts +3 -0
  300. package/dist/core/migrations/rename-visibility-field.d.ts.map +1 -0
  301. package/dist/core/migrations/rename-visibility-field.js +62 -0
  302. package/dist/core/migrations/rename-visibility-field.js.map +1 -0
  303. package/dist/core/migrations/types.d.ts +27 -0
  304. package/dist/core/migrations/types.d.ts.map +1 -0
  305. package/dist/core/migrations/types.js +2 -0
  306. package/dist/core/migrations/types.js.map +1 -0
  307. package/dist/core/notes/checks.d.ts +20 -0
  308. package/dist/core/notes/checks.d.ts.map +1 -0
  309. package/dist/core/notes/checks.js +58 -0
  310. package/dist/core/notes/checks.js.map +1 -0
  311. package/dist/core/notes/list.d.ts +26 -0
  312. package/dist/core/notes/list.d.ts.map +1 -0
  313. package/dist/core/notes/list.js +84 -0
  314. package/dist/core/notes/list.js.map +1 -0
  315. package/dist/core/notes/parse.d.ts +12 -0
  316. package/dist/core/notes/parse.d.ts.map +1 -0
  317. package/dist/core/notes/parse.js +36 -0
  318. package/dist/core/notes/parse.js.map +1 -0
  319. package/dist/core/notes/render.d.ts +7 -0
  320. package/dist/core/notes/render.d.ts.map +1 -0
  321. package/dist/core/notes/render.js +13 -0
  322. package/dist/core/notes/render.js.map +1 -0
  323. package/dist/core/notes/visibility.d.ts +26 -0
  324. package/dist/core/notes/visibility.d.ts.map +1 -0
  325. package/dist/core/notes/visibility.js +41 -0
  326. package/dist/core/notes/visibility.js.map +1 -0
  327. package/dist/core/procedures.d.ts +44 -0
  328. package/dist/core/procedures.d.ts.map +1 -0
  329. package/dist/core/procedures.js +154 -0
  330. package/dist/core/procedures.js.map +1 -0
  331. package/dist/core/queue.d.ts +16 -0
  332. package/dist/core/queue.d.ts.map +1 -0
  333. package/dist/core/queue.js +75 -0
  334. package/dist/core/queue.js.map +1 -0
  335. package/dist/core/reconcile.d.ts +18 -0
  336. package/dist/core/reconcile.d.ts.map +1 -0
  337. package/dist/core/reconcile.js +49 -0
  338. package/dist/core/reconcile.js.map +1 -0
  339. package/dist/core/records.d.ts +16 -0
  340. package/dist/core/records.d.ts.map +1 -0
  341. package/dist/core/records.js +36 -0
  342. package/dist/core/records.js.map +1 -0
  343. package/dist/core/reporter.d.ts +20 -0
  344. package/dist/core/reporter.d.ts.map +1 -0
  345. package/dist/core/reporter.js +25 -0
  346. package/dist/core/reporter.js.map +1 -0
  347. package/dist/core/root.d.ts +24 -0
  348. package/dist/core/root.d.ts.map +1 -0
  349. package/dist/core/root.js +51 -0
  350. package/dist/core/root.js.map +1 -0
  351. package/dist/core/security/secrets.d.ts +17 -0
  352. package/dist/core/security/secrets.d.ts.map +1 -0
  353. package/dist/core/security/secrets.js +21 -0
  354. package/dist/core/security/secrets.js.map +1 -0
  355. package/dist/core/session.d.ts +15 -0
  356. package/dist/core/session.d.ts.map +1 -0
  357. package/dist/core/session.js +27 -0
  358. package/dist/core/session.js.map +1 -0
  359. package/dist/core/store.d.ts +15 -0
  360. package/dist/core/store.d.ts.map +1 -0
  361. package/dist/core/store.js +19 -0
  362. package/dist/core/store.js.map +1 -0
  363. package/dist/index.d.ts +13 -0
  364. package/dist/index.d.ts.map +1 -0
  365. package/dist/index.js +7 -0
  366. package/dist/index.js.map +1 -0
  367. package/dist/prompt/inquirer-prompter.d.ts +14 -0
  368. package/dist/prompt/inquirer-prompter.d.ts.map +1 -0
  369. package/dist/prompt/inquirer-prompter.js +27 -0
  370. package/dist/prompt/inquirer-prompter.js.map +1 -0
  371. package/dist/prompt/prompter.d.ts +24 -0
  372. package/dist/prompt/prompter.d.ts.map +1 -0
  373. package/dist/prompt/prompter.js +2 -0
  374. package/dist/prompt/prompter.js.map +1 -0
  375. package/dist/run.d.ts +16 -0
  376. package/dist/run.d.ts.map +1 -0
  377. package/dist/run.js +464 -0
  378. package/dist/run.js.map +1 -0
  379. package/dist/taxonomy/profiles.d.ts +31 -0
  380. package/dist/taxonomy/profiles.d.ts.map +1 -0
  381. package/dist/taxonomy/profiles.js +45 -0
  382. package/dist/taxonomy/profiles.js.map +1 -0
  383. package/dist/version.d.ts +3 -0
  384. package/dist/version.d.ts.map +1 -0
  385. package/dist/version.js +3 -0
  386. package/dist/version.js.map +1 -0
  387. package/package.json +56 -0
  388. package/templates/.gitkeep +0 -0
  389. package/templates/hooks/pre-commit.sh +21 -0
  390. package/templates/hooks/pre-push.sh +24 -0
@@ -0,0 +1,20 @@
1
+ /**
2
+ * store-lifecycle/context-visibility: a note relying on the fail-closed
3
+ * default is a health OBSERVATION (lint), not a doctor-failing invariant —
4
+ * doctor's own fail-closed-visibility invariant (wired in Phase 5, below)
5
+ * is a different, stricter check. `severity: 'observation'` is what keeps
6
+ * this out of doctor's exit code by construction, via the same registry
7
+ * lint reads from in Phase 7.
8
+ */
9
+ export declare const failClosedVisibilityCheck: import("../checks/types.js").CheckDefinition;
10
+ /**
11
+ * context-visibility spec (task 5.2): the same underlying condition as the
12
+ * lint-facing observation above, registered a second time as its own
13
+ * invariant so `doctor` can fail a run on it. Each check id carries exactly
14
+ * one severity, so the two never double-count a single run's pass/fail
15
+ * totals against each other (task 9.4) even though both watch the same
16
+ * condition for two different audiences (an operator skimming lint output,
17
+ * versus a gate that must block).
18
+ */
19
+ export declare const failClosedVisibilityInvariantCheck: import("../checks/types.js").CheckDefinition;
20
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../../src/core/notes/checks.ts"],"names":[],"mappings":"AAsBA;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,8CAUpC,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,kCAAkC,8CAU7C,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { defineCheck } from '../checks/types.js';
2
+ import { resolveVisibility } from './visibility.js';
3
+ async function failClosedFindings(ctx) {
4
+ const notes = await ctx.notes();
5
+ const findings = [];
6
+ for (const note of notes) {
7
+ const resolution = resolveVisibility(ctx.config, note);
8
+ if (resolution.reason === 'fail-closed default') {
9
+ findings.push({
10
+ code: 'visibility.fail_closed_default',
11
+ severity: 'info',
12
+ message: `"${note.path}" has no explicit or directory-derived visibility; relying on the fail-closed default.`,
13
+ subject: note.path,
14
+ });
15
+ }
16
+ }
17
+ return findings;
18
+ }
19
+ /**
20
+ * store-lifecycle/context-visibility: a note relying on the fail-closed
21
+ * default is a health OBSERVATION (lint), not a doctor-failing invariant —
22
+ * doctor's own fail-closed-visibility invariant (wired in Phase 5, below)
23
+ * is a different, stricter check. `severity: 'observation'` is what keeps
24
+ * this out of doctor's exit code by construction, via the same registry
25
+ * lint reads from in Phase 7.
26
+ */
27
+ export const failClosedVisibilityCheck = defineCheck({
28
+ id: 'visibility.fail_closed_default',
29
+ title: 'Notes relying on the fail-closed default visibility',
30
+ severity: 'observation',
31
+ capability: 'context-visibility',
32
+ scopes: ['store'],
33
+ async run(ctx) {
34
+ const findings = await failClosedFindings(ctx);
35
+ return { status: findings.length > 0 ? 'fail' : 'pass', findings };
36
+ },
37
+ });
38
+ /**
39
+ * context-visibility spec (task 5.2): the same underlying condition as the
40
+ * lint-facing observation above, registered a second time as its own
41
+ * invariant so `doctor` can fail a run on it. Each check id carries exactly
42
+ * one severity, so the two never double-count a single run's pass/fail
43
+ * totals against each other (task 9.4) even though both watch the same
44
+ * condition for two different audiences (an operator skimming lint output,
45
+ * versus a gate that must block).
46
+ */
47
+ export const failClosedVisibilityInvariantCheck = defineCheck({
48
+ id: 'visibility.fail_closed_default_invariant',
49
+ title: 'Every note has a resolvable visibility value',
50
+ severity: 'invariant',
51
+ capability: 'context-visibility',
52
+ scopes: ['store'],
53
+ async run(ctx) {
54
+ const findings = await failClosedFindings(ctx);
55
+ return { status: findings.length > 0 ? 'fail' : 'pass', findings };
56
+ },
57
+ });
58
+ //# sourceMappingURL=checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.js","sourceRoot":"","sources":["../../../src/core/notes/checks.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,KAAK,UAAU,kBAAkB,CAAC,GAAiB;IACjD,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACvD,IAAI,UAAU,CAAC,MAAM,KAAK,qBAAqB,EAAE,CAAC;YAChD,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,gCAAgC;gBACtC,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,wFAAwF;gBAC9G,OAAO,EAAE,IAAI,CAAC,IAAI;aACnB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,WAAW,CAAC;IACnD,EAAE,EAAE,gCAAgC;IACpC,KAAK,EAAE,qDAAqD;IAC5D,QAAQ,EAAE,aAAa;IACvB,UAAU,EAAE,oBAAoB;IAChC,MAAM,EAAE,CAAC,OAAO,CAAC;IACjB,KAAK,CAAC,GAAG,CAAC,GAAG;QACX,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;IACrE,CAAC;CACF,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,WAAW,CAAC;IAC5D,EAAE,EAAE,0CAA0C;IAC9C,KAAK,EAAE,8CAA8C;IACrD,QAAQ,EAAE,WAAW;IACrB,UAAU,EAAE,oBAAoB;IAChC,MAAM,EAAE,CAAC,OAAO,CAAC;IACjB,KAAK,CAAC,GAAG,CAAC,GAAG;QACX,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;IACrE,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { StoreConfig } from '../../config/schema.js';
2
+ /**
3
+ * The note-enumeration seam every later retrieval leg builds on. `as` is
4
+ * accepted (and, until Phase 5, ignored) from Phase 0 — a real finding:
5
+ * openspec/config.yaml's own authoring rule says "sequence visibility
6
+ * enforcement before retrieval — a pre-filter cannot be safely retrofitted
7
+ * from a post-filter," but tasks.md's phase order puts retrieval (Phase 3/4)
8
+ * before visibility enforcement (Phase 5). Accepting `as` here from the
9
+ * start means Phase 5 wires a real filter into an already-filterable
10
+ * signature, instead of auditing every earlier traversal for safety.
11
+ */
12
+ export interface NoteQuery {
13
+ /** The requesting context, for visibility filtering. Wired in Phase 5. */
14
+ as?: string;
15
+ underPrefix?: string;
16
+ }
17
+ export interface Note {
18
+ /** Path relative to the store root, forward-slash separated. */
19
+ path: string;
20
+ frontmatter: Record<string, unknown> | undefined;
21
+ body: string;
22
+ }
23
+ export declare function excludedPrefixesFor(config: StoreConfig): string[];
24
+ /** Every retrievable note in the store: everything under a .md path, minus every declared exclusion. */
25
+ export declare function listNotes(storeRoot: string, config: StoreConfig, query?: NoteQuery): Promise<Note[]>;
26
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/core/notes/list.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB,0EAA0E;IAC1E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACnB,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACjD,IAAI,EAAE,MAAM,CAAC;CACd;AAkCD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAUjE;AAkCD,wGAAwG;AACxG,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,GAAE,SAAc,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAO9G"}
@@ -0,0 +1,84 @@
1
+ import { readdir } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { configuredAdapters } from '../../adapters/registry.js';
4
+ import { parseNote } from './parse.js';
5
+ /** Infrastructure directories intrinsic to contexture itself — never configurable content locations. */
6
+ const ALWAYS_SKIP_DIRS = new Set(['.git', '.githooks', '.queue']);
7
+ /**
8
+ * Filenames intrinsic to contexture itself, never user content — same
9
+ * status as ALWAYS_SKIP_DIRS. AGENTS.md is a CLI-generated procedure
10
+ * document (task 4.5), not a note; without this it would otherwise be
11
+ * picked up as one, since it lives at the store root as a plain .md file.
12
+ */
13
+ const ALWAYS_SKIP_FILES = new Set(['AGENTS.md']);
14
+ /**
15
+ * Root-level files owned by configured harness-generation adapters (e.g.
16
+ * CLAUDE.md) are tool-owned pointers, never notes. A misconfigured adapter
17
+ * is doctor's problem to report (adapters.compatibility) — enumeration
18
+ * must not fail because of it, so resolution errors just skip nothing extra.
19
+ */
20
+ function harnessEntryFiles(config) {
21
+ try {
22
+ return new Set(configuredAdapters(config, 'harness-generation').map((a) => a.entryFileName));
23
+ }
24
+ catch {
25
+ return new Set();
26
+ }
27
+ }
28
+ function isUnderAnyPrefix(relativePath, prefixes) {
29
+ return prefixes.some((prefix) => {
30
+ const trimmed = prefix.replace(/\/+$/, '');
31
+ return relativePath === trimmed || relativePath.startsWith(`${trimmed}/`);
32
+ });
33
+ }
34
+ export function excludedPrefixesFor(config) {
35
+ return [
36
+ ...config.retrieval.exclude_paths,
37
+ ...config.derived.paths,
38
+ config.session.worktrees_path,
39
+ config.catalog.path,
40
+ // Tool-owned instruction docs (skills, conventions) are never notes, wherever they live.
41
+ config.harness.procedures_path,
42
+ config.harness.conventions_path,
43
+ ];
44
+ }
45
+ async function walk(dir, root, excludePrefixes, skipRootFiles, results) {
46
+ let entries;
47
+ try {
48
+ entries = await readdir(dir, { withFileTypes: true });
49
+ }
50
+ catch (err) {
51
+ if (err.code === 'ENOENT')
52
+ return;
53
+ throw err;
54
+ }
55
+ for (const entry of entries) {
56
+ const fullPath = path.join(dir, entry.name);
57
+ const relativePath = path.relative(root, fullPath).split(path.sep).join('/');
58
+ if (entry.isDirectory()) {
59
+ if (ALWAYS_SKIP_DIRS.has(entry.name))
60
+ continue;
61
+ if (isUnderAnyPrefix(relativePath, excludePrefixes))
62
+ continue;
63
+ await walk(fullPath, root, excludePrefixes, skipRootFiles, results);
64
+ }
65
+ else if (entry.isFile() && entry.name.endsWith('.md')) {
66
+ if (ALWAYS_SKIP_FILES.has(entry.name))
67
+ continue;
68
+ if (relativePath === entry.name && skipRootFiles.has(entry.name))
69
+ continue;
70
+ if (isUnderAnyPrefix(relativePath, excludePrefixes))
71
+ continue;
72
+ results.push(relativePath);
73
+ }
74
+ }
75
+ }
76
+ /** Every retrievable note in the store: everything under a .md path, minus every declared exclusion. */
77
+ export async function listNotes(storeRoot, config, query = {}) {
78
+ const relativePaths = [];
79
+ await walk(storeRoot, storeRoot, excludedPrefixesFor(config), harnessEntryFiles(config), relativePaths);
80
+ relativePaths.sort();
81
+ const scoped = query.underPrefix ? relativePaths.filter((p) => isUnderAnyPrefix(p, [query.underPrefix])) : relativePaths;
82
+ return Promise.all(scoped.map((relativePath) => parseNote(path.join(storeRoot, relativePath), relativePath)));
83
+ }
84
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/core/notes/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Note } from './list.js';
2
+ /**
3
+ * context-store spec: "A note SHALL be a markdown file whose optional YAML
4
+ * frontmatter may declare... A note with no frontmatter SHALL be treated as
5
+ * valid content." Absence of frontmatter is fine; a `---` block that IS
6
+ * present but fails to parse, or doesn't parse to a mapping, is a real
7
+ * error — fail loud rather than silently treat malformed content as if it
8
+ * had no frontmatter at all.
9
+ */
10
+ export declare function parseNoteText(raw: string, relativePath: string): Note;
11
+ export declare function parseNote(absolutePath: string, relativePath: string): Promise<Note>;
12
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/core/notes/parse.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAItC;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAqBrE;AAED,wBAAsB,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGzF"}
@@ -0,0 +1,36 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { parse as parseYaml } from 'yaml';
3
+ import { InvalidNoteFrontmatterError } from '../errors.js';
4
+ const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
5
+ /**
6
+ * context-store spec: "A note SHALL be a markdown file whose optional YAML
7
+ * frontmatter may declare... A note with no frontmatter SHALL be treated as
8
+ * valid content." Absence of frontmatter is fine; a `---` block that IS
9
+ * present but fails to parse, or doesn't parse to a mapping, is a real
10
+ * error — fail loud rather than silently treat malformed content as if it
11
+ * had no frontmatter at all.
12
+ */
13
+ export function parseNoteText(raw, relativePath) {
14
+ const match = FRONTMATTER_RE.exec(raw);
15
+ if (!match) {
16
+ return { path: relativePath, frontmatter: undefined, body: raw };
17
+ }
18
+ const frontmatterText = match[1] ?? '';
19
+ const body = raw.slice(match[0].length);
20
+ let parsed;
21
+ try {
22
+ parsed = parseYaml(frontmatterText);
23
+ }
24
+ catch (err) {
25
+ throw new InvalidNoteFrontmatterError(relativePath, err instanceof Error ? err.message : String(err));
26
+ }
27
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
28
+ throw new InvalidNoteFrontmatterError(relativePath, 'frontmatter must be a YAML mapping');
29
+ }
30
+ return { path: relativePath, frontmatter: parsed, body };
31
+ }
32
+ export async function parseNote(absolutePath, relativePath) {
33
+ const raw = await readFile(absolutePath, 'utf8');
34
+ return parseNoteText(raw, relativePath);
35
+ }
36
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/core/notes/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAG3D,MAAM,cAAc,GAAG,mCAAmC,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,YAAoB;IAC7D,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACnE,CAAC;IAED,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACvC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAExC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC,eAAe,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,2BAA2B,CAAC,YAAY,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACxG,CAAC;IAED,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,2BAA2B,CAAC,YAAY,EAAE,oCAAoC,CAAC,CAAC;IAC5F,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,MAAiC,EAAE,IAAI,EAAE,CAAC;AACtF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,YAAoB,EAAE,YAAoB;IACxE,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACjD,OAAO,aAAa,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The inverse of parseNoteText (core/notes/parse.ts): re-serializes a note
3
+ * back to raw file text. `undefined` frontmatter renders as no frontmatter
4
+ * block at all, matching parseNoteText's own treatment of absence.
5
+ */
6
+ export declare function renderNoteText(frontmatter: Record<string, unknown> | undefined, body: string): string;
7
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/core/notes/render.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrG"}
@@ -0,0 +1,13 @@
1
+ import { stringify as stringifyYaml } from 'yaml';
2
+ /**
3
+ * The inverse of parseNoteText (core/notes/parse.ts): re-serializes a note
4
+ * back to raw file text. `undefined` frontmatter renders as no frontmatter
5
+ * block at all, matching parseNoteText's own treatment of absence.
6
+ */
7
+ export function renderNoteText(frontmatter, body) {
8
+ if (!frontmatter || Object.keys(frontmatter).length === 0) {
9
+ return body;
10
+ }
11
+ return `---\n${stringifyYaml(frontmatter, { indent: 2 })}---\n${body}`;
12
+ }
13
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/core/notes/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,MAAM,CAAC;AAElD;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,WAAgD,EAAE,IAAY;IAC3F,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,QAAQ,aAAa,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC;AACzE,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { StoreConfig } from '../../config/schema.js';
2
+ import type { Note } from './list.js';
3
+ /**
4
+ * context-visibility spec: resolution order is explicit → directory default
5
+ * → the configured fail-closed default, and every resolution reports WHICH
6
+ * rung produced it — not just the resolved value — so a note relying on the
7
+ * fail-closed default is distinguishable from one genuinely classified.
8
+ */
9
+ export type VisibilityReason = 'explicit' | 'directory default' | 'fail-closed default';
10
+ export interface VisibilityResolution {
11
+ value: string;
12
+ reason: VisibilityReason;
13
+ }
14
+ export declare function resolveVisibility(config: StoreConfig, note: Note): VisibilityResolution;
15
+ /**
16
+ * context-visibility spec (visibility-contexts-and-wall-verdicts): the set
17
+ * of visibility VALUES a requesting context can see — the one shared
18
+ * primitive every filtered consumer (graph pre-filter, disclosure rung 3)
19
+ * calls instead of raw equality. Identity default: an unconfigured context
20
+ * sees exactly its own value, so unconfigured stores behave exactly as
21
+ * before the mapping existed, and unknown contexts fail closed to it.
22
+ */
23
+ export declare function visibleValuesFor(config: StoreConfig, context: string): readonly string[];
24
+ /** Whether `context` can see a note whose resolved visibility is `value`. */
25
+ export declare function canSee(config: StoreConfig, context: string, value: string): boolean;
26
+ //# sourceMappingURL=visibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visibility.d.ts","sourceRoot":"","sources":["../../../src/core/notes/visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,mBAAmB,GAAG,qBAAqB,CAAC;AAExF,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,GAAG,oBAAoB,CAavF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAExF;AAED,6EAA6E;AAC7E,wBAAgB,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnF"}
@@ -0,0 +1,41 @@
1
+ export function resolveVisibility(config, note) {
2
+ const fieldKey = config.fields.visibility;
3
+ const explicit = note.frontmatter?.[fieldKey];
4
+ if (typeof explicit === 'string' && explicit.length > 0) {
5
+ return { value: explicit, reason: 'explicit' };
6
+ }
7
+ const directoryDefault = findDirectoryDefault(config, note.path);
8
+ if (directoryDefault !== undefined) {
9
+ return { value: directoryDefault, reason: 'directory default' };
10
+ }
11
+ return { value: config.visibility.default_context, reason: 'fail-closed default' };
12
+ }
13
+ /**
14
+ * context-visibility spec (visibility-contexts-and-wall-verdicts): the set
15
+ * of visibility VALUES a requesting context can see — the one shared
16
+ * primitive every filtered consumer (graph pre-filter, disclosure rung 3)
17
+ * calls instead of raw equality. Identity default: an unconfigured context
18
+ * sees exactly its own value, so unconfigured stores behave exactly as
19
+ * before the mapping existed, and unknown contexts fail closed to it.
20
+ */
21
+ export function visibleValuesFor(config, context) {
22
+ return config.visibility.contexts[context] ?? [context];
23
+ }
24
+ /** Whether `context` can see a note whose resolved visibility is `value`. */
25
+ export function canSee(config, context, value) {
26
+ return visibleValuesFor(config, context).includes(value);
27
+ }
28
+ /** Longest matching path-prefix wins, so a more specific directory default overrides a broader one. */
29
+ function findDirectoryDefault(config, notePath) {
30
+ let best;
31
+ for (const [prefix, value] of Object.entries(config.visibility.directory_defaults)) {
32
+ const normalizedPrefix = prefix.endsWith('/') ? prefix : `${prefix}/`;
33
+ if (notePath === prefix || notePath.startsWith(normalizedPrefix)) {
34
+ if (!best || prefix.length > best.prefix.length) {
35
+ best = { prefix, value };
36
+ }
37
+ }
38
+ }
39
+ return best?.value;
40
+ }
41
+ //# sourceMappingURL=visibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visibility.js","sourceRoot":"","sources":["../../../src/core/notes/visibility.ts"],"names":[],"mappings":"AAgBA,MAAM,UAAU,iBAAiB,CAAC,MAAmB,EAAE,IAAU;IAC/D,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACjD,CAAC;IAED,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAClE,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,eAAe,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;AACrF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAmB,EAAE,OAAe;IACnE,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC1D,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,MAAM,CAAC,MAAmB,EAAE,OAAe,EAAE,KAAa;IACxE,OAAO,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED,uGAAuG;AACvG,SAAS,oBAAoB,CAAC,MAAmB,EAAE,QAAgB;IACjE,IAAI,IAAmD,CAAC;IACxD,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACnF,MAAM,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC;QACtE,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACjE,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBAChD,IAAI,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,EAAE,KAAK,CAAC;AACrB,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { StoreConfig } from '../config/schema.js';
2
+ import { type ScannedDoc } from './conventions.js';
3
+ /**
4
+ * harness-portability spec (task 8.6, revised by entry-doc-generation D5):
5
+ * reusable store procedures ship as contexture-OWNED skills. The canonical
6
+ * content is this module (versioned with the package); a store carries a
7
+ * full copy at `<procedures_path>/ctxr-<slug>/SKILL.md` — written by
8
+ * `ctxr init`, refreshed by `ctxr update`, never hand-edited. The default
9
+ * location is the directory harnesses with skill auto-discovery read, so
10
+ * there is no wrapper and no extra hop; any other harness reaches the same
11
+ * file by path from AGENTS.md. Operator-authored skills live alongside,
12
+ * untouched by sync. Each seed names the real CLI commands built in
13
+ * earlier phases, in the order a judgment-driven operation uses them.
14
+ */
15
+ export interface Procedure {
16
+ /** Skill directory slug under config.harness.procedures_path (file is `<slug>/SKILL.md`). */
17
+ file: string;
18
+ /** The human title (the H1 in the skill body). */
19
+ name: string;
20
+ /** One line for skill-discovery metadata and the AGENTS.md index. */
21
+ description: string;
22
+ content: string;
23
+ }
24
+ export declare const MANAGED_SKILL_HEADER = "<!-- Owned by contexture \u2014 written by `ctxr init`, refreshed by `ctxr update`. Do not edit; add your own skills alongside. -->";
25
+ export declare const PROCEDURES: readonly Procedure[];
26
+ /**
27
+ * entry-doc-generation spec: every skill actually on disk — the contexture-
28
+ * owned ones plus any operator-authored ones. This is what the AGENTS.md
29
+ * index and verify --portable consume; the static PROCEDURES const is only
30
+ * the canonical content syncShippedSkills writes.
31
+ */
32
+ export declare function scanProcedures(root: string, config: StoreConfig): Promise<ScannedDoc[]>;
33
+ export declare function procedurePaths(config: StoreConfig): string[];
34
+ /**
35
+ * Brings every contexture-owned skill copy to the installed package's
36
+ * content: written when missing, rewritten when different (byte-stable —
37
+ * an up-to-date copy is not touched). Managed copies the installed version
38
+ * no longer ships (recognised by the managed header) are removed, so a
39
+ * renamed slug never leaves an orphan behind. Only files bearing the header
40
+ * are ever removed; operator skills are untouched. Returns every path it
41
+ * wrote or removed.
42
+ */
43
+ export declare function syncShippedSkills(root: string, config: StoreConfig): Promise<string[]>;
44
+ //# sourceMappingURL=procedures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../../src/core/procedures.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGjF;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,oBAAoB,wIACiG,CAAC;AAEnI,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EA8E1C,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAEvF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAE5D;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA2C5F"}
@@ -0,0 +1,154 @@
1
+ import { mkdir, readdir, readFile, rm } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { scanDocsDir, SKILL_FILE_NAME } from './conventions.js';
4
+ import { writeFileAtomic } from './fs/atomic.js';
5
+ export const MANAGED_SKILL_HEADER = '<!-- Owned by contexture — written by `ctxr init`, refreshed by `ctxr update`. Do not edit; add your own skills alongside. -->';
6
+ export const PROCEDURES = [
7
+ {
8
+ file: 'ctxr-ingest-orchestration',
9
+ name: 'Ingest orchestration',
10
+ description: 'Capture raw material into the inbox, run the dedupe check, and ingest it with source identity via the contexture CLI.',
11
+ content: `---
12
+ name: ctxr-ingest-orchestration
13
+ description: Capture raw material into the inbox, run the dedupe check, and ingest it with source identity via the contexture CLI.
14
+ ---
15
+
16
+ ${MANAGED_SKILL_HEADER}
17
+
18
+ # Ingest orchestration
19
+
20
+ 1. Capture: write a plain markdown file directly into the inbox (see AGENTS.md's capture section) — no source-identity frontmatter.
21
+ 2. Check: run \`ctxr source check <path> --source-id <id>\` and read the verdict — \`new\`, \`already_ingested\`, \`alternate_source_match\`, or \`multiple_matches\`.
22
+ 3. On \`multiple_matches\`, stop and resolve the ambiguity yourself; do not guess which existing note it is.
23
+ 4. On \`new\` (or a deliberate decision to ingest anyway despite an \`alternate_source_match\`), run \`ctxr ingest <path> --source-type <type> --source-id <id>\`.
24
+ 5. The result already has a catalog entry — no separate catalog step is needed.
25
+ `,
26
+ },
27
+ {
28
+ file: 'ctxr-placement',
29
+ name: 'Placement',
30
+ description: 'Choose the right taxonomy layer for a new or relocated note in this contexture store.',
31
+ content: `---
32
+ name: ctxr-placement
33
+ description: Choose the right taxonomy layer for a new or relocated note in this contexture store.
34
+ ---
35
+
36
+ ${MANAGED_SKILL_HEADER}
37
+
38
+ # Placement
39
+
40
+ 1. Read AGENTS.md's "Placing a new note" section for this store's configured taxonomy layers (or lack thereof).
41
+ 2. Choose the layer whose description best matches the note; if none fits, use the catch-all location.
42
+ 3. To relocate a note that already exists (not a first placement), use \`ctxr archive <path>\` if it is being retired, or a plain tracked \`git mv\` for an ordinary re-placement — either way, the note's frontmatter (including its visibility field) is left untouched.
43
+ 4. Run \`ctxr lint\` afterward; "uningested inbox material" and "no catalog entry" findings will surface anything left unplaced.
44
+ `,
45
+ },
46
+ {
47
+ file: 'ctxr-connection-finding',
48
+ name: 'Connection finding',
49
+ description: 'Find related notes via the wikilink graph of the store (neighbors, paths, hubs) and write rollups from gathered sources.',
50
+ content: `---
51
+ name: ctxr-connection-finding
52
+ description: Find related notes via the wikilink graph of the store (neighbors, paths, hubs) and write rollups from gathered sources.
53
+ ---
54
+
55
+ ${MANAGED_SKILL_HEADER}
56
+
57
+ # Connection finding
58
+
59
+ 1. Run \`ctxr graph build\` to refresh the wikilink graph from the store's current notes.
60
+ 2. To find what a note connects to or from, run \`ctxr graph query neighbors <path>\` (add \`--depth\` for further hops, \`--direction in|out|both\`).
61
+ 3. To find a path between two notes, run \`ctxr graph query path <from> <to>\`.
62
+ 4. To find the most-referenced notes, run \`ctxr graph query hubs\`.
63
+ 5. Before writing a rollup for an entity, run \`ctxr rollup gather <entity>\` to enumerate candidate source notes — read those, then commit your synthesis with \`ctxr rollup write <entity> --content-file <path>\`.
64
+ `,
65
+ },
66
+ {
67
+ file: 'ctxr-organize-audit',
68
+ name: 'Organize audit',
69
+ description: 'Audit store health with ctxr lint (observations) and ctxr doctor (blocking invariants).',
70
+ content: `---
71
+ name: ctxr-organize-audit
72
+ description: Audit store health with ctxr lint (observations) and ctxr doctor (blocking invariants).
73
+ ---
74
+
75
+ ${MANAGED_SKILL_HEADER}
76
+
77
+ # Organize audit
78
+
79
+ 1. Run \`ctxr lint\` for a full health report — orphan notes, broken links, uningested inbox material, and catalog gaps. It always exits 0; read its findings, it never blocks anything.
80
+ 2. Run \`ctxr doctor\` to check the invariants that DO block: catalog coverage, fail-closed visibility, hook health, and more.
81
+ 3. Address doctor's failures before submitting a session; lint's findings are a judgment call for whoever is doing the audit.
82
+ `,
83
+ },
84
+ ];
85
+ /**
86
+ * entry-doc-generation spec: every skill actually on disk — the contexture-
87
+ * owned ones plus any operator-authored ones. This is what the AGENTS.md
88
+ * index and verify --portable consume; the static PROCEDURES const is only
89
+ * the canonical content syncShippedSkills writes.
90
+ */
91
+ export function scanProcedures(root, config) {
92
+ return scanDocsDir(root, config.harness.procedures_path);
93
+ }
94
+ export function procedurePaths(config) {
95
+ return PROCEDURES.map((p) => path.join(config.harness.procedures_path, p.file, SKILL_FILE_NAME).split(path.sep).join('/'));
96
+ }
97
+ /**
98
+ * Brings every contexture-owned skill copy to the installed package's
99
+ * content: written when missing, rewritten when different (byte-stable —
100
+ * an up-to-date copy is not touched). Managed copies the installed version
101
+ * no longer ships (recognised by the managed header) are removed, so a
102
+ * renamed slug never leaves an orphan behind. Only files bearing the header
103
+ * are ever removed; operator skills are untouched. Returns every path it
104
+ * wrote or removed.
105
+ */
106
+ export async function syncShippedSkills(root, config) {
107
+ const changed = [];
108
+ for (const procedure of PROCEDURES) {
109
+ const relativePath = path
110
+ .join(config.harness.procedures_path, procedure.file, SKILL_FILE_NAME)
111
+ .split(path.sep)
112
+ .join('/');
113
+ const absolutePath = path.join(root, relativePath);
114
+ let existing;
115
+ try {
116
+ existing = await readFile(absolutePath, 'utf8');
117
+ }
118
+ catch {
119
+ existing = undefined;
120
+ }
121
+ if (existing !== procedure.content) {
122
+ await mkdir(path.dirname(absolutePath), { recursive: true });
123
+ await writeFileAtomic(absolutePath, procedure.content);
124
+ changed.push(relativePath);
125
+ }
126
+ }
127
+ const shippedSlugs = new Set(PROCEDURES.map((p) => p.file));
128
+ const skillsDir = path.join(root, config.harness.procedures_path);
129
+ let entries = [];
130
+ try {
131
+ entries = await readdir(skillsDir, { withFileTypes: true });
132
+ }
133
+ catch {
134
+ entries = [];
135
+ }
136
+ for (const entry of entries) {
137
+ if (!entry.isDirectory() || shippedSlugs.has(entry.name))
138
+ continue;
139
+ const skillFile = path.join(skillsDir, entry.name, SKILL_FILE_NAME);
140
+ let content;
141
+ try {
142
+ content = await readFile(skillFile, 'utf8');
143
+ }
144
+ catch {
145
+ continue;
146
+ }
147
+ if (!content.includes(MANAGED_SKILL_HEADER))
148
+ continue; // operator-authored: never touched
149
+ await rm(path.join(skillsDir, entry.name), { recursive: true, force: true });
150
+ changed.push(path.join(config.harness.procedures_path, entry.name, SKILL_FILE_NAME).split(path.sep).join('/'));
151
+ }
152
+ return changed;
153
+ }
154
+ //# sourceMappingURL=procedures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procedures.js","sourceRoot":"","sources":["../../src/core/procedures.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export declare function queueAppend(storeRoot: string, targetRelativePath: string, content: string): Promise<string>;
2
+ export interface AppliedEntry {
3
+ file: string;
4
+ target: string;
5
+ }
6
+ export interface ReconcileSummary {
7
+ applied: AppliedEntry[];
8
+ }
9
+ /**
10
+ * Applies every pending queue file to its target, oldest first, deleting
11
+ * each as it's applied. A malformed entry (missing header, path escaping
12
+ * the store, or a non-.md target) throws rather than being silently
13
+ * skipped or guessed at.
14
+ */
15
+ export declare function reconcileQueue(storeRoot: string): Promise<ReconcileSummary>;
16
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/core/queue.ts"],"names":[],"mappings":"AAmBA,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUjH;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwCjF"}