@ybotok/loam 0.1.0-beta.3 → 0.2.0-alpha.13

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 (1256) hide show
  1. package/CHANGELOG.md +5992 -82
  2. package/COMPARISON.md +168 -63
  3. package/CONTRIBUTING.md +121 -0
  4. package/MIGRATING-from-OpenSpec.md +238 -55
  5. package/QUICKSTART.md +302 -0
  6. package/README.md +653 -144
  7. package/ROADMAP.md +1035 -0
  8. package/SCHEMA.md +3916 -263
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +927 -0
  11. package/dist/cli.js +133 -21
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +204 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +309 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +74 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/closing.js +42 -0
  20. package/dist/commands/archive/closing.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
  22. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  23. package/dist/commands/archive/plan/contracts/consumers.js +56 -0
  24. package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
  25. package/dist/commands/archive/plan/contracts/openapi.js +193 -0
  26. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  27. package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
  28. package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
  29. package/dist/commands/archive/plan/document/head.js +151 -0
  30. package/dist/commands/archive/plan/document/head.js.map +1 -0
  31. package/dist/commands/archive/plan/document/links.js +284 -0
  32. package/dist/commands/archive/plan/document/links.js.map +1 -0
  33. package/dist/commands/archive/plan/document/run.js +136 -0
  34. package/dist/commands/archive/plan/document/run.js.map +1 -0
  35. package/dist/commands/archive/plan/gate.js +319 -0
  36. package/dist/commands/archive/plan/gate.js.map +1 -0
  37. package/dist/commands/archive/plan/landscape.js +298 -0
  38. package/dist/commands/archive/plan/landscape.js.map +1 -0
  39. package/dist/commands/archive/plan/model/extending.js +85 -0
  40. package/dist/commands/archive/plan/model/extending.js.map +1 -0
  41. package/dist/commands/archive/plan/refusal.js +106 -0
  42. package/dist/commands/archive/plan/refusal.js.map +1 -0
  43. package/dist/commands/archive/plan/specs.js +318 -0
  44. package/dist/commands/archive/plan/specs.js.map +1 -0
  45. package/dist/commands/archive/plan/state.js +30 -0
  46. package/dist/commands/archive/plan/state.js.map +1 -0
  47. package/dist/commands/archive/run.js +355 -0
  48. package/dist/commands/archive/run.js.map +1 -0
  49. package/dist/commands/archive/shipped.js +49 -0
  50. package/dist/commands/archive/shipped.js.map +1 -0
  51. package/dist/commands/context/context.js +166 -0
  52. package/dist/commands/context/context.js.map +1 -0
  53. package/dist/commands/context/print.js +305 -0
  54. package/dist/commands/context/print.js.map +1 -0
  55. package/dist/commands/delta/delta.js +367 -0
  56. package/dist/commands/delta/delta.js.map +1 -0
  57. package/dist/commands/delta/print.js +221 -0
  58. package/dist/commands/delta/print.js.map +1 -0
  59. package/dist/commands/dependencies.js +6 -8
  60. package/dist/commands/dependencies.js.map +1 -1
  61. package/dist/commands/diff/diff.js +86 -0
  62. package/dist/commands/diff/diff.js.map +1 -0
  63. package/dist/commands/diff/print.js +38 -0
  64. package/dist/commands/diff/print.js.map +1 -0
  65. package/dist/commands/doctor.js +65 -5
  66. package/dist/commands/doctor.js.map +1 -1
  67. package/dist/commands/explain/explain.js +227 -0
  68. package/dist/commands/explain/explain.js.map +1 -0
  69. package/dist/commands/explore.js +39 -28
  70. package/dist/commands/explore.js.map +1 -1
  71. package/dist/commands/gate/gate.js +152 -0
  72. package/dist/commands/gate/gate.js.map +1 -0
  73. package/dist/commands/gate/print.js +66 -0
  74. package/dist/commands/gate/print.js.map +1 -0
  75. package/dist/commands/gherkin/commit.js +105 -0
  76. package/dist/commands/gherkin/commit.js.map +1 -0
  77. package/dist/commands/gherkin/gherkin.js +262 -0
  78. package/dist/commands/gherkin/gherkin.js.map +1 -0
  79. package/dist/commands/gherkin/reconcile.js +146 -0
  80. package/dist/commands/gherkin/reconcile.js.map +1 -0
  81. package/dist/commands/gherkin/render.js +77 -0
  82. package/dist/commands/gherkin/render.js.map +1 -0
  83. package/dist/commands/init/example.js +204 -0
  84. package/dist/commands/init/example.js.map +1 -0
  85. package/dist/commands/init/first-hour.js +72 -0
  86. package/dist/commands/init/first-hour.js.map +1 -0
  87. package/dist/commands/{init.js → init/init.js} +142 -71
  88. package/dist/commands/init/init.js.map +1 -0
  89. package/dist/commands/init/mcp.js +131 -0
  90. package/dist/commands/init/mcp.js.map +1 -0
  91. package/dist/commands/init/options.js +78 -0
  92. package/dist/commands/init/options.js.map +1 -0
  93. package/dist/commands/instructions.js +72 -14
  94. package/dist/commands/instructions.js.map +1 -1
  95. package/dist/commands/list/campaign/campaign.js +63 -0
  96. package/dist/commands/list/campaign/campaign.js.map +1 -0
  97. package/dist/commands/list/campaign/owners.js +65 -0
  98. package/dist/commands/list/campaign/owners.js.map +1 -0
  99. package/dist/commands/list/json.js +155 -0
  100. package/dist/commands/list/json.js.map +1 -0
  101. package/dist/commands/list/list.js +358 -0
  102. package/dist/commands/list/list.js.map +1 -0
  103. package/dist/commands/list/print.js +344 -0
  104. package/dist/commands/list/print.js.map +1 -0
  105. package/dist/commands/list/review.js +120 -0
  106. package/dist/commands/list/review.js.map +1 -0
  107. package/dist/commands/list/suites/suites.js +140 -0
  108. package/dist/commands/list/suites/suites.js.map +1 -0
  109. package/dist/commands/list/views.js +108 -0
  110. package/dist/commands/list/views.js.map +1 -0
  111. package/dist/commands/mcp/dispatch.js +238 -0
  112. package/dist/commands/mcp/dispatch.js.map +1 -0
  113. package/dist/commands/mcp/mcp.js +75 -0
  114. package/dist/commands/mcp/mcp.js.map +1 -0
  115. package/dist/commands/mcp/serve.js +55 -0
  116. package/dist/commands/mcp/serve.js.map +1 -0
  117. package/dist/commands/migrate-openspec/materialize/active.js +175 -0
  118. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  119. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  120. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  121. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  122. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  123. package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
  124. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  125. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  126. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  127. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  128. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  129. package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
  130. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  131. package/dist/commands/migrate-openspec/openspec/error.js +18 -0
  132. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  133. package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
  134. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  135. package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
  136. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  137. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  138. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  139. package/dist/commands/migrate-openspec/print.js +89 -0
  140. package/dist/commands/migrate-openspec/print.js.map +1 -0
  141. package/dist/commands/new/capability-template.js +118 -0
  142. package/dist/commands/new/capability-template.js.map +1 -0
  143. package/dist/commands/new/commit.js +62 -0
  144. package/dist/commands/new/commit.js.map +1 -0
  145. package/dist/commands/new/modifies.js +206 -0
  146. package/dist/commands/new/modifies.js.map +1 -0
  147. package/dist/commands/new/new.js +328 -0
  148. package/dist/commands/new/new.js.map +1 -0
  149. package/dist/commands/new/templates.js +279 -0
  150. package/dist/commands/new/templates.js.map +1 -0
  151. package/dist/commands/open.js +199 -0
  152. package/dist/commands/open.js.map +1 -0
  153. package/dist/commands/policy/format.js +152 -0
  154. package/dist/commands/policy/format.js.map +1 -0
  155. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
  156. package/dist/commands/policy/gate.js.map +1 -0
  157. package/dist/commands/rebase/edit.js +106 -0
  158. package/dist/commands/rebase/edit.js.map +1 -0
  159. package/dist/commands/rebase/living.js +185 -0
  160. package/dist/commands/rebase/living.js.map +1 -0
  161. package/dist/commands/rebase/plan.js +245 -0
  162. package/dist/commands/rebase/plan.js.map +1 -0
  163. package/dist/commands/rebase/rebase.js +300 -0
  164. package/dist/commands/rebase/rebase.js.map +1 -0
  165. package/dist/commands/seed/commit.js +221 -0
  166. package/dist/commands/seed/commit.js.map +1 -0
  167. package/dist/commands/seed/plan.js +278 -0
  168. package/dist/commands/seed/plan.js.map +1 -0
  169. package/dist/commands/seed/seed.js +174 -0
  170. package/dist/commands/seed/seed.js.map +1 -0
  171. package/dist/commands/show/feature.js +182 -0
  172. package/dist/commands/show/feature.js.map +1 -0
  173. package/dist/commands/show/introduced.js +157 -0
  174. package/dist/commands/show/introduced.js.map +1 -0
  175. package/dist/commands/show/marks.js +53 -0
  176. package/dist/commands/show/marks.js.map +1 -0
  177. package/dist/commands/show/service.js +239 -0
  178. package/dist/commands/show/service.js.map +1 -0
  179. package/dist/commands/show/show.js +87 -0
  180. package/dist/commands/show/show.js.map +1 -0
  181. package/dist/commands/status/fleet-next.js +90 -0
  182. package/dist/commands/status/fleet-next.js.map +1 -0
  183. package/dist/commands/status/json.js +47 -0
  184. package/dist/commands/status/json.js.map +1 -0
  185. package/dist/commands/status/print.js +209 -0
  186. package/dist/commands/status/print.js.map +1 -0
  187. package/dist/commands/status/status.js +115 -0
  188. package/dist/commands/status/status.js.map +1 -0
  189. package/dist/commands/steps/steps.js +269 -0
  190. package/dist/commands/steps/steps.js.map +1 -0
  191. package/dist/commands/subsystem/edit.js +192 -0
  192. package/dist/commands/subsystem/edit.js.map +1 -0
  193. package/dist/commands/subsystem/move.js +325 -0
  194. package/dist/commands/subsystem/move.js.map +1 -0
  195. package/dist/commands/subsystem/query.js +113 -0
  196. package/dist/commands/subsystem/query.js.map +1 -0
  197. package/dist/commands/subsystem/subsystem.js +98 -0
  198. package/dist/commands/subsystem/subsystem.js.map +1 -0
  199. package/dist/commands/subsystem/sync.js +318 -0
  200. package/dist/commands/subsystem/sync.js.map +1 -0
  201. package/dist/commands/subsystem/txn/exclude.js +132 -0
  202. package/dist/commands/subsystem/txn/exclude.js.map +1 -0
  203. package/dist/commands/subsystem/txn/links.js +128 -0
  204. package/dist/commands/subsystem/txn/links.js.map +1 -0
  205. package/dist/commands/subsystem/txn/report.js +174 -0
  206. package/dist/commands/subsystem/txn/report.js.map +1 -0
  207. package/dist/commands/subsystem/txn/txn.js +196 -0
  208. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  209. package/dist/commands/subsystem/txn/views.js +249 -0
  210. package/dist/commands/subsystem/txn/views.js.map +1 -0
  211. package/dist/commands/tasks/actions.js +107 -0
  212. package/dist/commands/tasks/actions.js.map +1 -0
  213. package/dist/commands/tasks/render.js +253 -0
  214. package/dist/commands/tasks/render.js.map +1 -0
  215. package/dist/commands/tasks/tasks.js +119 -0
  216. package/dist/commands/tasks/tasks.js.map +1 -0
  217. package/dist/commands/unarchive/manifest.js +176 -0
  218. package/dist/commands/unarchive/manifest.js.map +1 -0
  219. package/dist/commands/unarchive/restore.js +254 -0
  220. package/dist/commands/unarchive/restore.js.map +1 -0
  221. package/dist/commands/unarchive/unarchive.js +59 -0
  222. package/dist/commands/unarchive/unarchive.js.map +1 -0
  223. package/dist/commands/validate/arch-coverage.js +245 -0
  224. package/dist/commands/validate/arch-coverage.js.map +1 -0
  225. package/dist/commands/validate/checks/fleet-shape.js +204 -0
  226. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  227. package/dist/commands/validate/checks/health-deps.js +58 -0
  228. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  229. package/dist/commands/validate/checks/introduced.js +102 -0
  230. package/dist/commands/validate/checks/introduced.js.map +1 -0
  231. package/dist/commands/validate/checks/requirements.js +264 -0
  232. package/dist/commands/validate/checks/requirements.js.map +1 -0
  233. package/dist/commands/validate/checks/sources.js +85 -0
  234. package/dist/commands/validate/checks/sources.js.map +1 -0
  235. package/dist/commands/validate/coverage/covers-after.js +105 -0
  236. package/dist/commands/validate/coverage/covers-after.js.map +1 -0
  237. package/dist/commands/validate/feature.js +222 -0
  238. package/dist/commands/validate/feature.js.map +1 -0
  239. package/dist/commands/validate/fleet/census.js +93 -0
  240. package/dist/commands/validate/fleet/census.js.map +1 -0
  241. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  242. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  243. package/dist/commands/validate/fleet/landscape.js +371 -0
  244. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  245. package/dist/commands/validate/fleet/load.js +118 -0
  246. package/dist/commands/validate/fleet/load.js.map +1 -0
  247. package/dist/commands/validate/fleet/map/attest.js +98 -0
  248. package/dist/commands/validate/fleet/map/attest.js.map +1 -0
  249. package/dist/commands/validate/fleet/map/bindings.js +107 -0
  250. package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
  251. package/dist/commands/validate/fleet/map/consumers.js +244 -0
  252. package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
  253. package/dist/commands/validate/fleet/map/isolation.js +116 -0
  254. package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
  255. package/dist/commands/validate/fleet/map/usecases.js +54 -0
  256. package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
  257. package/dist/commands/validate/fleet/obligations.js +266 -0
  258. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  259. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  260. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  261. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  262. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  263. package/dist/commands/validate/fleet/scorecard/print.js +71 -0
  264. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  265. package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
  266. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  267. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  268. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  269. package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
  270. package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
  271. package/dist/commands/validate/fleet/views/ids.js +75 -0
  272. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  273. package/dist/commands/validate/fleet/views/projects.js +278 -0
  274. package/dist/commands/validate/fleet/views/projects.js.map +1 -0
  275. package/dist/commands/validate/fleet/views/root-documents.js +83 -0
  276. package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
  277. package/dist/commands/validate/fleet/views/stale.js +52 -0
  278. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  279. package/dist/commands/validate/links/corpus.js +89 -0
  280. package/dist/commands/validate/links/corpus.js.map +1 -0
  281. package/dist/commands/validate/links/glossary.js +75 -0
  282. package/dist/commands/validate/links/glossary.js.map +1 -0
  283. package/dist/commands/validate/render/repeats.js +63 -0
  284. package/dist/commands/validate/render/repeats.js.map +1 -0
  285. package/dist/commands/validate/render/rollups.js +115 -0
  286. package/dist/commands/validate/render/rollups.js.map +1 -0
  287. package/dist/commands/validate/render/text.js +199 -0
  288. package/dist/commands/validate/render/text.js.map +1 -0
  289. package/dist/commands/validate/report.js +145 -0
  290. package/dist/commands/validate/report.js.map +1 -0
  291. package/dist/commands/validate/scope.js +113 -0
  292. package/dist/commands/validate/scope.js.map +1 -0
  293. package/dist/commands/validate/service/api.js +252 -0
  294. package/dist/commands/validate/service/api.js.map +1 -0
  295. package/dist/commands/validate/service/contracts/generated.js +134 -0
  296. package/dist/commands/validate/service/contracts/generated.js.map +1 -0
  297. package/dist/commands/validate/service/events/events.js +241 -0
  298. package/dist/commands/validate/service/events/events.js.map +1 -0
  299. package/dist/commands/validate/service/events/message-producers.js +77 -0
  300. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  301. package/dist/commands/validate/service/evidence-pins.js +177 -0
  302. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  303. package/dist/commands/validate/service/model/diverged.js +226 -0
  304. package/dist/commands/validate/service/model/diverged.js.map +1 -0
  305. package/dist/commands/validate/service/model/grade.js +163 -0
  306. package/dist/commands/validate/service/model/grade.js.map +1 -0
  307. package/dist/commands/validate/service/service.js +310 -0
  308. package/dist/commands/validate/service/service.js.map +1 -0
  309. package/dist/commands/validate/service/specs.js +279 -0
  310. package/dist/commands/validate/service/specs.js.map +1 -0
  311. package/dist/commands/validate/service/spine.js +148 -0
  312. package/dist/commands/validate/service/spine.js.map +1 -0
  313. package/dist/commands/validate/service/usecases/tags.js +113 -0
  314. package/dist/commands/validate/service/usecases/tags.js.map +1 -0
  315. package/dist/commands/validate/service/usecases/usecases.js +209 -0
  316. package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
  317. package/dist/commands/validate/validate.js +363 -0
  318. package/dist/commands/validate/validate.js.map +1 -0
  319. package/dist/commands/verify/cross/diff.js +178 -0
  320. package/dist/commands/verify/cross/diff.js.map +1 -0
  321. package/dist/commands/verify/evidence/contract.js +32 -0
  322. package/dist/commands/verify/evidence/contract.js.map +1 -0
  323. package/dist/commands/verify/evidence/pins.js +52 -0
  324. package/dist/commands/verify/evidence/pins.js.map +1 -0
  325. package/dist/commands/verify/evidence/read.js +81 -0
  326. package/dist/commands/verify/evidence/read.js.map +1 -0
  327. package/dist/commands/verify/frozen.js +263 -0
  328. package/dist/commands/verify/frozen.js.map +1 -0
  329. package/dist/commands/verify/record.js +278 -0
  330. package/dist/commands/verify/record.js.map +1 -0
  331. package/dist/commands/verify/report.js +206 -0
  332. package/dist/commands/verify/report.js.map +1 -0
  333. package/dist/commands/verify/results.js +328 -0
  334. package/dist/commands/verify/results.js.map +1 -0
  335. package/dist/commands/verify/verify.js +220 -0
  336. package/dist/commands/verify/verify.js.map +1 -0
  337. package/dist/commands/vouch/contract.js +11 -0
  338. package/dist/commands/vouch/contract.js.map +1 -0
  339. package/dist/commands/vouch/pack/contract.js +2 -0
  340. package/dist/commands/vouch/pack/contract.js.map +1 -0
  341. package/dist/commands/vouch/pack/pack.js +266 -0
  342. package/dist/commands/vouch/pack/pack.js.map +1 -0
  343. package/dist/commands/vouch/pack/print.js +266 -0
  344. package/dist/commands/vouch/pack/print.js.map +1 -0
  345. package/dist/commands/vouch/pack/sections.js +141 -0
  346. package/dist/commands/vouch/pack/sections.js.map +1 -0
  347. package/dist/commands/vouch/prompt/confirm.js +46 -0
  348. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  349. package/dist/commands/vouch/report.js +101 -0
  350. package/dist/commands/vouch/report.js.map +1 -0
  351. package/dist/commands/vouch/run.js +230 -0
  352. package/dist/commands/vouch/run.js.map +1 -0
  353. package/dist/commands/vouch/sample/plan.js +111 -0
  354. package/dist/commands/vouch/sample/plan.js.map +1 -0
  355. package/dist/commands/vouch/sample/print.js +109 -0
  356. package/dist/commands/vouch/sample/print.js.map +1 -0
  357. package/dist/commands/vouch/vet/verify.js +155 -0
  358. package/dist/commands/vouch/vet/verify.js.map +1 -0
  359. package/dist/commands/vouch/vouch.js +169 -0
  360. package/dist/commands/vouch/vouch.js.map +1 -0
  361. package/dist/core/agent/agents-md/command-map.js +299 -0
  362. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  363. package/dist/core/agent/agents-md/map/explain.js +46 -0
  364. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  365. package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
  366. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  367. package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
  368. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  369. package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
  370. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  371. package/dist/core/agent/agents-md/map/mcp.js +44 -0
  372. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  373. package/dist/core/agent/agents-md/map/status.js +78 -0
  374. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  375. package/dist/core/agent/agents-md/map/subsystem.js +104 -0
  376. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  377. package/dist/core/agent/agents-md/map/usecases.js +138 -0
  378. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  379. package/dist/core/agent/agents-md/refusals.js +273 -0
  380. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  381. package/dist/core/agent/agents-md.js +203 -0
  382. package/dist/core/agent/agents-md.js.map +1 -0
  383. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
  384. package/dist/core/agent/agents-stamp.js.map +1 -0
  385. package/dist/core/agent/contract.js +2 -0
  386. package/dist/core/agent/contract.js.map +1 -0
  387. package/dist/core/agent/protocol.js +193 -0
  388. package/dist/core/agent/protocol.js.map +1 -0
  389. package/dist/core/agent/scaffold.js +254 -0
  390. package/dist/core/agent/scaffold.js.map +1 -0
  391. package/dist/core/agent/support/report.js +144 -0
  392. package/dist/core/agent/support/report.js.map +1 -0
  393. package/dist/core/agent/tools/dialects.js +151 -0
  394. package/dist/core/agent/tools/dialects.js.map +1 -0
  395. package/dist/core/agent/tools/registry.js +193 -0
  396. package/dist/core/agent/tools/registry.js.map +1 -0
  397. package/dist/core/agent/workflows/adopt.js +280 -0
  398. package/dist/core/agent/workflows/adopt.js.map +1 -0
  399. package/dist/core/agent/workflows/check.js +373 -0
  400. package/dist/core/agent/workflows/check.js.map +1 -0
  401. package/dist/core/agent/workflows/closing.js +323 -0
  402. package/dist/core/agent/workflows/closing.js.map +1 -0
  403. package/dist/core/agent/workflows/feature.js +220 -0
  404. package/dist/core/agent/workflows/feature.js.map +1 -0
  405. package/dist/core/agent/workflows/implement.js +188 -0
  406. package/dist/core/agent/workflows/implement.js.map +1 -0
  407. package/dist/core/agent/workflows/reference/authoring.js +311 -0
  408. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  409. package/dist/core/agent/workflows/reference/codes.js +67 -0
  410. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  411. package/dist/core/agent/workflows/reference/done-check.js +210 -0
  412. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  413. package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
  414. package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
  415. package/dist/core/agent/workflows/reference/reference.js +19 -0
  416. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  417. package/dist/core/agent/workflows/reference/spine.js +338 -0
  418. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  419. package/dist/core/asyncapi/baseline/plan.js +43 -0
  420. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  421. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  422. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  423. package/dist/core/asyncapi/depth.js +164 -0
  424. package/dist/core/asyncapi/depth.js.map +1 -0
  425. package/dist/core/asyncapi/digest.js +146 -0
  426. package/dist/core/asyncapi/digest.js.map +1 -0
  427. package/dist/core/asyncapi/merge/components.js +92 -0
  428. package/dist/core/asyncapi/merge/components.js.map +1 -0
  429. package/dist/core/asyncapi/merge/error.js +38 -0
  430. package/dist/core/asyncapi/merge/error.js.map +1 -0
  431. package/dist/core/asyncapi/merge/markers.js +290 -0
  432. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  433. package/dist/core/asyncapi/merge/merge.js +195 -0
  434. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  435. package/dist/core/asyncapi/merge/pin.js +83 -0
  436. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  437. package/dist/core/asyncapi/model.js +11 -0
  438. package/dist/core/asyncapi/model.js.map +1 -0
  439. package/dist/core/asyncapi/producers.js +50 -0
  440. package/dist/core/asyncapi/producers.js.map +1 -0
  441. package/dist/core/asyncapi/read.js +263 -0
  442. package/dist/core/asyncapi/read.js.map +1 -0
  443. package/dist/core/brief/brief.js +285 -0
  444. package/dist/core/brief/brief.js.map +1 -0
  445. package/dist/core/brief/checks.js +385 -0
  446. package/dist/core/brief/checks.js.map +1 -0
  447. package/dist/core/brief/landscape.js +273 -0
  448. package/dist/core/brief/landscape.js.map +1 -0
  449. package/dist/core/brief/map/extend.js +84 -0
  450. package/dist/core/brief/map/extend.js.map +1 -0
  451. package/dist/core/brief/map/owed.js +266 -0
  452. package/dist/core/brief/map/owed.js.map +1 -0
  453. package/dist/core/brief/targets.js +304 -0
  454. package/dist/core/brief/targets.js.map +1 -0
  455. package/dist/core/brief/unchecked.js +58 -0
  456. package/dist/core/brief/unchecked.js.map +1 -0
  457. package/dist/core/c4/arch.js +190 -0
  458. package/dist/core/c4/arch.js.map +1 -0
  459. package/dist/core/c4/direction/direction.js +114 -0
  460. package/dist/core/c4/direction/direction.js.map +1 -0
  461. package/dist/core/c4/likec4.js +243 -0
  462. package/dist/core/c4/likec4.js.map +1 -0
  463. package/dist/core/c4/locate/unlocated.js +150 -0
  464. package/dist/core/c4/locate/unlocated.js.map +1 -0
  465. package/dist/core/c4/parsed/deployment.js +160 -0
  466. package/dist/core/c4/parsed/deployment.js.map +1 -0
  467. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  468. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  469. package/dist/core/c4/parsed/specification.js +78 -0
  470. package/dist/core/c4/parsed/specification.js.map +1 -0
  471. package/dist/core/c4/parsed/values.js +110 -0
  472. package/dist/core/c4/parsed/values.js.map +1 -0
  473. package/dist/core/c4/parsed/view-ids.js +113 -0
  474. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  475. package/dist/core/c4/prefetch/fleet.js +134 -0
  476. package/dist/core/c4/prefetch/fleet.js.map +1 -0
  477. package/dist/core/c4/project/architecture.js +161 -0
  478. package/dist/core/c4/project/architecture.js.map +1 -0
  479. package/dist/core/c4/project/batch.js +140 -0
  480. package/dist/core/c4/project/batch.js.map +1 -0
  481. package/dist/core/c4/project/documents.js +89 -0
  482. package/dist/core/c4/project/documents.js.map +1 -0
  483. package/dist/core/c4/project/load.js +219 -0
  484. package/dist/core/c4/project/load.js.map +1 -0
  485. package/dist/core/c4/project/staged.js +277 -0
  486. package/dist/core/c4/project/staged.js.map +1 -0
  487. package/dist/core/c4/resolve/attested.js +0 -0
  488. package/dist/core/c4/resolve/attested.js.map +1 -0
  489. package/dist/core/c4/resolve/external.js +51 -0
  490. package/dist/core/c4/resolve/external.js.map +1 -0
  491. package/dist/core/c4/resolve/service.js +174 -0
  492. package/dist/core/c4/resolve/service.js.map +1 -0
  493. package/dist/core/c4/resolve/steps.js +290 -0
  494. package/dist/core/c4/resolve/steps.js.map +1 -0
  495. package/dist/core/c4/resolve/systems.js +154 -0
  496. package/dist/core/c4/resolve/systems.js.map +1 -0
  497. package/dist/core/c4/root-project/exclude.js +352 -0
  498. package/dist/core/c4/root-project/exclude.js.map +1 -0
  499. package/dist/core/c4/seed/fleet-file.js +201 -0
  500. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  501. package/dist/core/c4/seed/items.js +91 -0
  502. package/dist/core/c4/seed/items.js.map +1 -0
  503. package/dist/core/c4/seed/stamp.js +48 -0
  504. package/dist/core/c4/seed/stamp.js.map +1 -0
  505. package/dist/core/c4/seed/template.js +173 -0
  506. package/dist/core/c4/seed/template.js.map +1 -0
  507. package/dist/core/c4/service-model/created/models.js +96 -0
  508. package/dist/core/c4/service-model/created/models.js.map +1 -0
  509. package/dist/core/c4/service-model/documents.js +47 -0
  510. package/dist/core/c4/service-model/documents.js.map +1 -0
  511. package/dist/core/c4/service-model/fleet/extending.js +82 -0
  512. package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
  513. package/dist/core/c4/service-model/load.js +165 -0
  514. package/dist/core/c4/service-model/load.js.map +1 -0
  515. package/dist/core/c4/service-model/renderer.js +128 -0
  516. package/dist/core/c4/service-model/renderer.js.map +1 -0
  517. package/dist/core/c4/service-model/shape.js +106 -0
  518. package/dist/core/c4/service-model/shape.js.map +1 -0
  519. package/dist/core/c4/service-model/slice.js +188 -0
  520. package/dist/core/c4/service-model/slice.js.map +1 -0
  521. package/dist/core/c4/source-mask.js +369 -0
  522. package/dist/core/c4/source-mask.js.map +1 -0
  523. package/dist/core/c4/source-scan.js +308 -0
  524. package/dist/core/c4/source-scan.js.map +1 -0
  525. package/dist/core/c4/splice/authored-source.js +167 -0
  526. package/dist/core/c4/splice/authored-source.js.map +1 -0
  527. package/dist/core/c4/splice/contract.js +30 -0
  528. package/dist/core/c4/splice/contract.js.map +1 -0
  529. package/dist/core/c4/splice/delta-blocks.js +126 -0
  530. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  531. package/dist/core/c4/splice/identity/declared.js +87 -0
  532. package/dist/core/c4/splice/identity/declared.js.map +1 -0
  533. package/dist/core/c4/splice/identity/edges.js +73 -0
  534. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  535. package/dist/core/c4/splice/identity/existing.js +80 -0
  536. package/dist/core/c4/splice/identity/existing.js.map +1 -0
  537. package/dist/core/c4/splice/identity/interior.js +80 -0
  538. package/dist/core/c4/splice/identity/interior.js.map +1 -0
  539. package/dist/core/c4/splice/identity/owner.js +50 -0
  540. package/dist/core/c4/splice/identity/owner.js.map +1 -0
  541. package/dist/core/c4/splice/landscape-merge.js +337 -0
  542. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  543. package/dist/core/c4/splice/model/merge.js +151 -0
  544. package/dist/core/c4/splice/model/merge.js.map +1 -0
  545. package/dist/core/c4/splice/placement.js +298 -0
  546. package/dist/core/c4/splice/placement.js.map +1 -0
  547. package/dist/core/c4/splice/text/spot.js +131 -0
  548. package/dist/core/c4/splice/text/spot.js.map +1 -0
  549. package/dist/core/c4/workspace.js +166 -0
  550. package/dist/core/c4/workspace.js.map +1 -0
  551. package/dist/core/capabilities/authoring/notes.js +141 -0
  552. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  553. package/dist/core/capabilities/capabilities.js +124 -0
  554. package/dist/core/capabilities/capabilities.js.map +1 -0
  555. package/dist/core/capabilities/delta/doc.js +47 -0
  556. package/dist/core/capabilities/delta/doc.js.map +1 -0
  557. package/dist/core/capabilities/delta/overlay.js +129 -0
  558. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  559. package/dist/core/capabilities/delta/summary.js +57 -0
  560. package/dist/core/capabilities/delta/summary.js.map +1 -0
  561. package/dist/core/capabilities/delta/tree.js +43 -0
  562. package/dist/core/capabilities/delta/tree.js.map +1 -0
  563. package/dist/core/capabilities/delta/uncovered.js +222 -0
  564. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  565. package/dist/core/capabilities/findings.js +338 -0
  566. package/dist/core/capabilities/findings.js.map +1 -0
  567. package/dist/core/capabilities/realizes/findings.js +174 -0
  568. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  569. package/dist/core/capabilities/realizes/join.js +123 -0
  570. package/dist/core/capabilities/realizes/join.js.map +1 -0
  571. package/dist/core/capabilities/rollup.js +205 -0
  572. package/dist/core/capabilities/rollup.js.map +1 -0
  573. package/dist/core/capabilities/tree.js +104 -0
  574. package/dist/core/capabilities/tree.js.map +1 -0
  575. package/dist/core/capabilities/usecase-join.js +267 -0
  576. package/dist/core/capabilities/usecase-join.js.map +1 -0
  577. package/dist/core/coherence/authoring/scaffold.js +185 -0
  578. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  579. package/dist/core/coherence/authoring/sentinels.js +75 -0
  580. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  581. package/dist/core/coherence/calls/called.js +52 -0
  582. package/dist/core/coherence/calls/called.js.map +1 -0
  583. package/dist/core/coherence/coherence.js +332 -0
  584. package/dist/core/coherence/coherence.js.map +1 -0
  585. package/dist/core/coherence/consumed/operations.js +70 -0
  586. package/dist/core/coherence/consumed/operations.js.map +1 -0
  587. package/dist/core/coherence/consumed/refusal.js +38 -0
  588. package/dist/core/coherence/consumed/refusal.js.map +1 -0
  589. package/dist/core/coherence/covers/health.js +85 -0
  590. package/dist/core/coherence/covers/health.js.map +1 -0
  591. package/dist/core/coherence/declared.js +295 -0
  592. package/dist/core/coherence/declared.js.map +1 -0
  593. package/dist/core/coherence/events/declared.js +191 -0
  594. package/dist/core/coherence/events/declared.js.map +1 -0
  595. package/dist/core/coherence/events/events.js +335 -0
  596. package/dist/core/coherence/events/events.js.map +1 -0
  597. package/dist/core/coherence/events/grades.js +189 -0
  598. package/dist/core/coherence/events/grades.js.map +1 -0
  599. package/dist/core/coherence/events/lookups.js +63 -0
  600. package/dist/core/coherence/events/lookups.js.map +1 -0
  601. package/dist/core/coherence/events/produced.js +100 -0
  602. package/dist/core/coherence/events/produced.js.map +1 -0
  603. package/dist/core/coherence/living.js +198 -0
  604. package/dist/core/coherence/living.js.map +1 -0
  605. package/dist/core/coherence/lookups.js +95 -0
  606. package/dist/core/coherence/lookups.js.map +1 -0
  607. package/dist/core/coherence/pending.js +39 -0
  608. package/dist/core/coherence/pending.js.map +1 -0
  609. package/dist/core/coherence/retired/archived.js +285 -0
  610. package/dist/core/coherence/retired/archived.js.map +1 -0
  611. package/dist/core/coherence/retired/event-pair.js +62 -0
  612. package/dist/core/coherence/retired/event-pair.js.map +1 -0
  613. package/dist/core/coherence/retired/merged.js +79 -0
  614. package/dist/core/coherence/retired/merged.js.map +1 -0
  615. package/dist/core/coherence/retired/retirement.js +49 -0
  616. package/dist/core/coherence/retired/retirement.js.map +1 -0
  617. package/dist/core/coherence/retired/revival/arrivals.js +131 -0
  618. package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
  619. package/dist/core/coherence/retired/revival/revived.js +297 -0
  620. package/dist/core/coherence/retired/revival/revived.js.map +1 -0
  621. package/dist/core/conflict-markers.js +60 -0
  622. package/dist/core/conflict-markers.js.map +1 -0
  623. package/dist/core/consumers/after.js +113 -0
  624. package/dist/core/consumers/after.js.map +1 -0
  625. package/dist/core/consumers/consumers.js +296 -0
  626. package/dist/core/consumers/consumers.js.map +1 -0
  627. package/dist/core/consumers/current.js +211 -0
  628. package/dist/core/consumers/current.js.map +1 -0
  629. package/dist/core/consumers/scan.js +46 -0
  630. package/dist/core/consumers/scan.js.map +1 -0
  631. package/dist/core/consumers/state.js +27 -0
  632. package/dist/core/consumers/state.js.map +1 -0
  633. package/dist/core/delta/claims.js +73 -0
  634. package/dist/core/delta/claims.js.map +1 -0
  635. package/dist/core/delta/delta.js +341 -0
  636. package/dist/core/delta/delta.js.map +1 -0
  637. package/dist/core/delta/document.js +177 -0
  638. package/dist/core/delta/document.js.map +1 -0
  639. package/dist/core/delta/scope.js +48 -0
  640. package/dist/core/delta/scope.js.map +1 -0
  641. package/dist/core/delta/select.js +237 -0
  642. package/dist/core/delta/select.js.map +1 -0
  643. package/dist/core/dependencies/dependencies.js +141 -0
  644. package/dist/core/dependencies/dependencies.js.map +1 -0
  645. package/dist/core/dependencies/facts.js +165 -0
  646. package/dist/core/dependencies/facts.js.map +1 -0
  647. package/dist/core/dependencies/fanin.js +88 -0
  648. package/dist/core/dependencies/fanin.js.map +1 -0
  649. package/dist/core/dependencies/graph.js +106 -0
  650. package/dist/core/dependencies/graph.js.map +1 -0
  651. package/dist/core/deployment/delta.js +191 -0
  652. package/dist/core/deployment/delta.js.map +1 -0
  653. package/dist/core/deployment/objects.js +145 -0
  654. package/dist/core/deployment/objects.js.map +1 -0
  655. package/dist/core/diff/base-git.js +230 -0
  656. package/dist/core/diff/base-git.js.map +1 -0
  657. package/dist/core/diff/base-state.js +237 -0
  658. package/dist/core/diff/base-state.js.map +1 -0
  659. package/dist/core/diff/joins.js +136 -0
  660. package/dist/core/diff/joins.js.map +1 -0
  661. package/dist/core/diff/scope/changed-paths.js +204 -0
  662. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  663. package/dist/core/diff/scope/edges.js +82 -0
  664. package/dist/core/diff/scope/edges.js.map +1 -0
  665. package/dist/core/diff/semantic.js +312 -0
  666. package/dist/core/diff/semantic.js.map +1 -0
  667. package/dist/core/docs.js +37 -85
  668. package/dist/core/docs.js.map +1 -1
  669. package/dist/core/doctor/agents.js +238 -0
  670. package/dist/core/doctor/agents.js.map +1 -0
  671. package/dist/core/doctor/config.js +139 -0
  672. package/dist/core/doctor/config.js.map +1 -0
  673. package/dist/core/doctor/doctor.js +355 -0
  674. package/dist/core/doctor/doctor.js.map +1 -0
  675. package/dist/core/doctor/report.js +13 -0
  676. package/dist/core/doctor/report.js.map +1 -0
  677. package/dist/core/doctor/reports/scan.js +242 -0
  678. package/dist/core/doctor/reports/scan.js.map +1 -0
  679. package/dist/core/doctor/residue.js +110 -0
  680. package/dist/core/doctor/residue.js.map +1 -0
  681. package/dist/core/document/apply.js +224 -0
  682. package/dist/core/document/apply.js.map +1 -0
  683. package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
  684. package/dist/core/document/frontmatter.js.map +1 -0
  685. package/dist/core/document/grammar/directives.js +143 -0
  686. package/dist/core/document/grammar/directives.js.map +1 -0
  687. package/dist/core/document/parse.js +286 -0
  688. package/dist/core/document/parse.js.map +1 -0
  689. package/dist/core/document/scenarios.js +238 -0
  690. package/dist/core/document/scenarios.js.map +1 -0
  691. package/dist/core/document/spec.js +234 -0
  692. package/dist/core/document/spec.js.map +1 -0
  693. package/dist/core/{config.js → envelope/config.js} +89 -18
  694. package/dist/core/envelope/config.js.map +1 -0
  695. package/dist/core/envelope/json.js +209 -0
  696. package/dist/core/envelope/json.js.map +1 -0
  697. package/dist/core/{version.js → envelope/version.js} +3 -3
  698. package/dist/core/envelope/version.js.map +1 -0
  699. package/dist/core/explain/families.js +180 -0
  700. package/dist/core/explain/families.js.map +1 -0
  701. package/dist/core/explain/fix-tables.js +178 -0
  702. package/dist/core/explain/fix-tables.js.map +1 -0
  703. package/dist/core/explain/lookup.js +194 -0
  704. package/dist/core/explain/lookup.js.map +1 -0
  705. package/dist/core/explain/refusals.js +49 -0
  706. package/dist/core/explain/refusals.js.map +1 -0
  707. package/dist/core/explain/terms/documents.js +227 -0
  708. package/dist/core/explain/terms/documents.js.map +1 -0
  709. package/dist/core/explain/terms/done-check.js +144 -0
  710. package/dist/core/explain/terms/done-check.js.map +1 -0
  711. package/dist/core/explain/terms/entry.js +14 -0
  712. package/dist/core/explain/terms/entry.js.map +1 -0
  713. package/dist/core/explain/terms/stages.js +71 -0
  714. package/dist/core/explain/terms/stages.js.map +1 -0
  715. package/dist/core/explain/terms/tasks.js +97 -0
  716. package/dist/core/explain/terms/tasks.js.map +1 -0
  717. package/dist/core/explain/terms.js +103 -0
  718. package/dist/core/explain/terms.js.map +1 -0
  719. package/dist/core/explore/describe.js +105 -0
  720. package/dist/core/explore/describe.js.map +1 -0
  721. package/dist/core/explore/explore.js +204 -0
  722. package/dist/core/explore/explore.js.map +1 -0
  723. package/dist/core/fleet-context.js +174 -146
  724. package/dist/core/fleet-context.js.map +1 -1
  725. package/dist/core/gate/checks.js +208 -0
  726. package/dist/core/gate/checks.js.map +1 -0
  727. package/dist/core/gate/partners.js +246 -0
  728. package/dist/core/gate/partners.js.map +1 -0
  729. package/dist/core/gate/report.js +47 -0
  730. package/dist/core/gate/report.js.map +1 -0
  731. package/dist/core/gate/verification.js +176 -0
  732. package/dist/core/gate/verification.js.map +1 -0
  733. package/dist/core/gherkin/digest.js +60 -0
  734. package/dist/core/gherkin/digest.js.map +1 -0
  735. package/dist/core/gherkin/emit.js +177 -0
  736. package/dist/core/gherkin/emit.js.map +1 -0
  737. package/dist/core/gherkin/read.js +76 -0
  738. package/dist/core/gherkin/read.js.map +1 -0
  739. package/dist/core/gherkin/stale.js +210 -0
  740. package/dist/core/gherkin/stale.js.map +1 -0
  741. package/dist/core/gherkin/stamp.js +77 -0
  742. package/dist/core/gherkin/stamp.js.map +1 -0
  743. package/dist/core/gherkin/steps/catalogue.js +154 -0
  744. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  745. package/dist/core/gherkin/steps/inventory.js +98 -0
  746. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  747. package/dist/core/gherkin/steps/phrase.js +72 -0
  748. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  749. package/dist/core/glossary/delta.js +109 -0
  750. package/dist/core/glossary/delta.js.map +1 -0
  751. package/dist/core/glossary/tree.js +73 -0
  752. package/dist/core/glossary/tree.js.map +1 -0
  753. package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
  754. package/dist/core/kernel/concurrency.js.map +1 -0
  755. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  756. package/dist/core/kernel/document-bytes.js.map +1 -0
  757. package/dist/core/kernel/fences.js +42 -0
  758. package/dist/core/kernel/fences.js.map +1 -0
  759. package/dist/core/kernel/ids/capability.js +72 -0
  760. package/dist/core/kernel/ids/capability.js.map +1 -0
  761. package/dist/core/kernel/ids/dirs.js +33 -0
  762. package/dist/core/kernel/ids/dirs.js.map +1 -0
  763. package/dist/core/kernel/ids/feature.js +75 -0
  764. package/dist/core/kernel/ids/feature.js.map +1 -0
  765. package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
  766. package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
  767. package/dist/core/kernel/ids/service.js +156 -0
  768. package/dist/core/kernel/ids/service.js.map +1 -0
  769. package/dist/core/kernel/ids/subsystem.js +63 -0
  770. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  771. package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
  772. package/dist/core/kernel/path-safety.js.map +1 -0
  773. package/dist/core/{records.js → kernel/records.js} +11 -0
  774. package/dist/core/kernel/records.js.map +1 -0
  775. package/dist/core/links/backlinks.js +66 -0
  776. package/dist/core/links/backlinks.js.map +1 -0
  777. package/dist/core/links/case.js +74 -0
  778. package/dist/core/links/case.js.map +1 -0
  779. package/dist/core/links/corpus.js +118 -0
  780. package/dist/core/links/corpus.js.map +1 -0
  781. package/dist/core/links/findings.js +110 -0
  782. package/dist/core/links/findings.js.map +1 -0
  783. package/dist/core/links/parse.js +265 -0
  784. package/dist/core/links/parse.js.map +1 -0
  785. package/dist/core/mcp/argv.js +212 -0
  786. package/dist/core/mcp/argv.js.map +1 -0
  787. package/dist/core/mcp/author-tools.js +73 -0
  788. package/dist/core/mcp/author-tools.js.map +1 -0
  789. package/dist/core/mcp/framing.js +46 -0
  790. package/dist/core/mcp/framing.js.map +1 -0
  791. package/dist/core/mcp/protocol.js +280 -0
  792. package/dist/core/mcp/protocol.js.map +1 -0
  793. package/dist/core/mcp/tools.js +324 -0
  794. package/dist/core/mcp/tools.js.map +1 -0
  795. package/dist/core/obligations/obligations.js +106 -0
  796. package/dist/core/obligations/obligations.js.map +1 -0
  797. package/dist/core/openapi/baseline/gate.js +207 -0
  798. package/dist/core/openapi/baseline/gate.js.map +1 -0
  799. package/dist/core/openapi/baseline/plan.js +142 -0
  800. package/dist/core/openapi/baseline/plan.js.map +1 -0
  801. package/dist/core/openapi/baseline/record.js +174 -0
  802. package/dist/core/openapi/baseline/record.js.map +1 -0
  803. package/dist/core/openapi/contract-text.js +33 -0
  804. package/dist/core/openapi/contract-text.js.map +1 -0
  805. package/dist/core/openapi/contract-tree.js +301 -0
  806. package/dist/core/openapi/contract-tree.js.map +1 -0
  807. package/dist/core/openapi/depth.js +136 -0
  808. package/dist/core/openapi/depth.js.map +1 -0
  809. package/dist/core/openapi/digest.js +239 -0
  810. package/dist/core/openapi/digest.js.map +1 -0
  811. package/dist/core/{openapi.js → openapi/doc.js} +54 -108
  812. package/dist/core/openapi/doc.js.map +1 -0
  813. package/dist/core/openapi/merge/components.js +199 -0
  814. package/dist/core/openapi/merge/components.js.map +1 -0
  815. package/dist/core/openapi/merge/error.js +16 -0
  816. package/dist/core/openapi/merge/error.js.map +1 -0
  817. package/dist/core/openapi/merge/markers.js +204 -0
  818. package/dist/core/openapi/merge/markers.js.map +1 -0
  819. package/dist/core/openapi/merge/merge.js +232 -0
  820. package/dist/core/openapi/merge/merge.js.map +1 -0
  821. package/dist/core/openapi/merge/pin.js +110 -0
  822. package/dist/core/openapi/merge/pin.js.map +1 -0
  823. package/dist/core/openspec/decide/capabilities.js +244 -0
  824. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  825. package/dist/core/openspec/decide/dispositions.js +63 -0
  826. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  827. package/dist/core/openspec/decide/renames.js +179 -0
  828. package/dist/core/openspec/decide/renames.js.map +1 -0
  829. package/dist/core/openspec/decide/verdict.js +84 -0
  830. package/dist/core/openspec/decide/verdict.js.map +1 -0
  831. package/dist/core/openspec/inventory.js +220 -0
  832. package/dist/core/openspec/inventory.js.map +1 -0
  833. package/dist/core/openspec/model/mapping.js +78 -0
  834. package/dist/core/openspec/model/mapping.js.map +1 -0
  835. package/dist/core/openspec/model/model.js +70 -0
  836. package/dist/core/openspec/model/model.js.map +1 -0
  837. package/dist/core/openspec/scan/changes.js +241 -0
  838. package/dist/core/openspec/scan/changes.js.map +1 -0
  839. package/dist/core/openspec/scan/config.js +191 -0
  840. package/dist/core/openspec/scan/config.js.map +1 -0
  841. package/dist/core/openspec/scan/shape.js +304 -0
  842. package/dist/core/openspec/scan/shape.js.map +1 -0
  843. package/dist/core/openspec/scan/walk.js +116 -0
  844. package/dist/core/openspec/scan/walk.js.map +1 -0
  845. package/dist/core/openspec/scan/workspace.js +71 -0
  846. package/dist/core/openspec/scan/workspace.js.map +1 -0
  847. package/dist/core/owners/codeowners.js +141 -0
  848. package/dist/core/owners/codeowners.js.map +1 -0
  849. package/dist/core/pack/features.js +120 -0
  850. package/dist/core/pack/features.js.map +1 -0
  851. package/dist/core/pack/joins.js +112 -0
  852. package/dist/core/pack/joins.js.map +1 -0
  853. package/dist/core/pack/living.js +157 -0
  854. package/dist/core/pack/living.js.map +1 -0
  855. package/dist/core/pack/pack.js +120 -0
  856. package/dist/core/pack/pack.js.map +1 -0
  857. package/dist/core/permissions/permissions.js +87 -0
  858. package/dist/core/permissions/permissions.js.map +1 -0
  859. package/dist/core/projection/api.js +84 -0
  860. package/dist/core/projection/api.js.map +1 -0
  861. package/dist/core/projection/arch-slice.js +63 -0
  862. package/dist/core/projection/arch-slice.js.map +1 -0
  863. package/dist/core/projection/events.js +34 -0
  864. package/dist/core/projection/events.js.map +1 -0
  865. package/dist/core/projection/introduced.js +14 -0
  866. package/dist/core/projection/introduced.js.map +1 -0
  867. package/dist/core/provenance/findings.js +244 -0
  868. package/dist/core/provenance/findings.js.map +1 -0
  869. package/dist/core/provenance/git.js +201 -0
  870. package/dist/core/provenance/git.js.map +1 -0
  871. package/dist/core/provenance/gitq/moves.js +139 -0
  872. package/dist/core/provenance/gitq/moves.js.map +1 -0
  873. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  874. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  875. package/dist/core/provenance/sample/scope.js +238 -0
  876. package/dist/core/provenance/sample/scope.js.map +1 -0
  877. package/dist/core/provenance/sample/sections.js +61 -0
  878. package/dist/core/provenance/sample/sections.js.map +1 -0
  879. package/dist/core/provenance/sources.js +280 -0
  880. package/dist/core/provenance/sources.js.map +1 -0
  881. package/dist/core/provenance/stamp.js +220 -0
  882. package/dist/core/provenance/stamp.js.map +1 -0
  883. package/dist/core/provenance/walk.js +157 -0
  884. package/dist/core/provenance/walk.js.map +1 -0
  885. package/dist/core/repo/authored/paths.js +210 -0
  886. package/dist/core/repo/authored/paths.js.map +1 -0
  887. package/dist/core/repo/entries.js +126 -0
  888. package/dist/core/repo/entries.js.map +1 -0
  889. package/dist/core/repo/paths.js +322 -0
  890. package/dist/core/repo/paths.js.map +1 -0
  891. package/dist/core/repo/repo.js +308 -0
  892. package/dist/core/repo/repo.js.map +1 -0
  893. package/dist/core/repo/service-target.js +153 -0
  894. package/dist/core/repo/service-target.js.map +1 -0
  895. package/dist/core/repo/state.js +58 -0
  896. package/dist/core/repo/state.js.map +1 -0
  897. package/dist/core/repo/tree/find.js +61 -0
  898. package/dist/core/repo/tree/find.js.map +1 -0
  899. package/dist/core/repo/tree/fs.js +90 -0
  900. package/dist/core/repo/tree/fs.js.map +1 -0
  901. package/dist/core/repo/tree/marker.js +61 -0
  902. package/dist/core/repo/tree/marker.js.map +1 -0
  903. package/dist/core/repo/tree/render/body.js +258 -0
  904. package/dist/core/repo/tree/render/body.js.map +1 -0
  905. package/dist/core/repo/tree/render/projects.js +182 -0
  906. package/dist/core/repo/tree/render/projects.js.map +1 -0
  907. package/dist/core/repo/tree/render/service/header.js +125 -0
  908. package/dist/core/repo/tree/render/service/header.js.map +1 -0
  909. package/dist/core/repo/tree/render/service/peers.js +28 -0
  910. package/dist/core/repo/tree/render/service/peers.js.map +1 -0
  911. package/dist/core/repo/tree/render/service/view-id.js +67 -0
  912. package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
  913. package/dist/core/repo/tree/render/service/views.js +78 -0
  914. package/dist/core/repo/tree/render/service/views.js.map +1 -0
  915. package/dist/core/repo/tree/render/stale.js +42 -0
  916. package/dist/core/repo/tree/render/stale.js.map +1 -0
  917. package/dist/core/repo/tree/render/text.js +84 -0
  918. package/dist/core/repo/tree/render/text.js.map +1 -0
  919. package/dist/core/repo/tree/render/views.js +293 -0
  920. package/dist/core/repo/tree/render/views.js.map +1 -0
  921. package/dist/core/repo/tree/walk.js +255 -0
  922. package/dist/core/repo/tree/walk.js.map +1 -0
  923. package/dist/core/results.js +146 -14
  924. package/dist/core/results.js.map +1 -1
  925. package/dist/core/scaffold/landscape.js +239 -0
  926. package/dist/core/scaffold/landscape.js.map +1 -0
  927. package/dist/core/scaffold/legacy.js +271 -0
  928. package/dist/core/scaffold/legacy.js.map +1 -0
  929. package/dist/core/scaffold/readme.js +84 -0
  930. package/dist/core/scaffold/readme.js.map +1 -0
  931. package/dist/core/staging/commit.js +252 -0
  932. package/dist/core/staging/commit.js.map +1 -0
  933. package/dist/core/staging/interrupted.js +96 -0
  934. package/dist/core/staging/interrupted.js.map +1 -0
  935. package/dist/core/staging/lock.js +268 -0
  936. package/dist/core/staging/lock.js.map +1 -0
  937. package/dist/core/staging/recovery/finding.js +35 -0
  938. package/dist/core/staging/recovery/finding.js.map +1 -0
  939. package/dist/core/staging/recovery/intent.js +95 -0
  940. package/dist/core/staging/recovery/intent.js.map +1 -0
  941. package/dist/core/staging/recovery/recover.js +204 -0
  942. package/dist/core/staging/recovery/recover.js.map +1 -0
  943. package/dist/core/staging/recovery/residue.js +62 -0
  944. package/dist/core/staging/recovery/residue.js.map +1 -0
  945. package/dist/core/staging/snapshot/manifest.js +188 -0
  946. package/dist/core/staging/snapshot/manifest.js.map +1 -0
  947. package/dist/core/staging/snapshot/snapshot.js +196 -0
  948. package/dist/core/staging/snapshot/snapshot.js.map +1 -0
  949. package/dist/core/staging/txn/forward.js +181 -0
  950. package/dist/core/staging/txn/forward.js.map +1 -0
  951. package/dist/core/staging/txn/journal.js +139 -0
  952. package/dist/core/staging/txn/journal.js.map +1 -0
  953. package/dist/core/staging/txn/transaction.js +75 -0
  954. package/dist/core/staging/txn/transaction.js.map +1 -0
  955. package/dist/core/staging/writes.js +113 -0
  956. package/dist/core/staging/writes.js.map +1 -0
  957. package/dist/core/status/actions/execution.js +60 -0
  958. package/dist/core/status/actions/execution.js.map +1 -0
  959. package/dist/core/status/contracts.js +126 -0
  960. package/dist/core/status/contracts.js.map +1 -0
  961. package/dist/core/status/feature/artifacts.js +196 -0
  962. package/dist/core/status/feature/artifacts.js.map +1 -0
  963. package/dist/core/status/feature/feature.js +214 -0
  964. package/dist/core/status/feature/feature.js.map +1 -0
  965. package/dist/core/status/feature/next.js +163 -0
  966. package/dist/core/status/feature/next.js.map +1 -0
  967. package/dist/core/status/feature/state.js +21 -0
  968. package/dist/core/status/feature/state.js.map +1 -0
  969. package/dist/core/status/feature/words.js +96 -0
  970. package/dist/core/status/feature/words.js.map +1 -0
  971. package/dist/core/status/fleet/fleet.js +216 -0
  972. package/dist/core/status/fleet/fleet.js.map +1 -0
  973. package/dist/core/status/fleet/next.js +302 -0
  974. package/dist/core/status/fleet/next.js.map +1 -0
  975. package/dist/core/status/interrupted.js +97 -0
  976. package/dist/core/status/interrupted.js.map +1 -0
  977. package/dist/core/status/report.js +31 -0
  978. package/dist/core/status/report.js.map +1 -0
  979. package/dist/core/status/scan.js +41 -0
  980. package/dist/core/status/scan.js.map +1 -0
  981. package/dist/core/status/verification.js +216 -0
  982. package/dist/core/status/verification.js.map +1 -0
  983. package/dist/core/tasks/packet.js +199 -0
  984. package/dist/core/tasks/packet.js.map +1 -0
  985. package/dist/core/tasks/record.js +43 -0
  986. package/dist/core/tasks/record.js.map +1 -0
  987. package/dist/core/tasks/sources.js +181 -0
  988. package/dist/core/tasks/sources.js.map +1 -0
  989. package/dist/core/tasks/stamps.js +76 -0
  990. package/dist/core/tasks/stamps.js.map +1 -0
  991. package/dist/core/tasks/unit.js +0 -0
  992. package/dist/core/tasks/unit.js.map +1 -0
  993. package/dist/core/usecases/capability.js +166 -0
  994. package/dist/core/usecases/capability.js.map +1 -0
  995. package/dist/core/usecases/delta/claims.js +140 -0
  996. package/dist/core/usecases/delta/claims.js.map +1 -0
  997. package/dist/core/usecases/delta/flows.js +101 -0
  998. package/dist/core/usecases/delta/flows.js.map +1 -0
  999. package/dist/core/usecases/delta/modified.js +315 -0
  1000. package/dist/core/usecases/delta/modified.js.map +1 -0
  1001. package/dist/core/usecases/delta/overlay.js +76 -0
  1002. package/dist/core/usecases/delta/overlay.js.map +1 -0
  1003. package/dist/core/usecases/fleet.js +296 -0
  1004. package/dist/core/usecases/fleet.js.map +1 -0
  1005. package/dist/core/usecases/grade/capability-tag.js +93 -0
  1006. package/dist/core/usecases/grade/capability-tag.js.map +1 -0
  1007. package/dist/core/usecases/grade/feature.js +88 -0
  1008. package/dist/core/usecases/grade/feature.js.map +1 -0
  1009. package/dist/core/usecases/grade/requirement-tag.js +94 -0
  1010. package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
  1011. package/dist/core/usecases/grade/steps.js +266 -0
  1012. package/dist/core/usecases/grade/steps.js.map +1 -0
  1013. package/dist/core/usecases/grade/usecases.js +112 -0
  1014. package/dist/core/usecases/grade/usecases.js.map +1 -0
  1015. package/dist/core/usecases/operations.js +123 -0
  1016. package/dist/core/usecases/operations.js.map +1 -0
  1017. package/dist/core/usecases/place.js +44 -0
  1018. package/dist/core/usecases/place.js.map +1 -0
  1019. package/dist/core/usecases/service/exclude.js +119 -0
  1020. package/dist/core/usecases/service/exclude.js.map +1 -0
  1021. package/dist/core/usecases/service/flows.js +164 -0
  1022. package/dist/core/usecases/service/flows.js.map +1 -0
  1023. package/dist/core/usecases/suites/participants.js +83 -0
  1024. package/dist/core/usecases/suites/participants.js.map +1 -0
  1025. package/dist/core/usecases/suites/suites.js +45 -0
  1026. package/dist/core/usecases/suites/suites.js.map +1 -0
  1027. package/dist/core/usecases/touch.js +101 -0
  1028. package/dist/core/usecases/touch.js.map +1 -0
  1029. package/dist/core/verify/answers.js +180 -0
  1030. package/dist/core/verify/answers.js.map +1 -0
  1031. package/dist/core/verify/build.js +170 -0
  1032. package/dist/core/verify/build.js.map +1 -0
  1033. package/dist/core/verify/checklist.js +259 -0
  1034. package/dist/core/verify/checklist.js.map +1 -0
  1035. package/dist/core/verify/claims/identity.js +61 -0
  1036. package/dist/core/verify/claims/identity.js.map +1 -0
  1037. package/dist/core/verify/cross/diff.js +97 -0
  1038. package/dist/core/verify/cross/diff.js.map +1 -0
  1039. package/dist/core/verify/evidence/contract.js +169 -0
  1040. package/dist/core/verify/evidence/contract.js.map +1 -0
  1041. package/dist/core/verify/location.js +67 -0
  1042. package/dist/core/verify/location.js.map +1 -0
  1043. package/dist/core/verify/pins/lint.js +158 -0
  1044. package/dist/core/verify/pins/lint.js.map +1 -0
  1045. package/dist/core/verify/pins/pin.js +95 -0
  1046. package/dist/core/verify/pins/pin.js.map +1 -0
  1047. package/dist/core/verify/read/file.js +224 -0
  1048. package/dist/core/verify/read/file.js.map +1 -0
  1049. package/dist/core/verify/read/shape.js +169 -0
  1050. package/dist/core/verify/read/shape.js.map +1 -0
  1051. package/dist/core/verify/read/union.js +105 -0
  1052. package/dist/core/verify/read/union.js.map +1 -0
  1053. package/dist/core/verify/record.js +165 -0
  1054. package/dist/core/verify/record.js.map +1 -0
  1055. package/dist/core/verify/store/commit.js +99 -0
  1056. package/dist/core/verify/store/commit.js.map +1 -0
  1057. package/dist/core/verify/store/render.js +61 -0
  1058. package/dist/core/verify/store/render.js.map +1 -0
  1059. package/dist/core/vocabulary/health.js +91 -0
  1060. package/dist/core/vocabulary/health.js.map +1 -0
  1061. package/dist/core/vocabulary/issue.js +59 -0
  1062. package/dist/core/vocabulary/issue.js.map +1 -0
  1063. package/dist/core/vocabulary/maturity.js +216 -0
  1064. package/dist/core/vocabulary/maturity.js.map +1 -0
  1065. package/dist/core/vocabulary/report.js +90 -0
  1066. package/dist/core/vocabulary/report.js.map +1 -0
  1067. package/dist/core/vocabulary/steps.js +266 -0
  1068. package/dist/core/vocabulary/steps.js.map +1 -0
  1069. package/dist/core/workspace/discover.js +239 -0
  1070. package/dist/core/workspace/discover.js.map +1 -0
  1071. package/dist/core/workspace/render.js +52 -0
  1072. package/dist/core/workspace/render.js.map +1 -0
  1073. package/examples/README.md +232 -0
  1074. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  1075. package/examples/docs/architecture/capabilities.yaml +31 -0
  1076. package/examples/docs/architecture/landscape.likec4 +336 -0
  1077. package/examples/docs/architecture/obligations.yaml +23 -0
  1078. package/examples/docs/architecture/permissions.yaml +50 -0
  1079. package/examples/docs/architecture/services.likec4 +70 -0
  1080. package/examples/docs/architecture/subsystems.likec4 +18 -0
  1081. package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
  1082. package/examples/docs/capabilities/checkout/spec.md +55 -0
  1083. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  1084. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  1085. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  1086. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  1087. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  1088. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  1089. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
  1090. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  1091. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  1092. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  1093. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  1094. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  1095. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
  1096. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  1097. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  1098. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  1099. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  1100. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  1101. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  1102. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  1103. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  1104. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  1105. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  1106. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
  1107. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  1108. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  1109. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  1110. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  1111. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  1112. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  1113. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  1114. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  1115. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  1116. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  1117. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  1118. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  1119. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  1120. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  1121. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  1122. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  1123. package/examples/docs/glossary/order.md +15 -0
  1124. package/examples/docs/glossary/payments/authorization.md +14 -0
  1125. package/examples/docs/likec4.config.json +8 -0
  1126. package/examples/docs/loam.json +3 -0
  1127. package/examples/docs/services/checkout-web/model.likec4 +92 -0
  1128. package/examples/docs/services/checkout-web/spec.md +91 -0
  1129. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  1130. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  1131. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  1132. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  1133. package/examples/docs/services/order-service/arch.spec.md +134 -0
  1134. package/examples/docs/services/order-service/asyncapi.yaml +109 -0
  1135. package/examples/docs/services/order-service/health.yaml +57 -0
  1136. package/examples/docs/services/order-service/model.likec4 +126 -0
  1137. package/examples/docs/services/order-service/openapi.yaml +257 -0
  1138. package/examples/docs/services/order-service/runbook.md +62 -0
  1139. package/examples/docs/services/order-service/spec.md +134 -0
  1140. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  1141. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  1142. package/examples/docs/services/payment-service/arch.spec.md +76 -0
  1143. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  1144. package/examples/docs/services/payment-service/health.yaml +39 -0
  1145. package/examples/docs/services/payment-service/model.likec4 +68 -0
  1146. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  1147. package/examples/docs/services/payment-service/runbook.md +37 -0
  1148. package/examples/docs/services/payment-service/spec.md +88 -0
  1149. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  1150. package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
  1151. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  1152. package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
  1153. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  1154. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  1155. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  1156. package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
  1157. package/examples/docs/services/platform/notification-service/health.yaml +40 -0
  1158. package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
  1159. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  1160. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  1161. package/examples/docs/services/platform/subsystem.yaml +2 -0
  1162. package/examples/fleet.yaml +57 -0
  1163. package/package.json +19 -6
  1164. package/dist/commands/adopt.js +0 -240
  1165. package/dist/commands/adopt.js.map +0 -1
  1166. package/dist/commands/archive.js +0 -1313
  1167. package/dist/commands/archive.js.map +0 -1
  1168. package/dist/commands/delta.js +0 -388
  1169. package/dist/commands/delta.js.map +0 -1
  1170. package/dist/commands/docs-repo-gate.js.map +0 -1
  1171. package/dist/commands/format.js +0 -17
  1172. package/dist/commands/format.js.map +0 -1
  1173. package/dist/commands/gherkin.js +0 -309
  1174. package/dist/commands/gherkin.js.map +0 -1
  1175. package/dist/commands/init.js.map +0 -1
  1176. package/dist/commands/list.js +0 -295
  1177. package/dist/commands/list.js.map +0 -1
  1178. package/dist/commands/migrate-openspec.js +0 -950
  1179. package/dist/commands/migrate-openspec.js.map +0 -1
  1180. package/dist/commands/new.js +0 -413
  1181. package/dist/commands/new.js.map +0 -1
  1182. package/dist/commands/rebase.js +0 -356
  1183. package/dist/commands/rebase.js.map +0 -1
  1184. package/dist/commands/show.js +0 -320
  1185. package/dist/commands/show.js.map +0 -1
  1186. package/dist/commands/status.js +0 -262
  1187. package/dist/commands/status.js.map +0 -1
  1188. package/dist/commands/unarchive.js +0 -317
  1189. package/dist/commands/unarchive.js.map +0 -1
  1190. package/dist/commands/validate.js +0 -1773
  1191. package/dist/commands/validate.js.map +0 -1
  1192. package/dist/commands/verify.js +0 -775
  1193. package/dist/commands/verify.js.map +0 -1
  1194. package/dist/commands/vouch.js +0 -421
  1195. package/dist/commands/vouch.js.map +0 -1
  1196. package/dist/core/agent.js +0 -2173
  1197. package/dist/core/agent.js.map +0 -1
  1198. package/dist/core/agents-stamp.js.map +0 -1
  1199. package/dist/core/arch.js +0 -130
  1200. package/dist/core/arch.js.map +0 -1
  1201. package/dist/core/asyncapi.js +0 -253
  1202. package/dist/core/asyncapi.js.map +0 -1
  1203. package/dist/core/brief.js +0 -755
  1204. package/dist/core/brief.js.map +0 -1
  1205. package/dist/core/coherence.js +0 -577
  1206. package/dist/core/coherence.js.map +0 -1
  1207. package/dist/core/concurrency.js.map +0 -1
  1208. package/dist/core/config.js.map +0 -1
  1209. package/dist/core/delta.js +0 -476
  1210. package/dist/core/delta.js.map +0 -1
  1211. package/dist/core/dependencies.js +0 -356
  1212. package/dist/core/dependencies.js.map +0 -1
  1213. package/dist/core/doctor.js +0 -596
  1214. package/dist/core/doctor.js.map +0 -1
  1215. package/dist/core/document-bytes.js.map +0 -1
  1216. package/dist/core/explore.js +0 -225
  1217. package/dist/core/explore.js.map +0 -1
  1218. package/dist/core/frontmatter.js.map +0 -1
  1219. package/dist/core/gherkin.js +0 -463
  1220. package/dist/core/gherkin.js.map +0 -1
  1221. package/dist/core/health.js +0 -67
  1222. package/dist/core/health.js.map +0 -1
  1223. package/dist/core/ids.js +0 -122
  1224. package/dist/core/ids.js.map +0 -1
  1225. package/dist/core/issue.js +0 -9
  1226. package/dist/core/issue.js.map +0 -1
  1227. package/dist/core/json.js +0 -74
  1228. package/dist/core/json.js.map +0 -1
  1229. package/dist/core/likec4.js +0 -489
  1230. package/dist/core/likec4.js.map +0 -1
  1231. package/dist/core/maturity.js +0 -66
  1232. package/dist/core/maturity.js.map +0 -1
  1233. package/dist/core/openapi-merge.js +0 -552
  1234. package/dist/core/openapi-merge.js.map +0 -1
  1235. package/dist/core/openapi.js.map +0 -1
  1236. package/dist/core/openspec-inventory.js +0 -1440
  1237. package/dist/core/openspec-inventory.js.map +0 -1
  1238. package/dist/core/path-safety.js.map +0 -1
  1239. package/dist/core/provenance.js +0 -787
  1240. package/dist/core/provenance.js.map +0 -1
  1241. package/dist/core/records.js.map +0 -1
  1242. package/dist/core/repo.js +0 -438
  1243. package/dist/core/repo.js.map +0 -1
  1244. package/dist/core/report.js +0 -47
  1245. package/dist/core/report.js.map +0 -1
  1246. package/dist/core/spec.js +0 -505
  1247. package/dist/core/spec.js.map +0 -1
  1248. package/dist/core/staging.js +0 -890
  1249. package/dist/core/staging.js.map +0 -1
  1250. package/dist/core/status.js +0 -1132
  1251. package/dist/core/status.js.map +0 -1
  1252. package/dist/core/steps.js +0 -72
  1253. package/dist/core/steps.js.map +0 -1
  1254. package/dist/core/verify.js +0 -807
  1255. package/dist/core/verify.js.map +0 -1
  1256. package/dist/core/version.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../../../src/core/provenance/sample/scope.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What a SAMPLED vouch claims, how its sample is chosen, and how the claim is\n * written into the document beside `vouched_by`.\n *\n * `loam vouch --sample <n>` exists because the alternative to a partial read\n * is usually not a full read — it is no vouch at all, and a fleet of\n * unvouched drafts. So this deliberately REDUCES the assurance a stamp\n * carries, and every line here exists to make sure the reduction is visible:\n * the scope rides beside `status: verified` (never as a new status — that\n * string is frozen), it says k of n in the document itself, and it carries\n * the seed so anyone can recompute exactly which sections the person was\n * shown. A sampled vouch that could be mistaken for a full one would be worse\n * than no vouch, because it would spend the one signal loam has.\n *\n * The seed is derived from the document's OWN content and the digest of its\n * sources — never from the clock, a counter or a random number — for three\n * reasons, in order of how much they matter:\n *\n * 1. **Anyone can audit it.** The stamp records the seed, k and n; the\n * document records `content_digest` and `sources_digest`. A reviewer\n * recomputes `sampleSeed` from those three values and `pickSample` over\n * the body, and gets back the exact list the voucher was shown.\n * 2. **The pick cannot be re-rolled in place.** A random seed would let an\n * agent run the vouch — or `--pack --sample` — until the section it wrote\n * carelessly fell outside the sample, leaving no trace anywhere. Content\n * derivation makes every re-roll an EDIT to the document: recorded in the\n * docs repo's history, and moving `content_digest` under any stamp\n * already standing over it.\n * 3. **The same recipe answers before and after.** The pre-vouch reading\n * list, the prompt and `loam vouch --pack --sample` all call `planSample`\n * with the digests the stamp is about to carry, so the pack cannot\n * prescribe one sample while the stamp records another.\n *\n * Reproducibility rests on one property of the writer:\n * `withFrontmatterFields` leaves the body byte-identical, and `contentDigest`\n * hashes only the body — so `contentDigest(raw)` computed BEFORE the stamp\n * equals the `content_digest` the stamp writes. That is what lets the sample\n * be chosen (and shown to a person) before the value it is keyed to exists on\n * disk.\n *\n * What this does NOT do — and the difference is worth stating plainly, since\n * an overstated claim is worse than none — is make the sample UNPREDICTABLE.\n * The recipe is published (SCHEMA.md), so anybody holding the document can\n * compute the pick before anybody vouches: that IS reason 1, and the two\n * properties are in direct tension. An agent that wants a particular section\n * left out of the read can append a space and recompute until it is, at the\n * cost of one cosmetic edit per attempt in a version-controlled file,\n * immediately before asking a person to vouch. Auditability was chosen over\n * unpredictability deliberately — hiding the recipe needs a secret loam has\n * nowhere to keep, and a sample nobody can check is not evidence of anything.\n * What the design buys is that steering is neither free nor invisible: the\n * same bargain `sources_digest` strikes, which is a change detector and not a\n * seal.\n *\n * It also does not weight the sample. See `pickSample`.\n */\nimport { createHash } from \"node:crypto\";\nimport { stringField, type Frontmatter } from \"../../document/frontmatter.js\";\nimport { splitSections, type DocSection } from \"./sections.js\";\n\n/**\n * Hex characters kept from a sha256 — `provenance/stamp.ts`'s DIGEST_LENGTH,\n * respelled rather than imported because this is a seed and not a digest: the\n * two would be free to diverge, and importing would tie a sampling decision to\n * a change-detection budget. 64 bits is not a seal here either; an adversary\n * who wants a collision can have one, and the audit trail is the git history\n * of the docs repo, not this number.\n */\nconst SEED_LENGTH = 16;\n\n/** What a sampled vouch stamped: how many sections of how many, and the seed that chose them. */\nexport interface VouchScope {\n /** k — how many sections the person was shown and asked to read. */\n sections: number;\n /** n — how many the file had when they read it. Always greater than `sections`. */\n of: number;\n /** The seed, `SEED_LENGTH` lowercase hex characters. */\n seed: string;\n}\n\n/**\n * The seed for one spec-axis FILE: `sha256(service \\0 content_digest \\0\n * sources_digest)`, first 16 hex characters.\n *\n * Per file, not per service, because the two inputs are per-file stamps —\n * spec.md and arch.spec.md carry their own digests, so one `--sample 3` run\n * picks three sections of each from two different seeds. The service id is in\n * the hash so two services whose specs happen to be byte-identical (a\n * scaffold, a copy) do not get the same reading list.\n *\n * NUL separators, `sourcesDigest`'s own recipe: without them\n * `(\"ab\", \"c\")` and `(\"a\", \"bc\")` hash alike, and a service id may contain\n * dots and dashes.\n */\nexport function sampleSeed(service: string, contentDigest: string, sourcesDigest: string): string {\n return createHash(\"sha256\")\n .update(`${service}\\0${contentDigest}\\0${sourcesDigest}`)\n .digest(\"hex\")\n .slice(0, SEED_LENGTH);\n}\n\n/**\n * Pick `n` sections deterministically from `sections`, returned in DOCUMENT\n * order.\n *\n * Rank each section by `sha256(seed \\0 index \\0 heading)` and take the `n`\n * lowest ranks. Hash-ranking rather than a seeded PRNG: there is no PRNG in\n * the standard library, adding a dependency for one is a product decision this\n * repo has already made against, and a hash rank is recomputable one section\n * at a time by anybody with a shell. The index is in the rank so two sections\n * with identical heading text (a document with two `## Notes`) still rank\n * apart, and the index tiebreak below keeps the sort total.\n *\n * Document order on the way out, not rank order: the person is going to read\n * the file top to bottom, and a list that jumps around is a list they lose\n * their place in.\n *\n * **Uniform — the sample is NOT weighted by fan-in**, and that is a decision\n * rather than an omission. `core/dependencies/fanin.ts` counts how many\n * services depend on a SERVICE; nothing in loam says which consumer depends on\n * which SECTION, and the join that would (section -> `Operations:`/`Publishes:`\n * -> landscape edge -> caller) has three defects at this stakes. It is\n * derivable only for `### Requirement:` sections that carry those lines, so\n * every narrative section — `## Overview`, `## Interfaces`, the prose most\n * likely to be quietly false — would weight to zero and effectively stop being\n * sampled. It needs the fleet map and every sibling's contract, so a vouch in\n * a service repo would depend on documents it cannot see, and an unparseable\n * landscape would silently flatten the weights back to uniform without saying\n * so. And decisively: those inputs are documents an agent can edit, and they\n * are not covered by either digest in the seed — so weighting would hand back\n * exactly the steering that content-derived seeding exists to take away. The\n * parameter list has room for weights if a later version can answer those;\n * v1's answer is that an unweighted sample nobody can aim is worth more than a\n * weighted one somebody can.\n */\nexport function pickSample(sections: readonly DocSection[], n: number, seed: string): DocSection[] {\n return sections\n .map((section, index) => ({\n index,\n section,\n rank: createHash(\"sha256\").update(`${seed}\\0${index}\\0${section.heading}`).digest(\"hex\"),\n }))\n // Rank first, index second: sha256 makes a tie astronomically unlikely,\n // but \"unlikely\" is not \"total\", and an unstable sort over equal ranks\n // would make the pick depend on the engine's sort implementation — which\n // is exactly the reproducibility this whole module promises.\n .sort((a, b) => (a.rank < b.rank ? -1 : a.rank > b.rank ? 1 : a.index - b.index))\n .slice(0, n)\n .sort((a, b) => a.index - b.index)\n .map((ranked) => ranked.section);\n}\n\n/** One file's sampling inputs — the two digests its stamp will carry, its body, and k. */\nexport interface SampleInputs {\n service: string;\n /** As `content_digest` will read — `contentDigest(raw)`, which the stamp preserves. */\n contentDigest: string;\n /** As `sources_digest` will read. */\n sourcesDigest: string;\n /** The document BODY, below the frontmatter (`rawBody`). */\n body: string;\n /** How many sections to read — `--sample <n>`, a whole number of at least 1. */\n n: number;\n}\n\n/** What a sample comes to for one file: the seed, how many sections there were, and which were picked. */\nexport interface PlannedSample {\n seed: string;\n /** n — every section the body has. `picked` is all of them when `of <= n`. */\n of: number;\n picked: DocSection[];\n}\n\n/**\n * The whole per-file derivation in one call, so that the reading list, the\n * prompt, `--pack --sample` and the stamp cannot drift into prescribing\n * different samples of the same file. Every caller goes through here.\n *\n * A file with `of <= n` comes back with every section picked: the sample\n * covers the document, so the run is an ordinary full vouch and stamps no\n * scope at all. That case is decided by comparing `picked.length` with `of`,\n * one derivation rather than a boolean somebody has to keep true.\n */\nexport function planSample(req: SampleInputs): PlannedSample {\n const sections = splitSections(req.body);\n const seed = sampleSeed(req.service, req.contentDigest, req.sourcesDigest);\n return { seed, of: sections.length, picked: pickSample(sections, req.n, seed) };\n}\n\n/**\n * The `vouch_scope` value: `sampled 4/17 seed=1a2b3c4d5e6f7089`.\n *\n * One flat string rather than a nested YAML mapping, following the\n * `sources_files` precedent: `withFrontmatterFields` takes string values and\n * promises a byte-identical body, and a mapping value would put the writer in\n * the business of composing YAML structure inside somebody's header. It also\n * reads: a reviewer scanning a diff sees the whole claim on one line.\n */\nexport function encodeVouchScope(scope: VouchScope): string {\n return `sampled ${scope.sections}/${scope.of} seed=${scope.seed}`;\n}\n\n/** Exactly what `encodeVouchScope` writes, and nothing else. */\nconst SCOPE_RE = new RegExp(String.raw`^sampled (\\d+)\\/(\\d+) seed=([0-9a-f]{${SEED_LENGTH}})$`);\n\n/**\n * Read a stamped `vouch_scope` back, or null when it is not one this loam\n * wrote.\n *\n * Null means \"cannot be read\", NEVER \"is not sampled\" — the two are different\n * facts and every caller must keep them apart, which is what `isSampled`\n * below is for. A verified document carrying an unreadable scope is graded as\n * SAMPLED by `sources.sampled-vouch`, `loam list` and `loam show`: fail\n * closed, because the alternative is that mangling one field promotes a\n * partial read to a full one.\n */\nexport function decodeVouchScope(stamped: string | undefined): VouchScope | null {\n if (stamped === undefined) return null;\n const m = SCOPE_RE.exec(stamped.trim());\n if (m === null) return null;\n const scope = { sections: Number(m[1]!), of: Number(m[2]!), seed: m[3]! };\n // A claim that reads as covering everything is not a sample, and neither is\n // one that read nothing: both are shapes this writer never produces, so\n // treating them as decodable would let a hand-edited `sampled 17/17` grade\n // as a legible partial claim instead of an unreadable one.\n return scope.sections >= 1 && scope.sections < scope.of ? scope : null;\n}\n\n/**\n * What a document's `vouch_scope` says, as the ONE question every reader that\n * reports trust must ask.\n *\n * It takes the whole frontmatter rather than a field value because the test\n * that matters is KEY PRESENCE, and no field accessor can express it: a scope\n * written as a YAML mapping or sequence — a hand edit, a merge tool, an agent\n * \"tidying\" the header into something more legible — reads back from\n * `stringField` as `undefined`, exactly like an absent field, and grading that\n * as a FULL vouch is the promotion this vocabulary exists to prevent. Asking\n * it here, once, is what stops that hole being reopened one reader at a time:\n *\n * - `none` — the key is not there. The only reading that means a full vouch.\n * - `sampled` — a value this loam wrote, with the k/n and seed decoded.\n * - `unreadable` — the key is there and says something else. Graded sampled\n * by every caller, with `text` for display (null when the value is not even\n * a scalar, so there is nothing to quote).\n *\n * One hole remains and is not closable here: `vouch_scope:` with no value at\n * all is a key whose value is YAML null, which reads as PRESENT — and simply\n * deleting the line reads as absent, like every other hand-removed stamp. The\n * answer to that is the docs repo's git history, not this parser.\n */\nexport type ScopeStamp =\n | { kind: \"none\" }\n | { kind: \"sampled\"; scope: VouchScope; text: string }\n | { kind: \"unreadable\"; text: string | null };\n\nexport function readVouchScope(fm: Frontmatter): ScopeStamp {\n if (!Object.hasOwn(fm.data, \"vouch_scope\")) return { kind: \"none\" };\n const text = stringField(fm, \"vouch_scope\");\n if (text === undefined) return { kind: \"unreadable\", text: null };\n const scope = decodeVouchScope(text);\n return scope === null ? { kind: \"unreadable\", text } : { kind: \"sampled\", scope, text };\n}\n\n/**\n * The scope as a surface shows it: the stamped text, or — for a value that is\n * not even text — one fixed sentence, because what a reader must not be shown\n * for a present scope is nothing at all. Null means the key is absent, which\n * is the only state that reads as a full vouch.\n *\n * One spelling of the unreadable case, because `loam show` and the context\n * pack have to say the same thing about the same document.\n */\nexport function scopeText(fm: Frontmatter): string | null {\n const stamp = readVouchScope(fm);\n if (stamp.kind === \"none\") return null;\n if (stamp.kind === \"sampled\") return stamp.text;\n return stamp.text ?? \"present, but its value is not text — graded sampled\";\n}\n\n/**\n * Which sections a recorded scope actually covered, recomputed from its own\n * seed over the body it was taken over.\n *\n * This is the audit property in code: hand it the stamped scope and the body\n * that was vouched, get back the list the voucher was shown. The re-vouch\n * pack uses it to say which sections a previous sampled vouch READ, so the\n * ones it did not can be named as never-read rather than quietly counted as\n * covered.\n *\n * Null when the body no longer has the section count the scope names — the\n * body has changed, so the pick cannot be reproduced and no claim about what\n * was read is safe. Fail closed: an unreproducible sample licenses nothing.\n */\nexport function sampledSections(body: string, scope: VouchScope): DocSection[] | null {\n const sections = splitSections(body);\n if (sections.length !== scope.of) return null;\n return pickSample(sections, scope.sections, scope.seed);\n}\n"]}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * A spec body cut into the units a sampled vouch reads.
3
+ *
4
+ * The unit is a heading and the contiguous text under it, at H2 *and* H3, cut
5
+ * at the next heading of either level — leaf blocks, no overlap. H3 counts
6
+ * because of what a living spec actually looks like: `## Requirements` holds
7
+ * every `### Requirement:` in the document, so an H2-only cut offers a sample
8
+ * of four or five units, one of which is most of the file. "Read two of these
9
+ * nine" is only an honest reduction if the units are the size of a thing a
10
+ * person reads.
11
+ *
12
+ * The fence rule is `core/kernel/fences.ts`'s `fenceTracker`, imported rather
13
+ * than restated: a `## ` line inside a code block is prose about a heading, not
14
+ * structure, and a sampler that disagreed with `sectionHeadings` about that
15
+ * would prescribe sections no reader can find. It sat in `core/document/parse.ts`
16
+ * when this walk was its only borrower, and moved down to the kernel when a
17
+ * fourth reader needed it from a package `core/document/` already depends on. On the H2 subset
18
+ * this walk returns exactly what `sectionHeadings` returns — same test, same
19
+ * `line.trim()` spelling, same 1-based line — and test/vouch-sample.test.ts
20
+ * pins that agreement, because the reading list and the re-vouch pack's
21
+ * "already covered" list name headings to the same person.
22
+ *
23
+ * No BOM strip here: every caller hands in `rawBody(raw)`, which already drops
24
+ * a BOM above the frontmatter, and stripping again at position 0 of a *body*
25
+ * would eat an author's zero-width no-break space.
26
+ */
27
+ import { fenceTracker } from "../../kernel/fences.js";
28
+ /**
29
+ * Two or three `#` followed by whitespace. `####` and deeper cannot match at
30
+ * all — `#{2,3}` has nowhere to leave a space before the fourth `#` — which is
31
+ * how a `#### Scenario:` stays interior to the requirement it belongs to
32
+ * rather than becoming a unit of its own. `sectionHeadings` spells the H2 half
33
+ * of this as `/^##\s+/` plus a `###` exclusion; both accept the same lines,
34
+ * and the exclusion is why THIS pattern cannot be written that way: `^##\s+`
35
+ * never matches `### ` at all, because the character after `##` is a `#`.
36
+ * Getting that wrong is not a compile error, it is a splitter that silently
37
+ * drops every requirement in the document.
38
+ */
39
+ const HEADING_RE = /^(#{2,3})\s+/;
40
+ /**
41
+ * Every H2 and H3 heading outside a fenced block, in document order.
42
+ *
43
+ * The text above the first heading is deliberately not a unit: it has no
44
+ * heading to name it in a reading list, and it is short. The reading list
45
+ * says "read the preamble" outside the k/n count instead, so a sample is
46
+ * never the reason nobody read the opening paragraph.
47
+ */
48
+ export function splitSections(body) {
49
+ const fenced = fenceTracker();
50
+ const out = [];
51
+ body.split(/\r?\n/).forEach((line, i) => {
52
+ if (fenced(line))
53
+ return;
54
+ const m = HEADING_RE.exec(line);
55
+ if (m === null)
56
+ return;
57
+ out.push({ heading: line.trim(), level: m[1].length === 3 ? 3 : 2, line: i + 1 });
58
+ });
59
+ return out;
60
+ }
61
+ //# sourceMappingURL=sections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sections.js","sourceRoot":"","sources":["../../../../src/core/provenance/sample/sections.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAWtD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,GAAG,cAAc,CAAC;AAElC;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO;QACzB,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK,IAAI;YAAE,OAAO;QACvB,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/**\n * A spec body cut into the units a sampled vouch reads.\n *\n * The unit is a heading and the contiguous text under it, at H2 *and* H3, cut\n * at the next heading of either level — leaf blocks, no overlap. H3 counts\n * because of what a living spec actually looks like: `## Requirements` holds\n * every `### Requirement:` in the document, so an H2-only cut offers a sample\n * of four or five units, one of which is most of the file. \"Read two of these\n * nine\" is only an honest reduction if the units are the size of a thing a\n * person reads.\n *\n * The fence rule is `core/kernel/fences.ts`'s `fenceTracker`, imported rather\n * than restated: a `## ` line inside a code block is prose about a heading, not\n * structure, and a sampler that disagreed with `sectionHeadings` about that\n * would prescribe sections no reader can find. It sat in `core/document/parse.ts`\n * when this walk was its only borrower, and moved down to the kernel when a\n * fourth reader needed it from a package `core/document/` already depends on. On the H2 subset\n * this walk returns exactly what `sectionHeadings` returns — same test, same\n * `line.trim()` spelling, same 1-based line — and test/vouch-sample.test.ts\n * pins that agreement, because the reading list and the re-vouch pack's\n * \"already covered\" list name headings to the same person.\n *\n * No BOM strip here: every caller hands in `rawBody(raw)`, which already drops\n * a BOM above the frontmatter, and stripping again at position 0 of a *body*\n * would eat an author's zero-width no-break space.\n */\nimport { fenceTracker } from \"../../kernel/fences.js\";\n\n/** One sampling unit: the heading that names it, and where it starts. */\nexport interface DocSection {\n /** The heading line as the document spells it, trimmed — `sectionHeadings`' spelling. */\n heading: string;\n level: 2 | 3;\n /** 1-based, counted within the BODY that was passed — not the file. */\n line: number;\n}\n\n/**\n * Two or three `#` followed by whitespace. `####` and deeper cannot match at\n * all — `#{2,3}` has nowhere to leave a space before the fourth `#` — which is\n * how a `#### Scenario:` stays interior to the requirement it belongs to\n * rather than becoming a unit of its own. `sectionHeadings` spells the H2 half\n * of this as `/^##\\s+/` plus a `###` exclusion; both accept the same lines,\n * and the exclusion is why THIS pattern cannot be written that way: `^##\\s+`\n * never matches `### ` at all, because the character after `##` is a `#`.\n * Getting that wrong is not a compile error, it is a splitter that silently\n * drops every requirement in the document.\n */\nconst HEADING_RE = /^(#{2,3})\\s+/;\n\n/**\n * Every H2 and H3 heading outside a fenced block, in document order.\n *\n * The text above the first heading is deliberately not a unit: it has no\n * heading to name it in a reading list, and it is short. The reading list\n * says \"read the preamble\" outside the k/n count instead, so a sample is\n * never the reason nobody read the opening paragraph.\n */\nexport function splitSections(body: string): DocSection[] {\n const fenced = fenceTracker();\n const out: DocSection[] = [];\n body.split(/\\r?\\n/).forEach((line, i) => {\n if (fenced(line)) return;\n const m = HEADING_RE.exec(line);\n if (m === null) return;\n out.push({ heading: line.trim(), level: m[1]!.length === 3 ? 3 : 2, line: i + 1 });\n });\n return out;\n}\n"]}
@@ -0,0 +1,280 @@
1
+ /**
2
+ * The `sources` list: vetting the entries an author wrote — patterns, escapes,
3
+ * missing paths, the refusal vocabulary `loam vouch` and `loam validate` share
4
+ * — and grading the vetted list against the service repo: resolved, unvouched,
5
+ * current, stale, and whether the walk reached the whole repository. Vetting
6
+ * and grading are one doctrine about one field, so they live in one file.
7
+ */
8
+ import { existsSync } from "node:fs";
9
+ import { listField, stringField } from "../document/frontmatter.js";
10
+ import { resolveInside } from "../kernel/path-safety.js";
11
+ import { decodeSourceIndex, movedSources, sourcesDigest } from "./stamp.js";
12
+ import { gitTrackedFiles } from "./git.js";
13
+ export async function sourceFindings(fm, service, label, repo) {
14
+ const sources = listField(fm, "sources");
15
+ if (sources.length === 0) {
16
+ return [
17
+ {
18
+ severity: "warn",
19
+ code: "sources.absent",
20
+ message: `${label} names no sources — nothing ties it to the code, so nothing can tell you when it goes out of date`,
21
+ },
22
+ ];
23
+ }
24
+ // Someone else's repository: the paths describe a tree loam is not standing in.
25
+ if (repo === undefined)
26
+ return [];
27
+ const repoDir = repo.dir;
28
+ // Before existence: a pattern entry would "not exist" as a literal path, and
29
+ // grading it missing would send the author fixing the wrong thing.
30
+ const patterns = patternSources(sources);
31
+ if (patterns.length > 0) {
32
+ return [
33
+ {
34
+ severity: "error",
35
+ code: "sources.path-missing",
36
+ message: `${label}: ${patterns.length} source(s) are glob patterns — ${patterns.join(", ")}. Patterns are no longer supported: name files or directories (a directory already covers everything beneath it).`,
37
+ details: patterns,
38
+ text: { detailPrefix: "- " },
39
+ },
40
+ ];
41
+ }
42
+ const unsafe = unsafeSources(repoDir, sources);
43
+ if (unsafe.length > 0) {
44
+ return [
45
+ {
46
+ severity: "error",
47
+ code: "sources.path-outside",
48
+ message: `${label}: ${unsafe.length} source(s) escape the service repo — ${unsafe.join(", ")}. Sources must be relative paths contained by this repository, including through symlinks.`,
49
+ details: unsafe,
50
+ text: { detailPrefix: "- " },
51
+ },
52
+ ];
53
+ }
54
+ const missing = missingSources(repoDir, sources);
55
+ if (missing.length > 0) {
56
+ return [
57
+ {
58
+ severity: "error",
59
+ code: "sources.path-missing",
60
+ message: `${label}: ${missing.length} source(s) do not exist — ${missing.join(", ")}`,
61
+ details: missing,
62
+ text: { detailPrefix: "- " },
63
+ },
64
+ ];
65
+ }
66
+ const resolved = {
67
+ severity: "ok",
68
+ code: "sources.resolved",
69
+ message: `${label}: ${sources.length} source(s) resolve`,
70
+ };
71
+ // The walk happens here rather than inside the staleness branch below, even
72
+ // though only staleness needs the hashes: what the walk REFUSED to follow is
73
+ // a hole in the tie to the code whether or not anybody has vouched yet, and
74
+ // an unvouched service is exactly where a reader is about to decide the
75
+ // sources list is honest.
76
+ const { digest, files, index, skipped } = await sourcesDigest(repoDir, sources);
77
+ const findings = [
78
+ resolved,
79
+ ...skippedFindings(skipped, label),
80
+ ...(await walkFindings(repo, files, label)),
81
+ ];
82
+ // The paths are there; the question staleness answers is whether what is AT
83
+ // them is still what somebody read.
84
+ const stamped = stringField(fm, "sources_digest");
85
+ if (stamped === undefined) {
86
+ return [
87
+ ...findings,
88
+ {
89
+ severity: "warn",
90
+ code: "sources.unvouched",
91
+ message: `${label}: no sources_digest — nobody has vouched for this against the code, so nothing can tell you when it goes stale. Run \`loam vouch --service ${service}\`.`,
92
+ },
93
+ ];
94
+ }
95
+ const since = stringField(fm, "last_verified") ?? "it was stamped";
96
+ if (digest === stamped) {
97
+ return [
98
+ ...findings,
99
+ {
100
+ severity: "ok",
101
+ code: "sources.current",
102
+ message: `${label}: sources unchanged since ${since} (${files.length} file(s), digest ${digest})`,
103
+ },
104
+ ];
105
+ }
106
+ // What MOVED, when the stamp recorded enough to say. Repeating the frontmatter's
107
+ // own `sources` entries back at a reader — which is all this finding could do
108
+ // before `sources_files` existed — answers a question nobody asked: they wrote
109
+ // that list, and "one of these five directories changed somehow" is where the
110
+ // search starts, not where it ends.
111
+ const moved = movedSources(decodeSourceIndex(stringField(fm, "sources_files")), index);
112
+ return [
113
+ ...findings,
114
+ {
115
+ // A warning, not an error: the doc may still be right, and only a person
116
+ // can say. What loam knows is that nobody has looked since the code moved.
117
+ severity: "warn",
118
+ code: "sources.stale",
119
+ message: `${label}: sources changed since ${since}${moved.summary} — run \`loam vouch --pack --service ${service}\` for the reading list, then \`loam vouch --service ${service}\``,
120
+ details: moved.paths ?? sources,
121
+ text: { detailPrefix: "- " },
122
+ },
123
+ ];
124
+ }
125
+ /** The first path segment — the top-level directory, or a root file's own name. */
126
+ function topLevel(path) {
127
+ const cut = path.indexOf("/");
128
+ return cut === -1 ? path : path.slice(0, cut);
129
+ }
130
+ /**
131
+ * Was the service WALKED, or only the part somebody wrote about?
132
+ *
133
+ * Every other check loam owns is computed from the documents, so a corpus can
134
+ * agree with itself perfectly while describing a third of a service — the
135
+ * failure `UNCHECKED` names as COMPLETENESS and then, correctly, declines to
136
+ * grade. This is the one measurement that escapes that circle, because it
137
+ * compares the document's `sources` against the REPOSITORY: a top-level path
138
+ * git tracks and no source reaches into is a part of the service nobody opened.
139
+ *
140
+ * git is the denominator on purpose. The alternative is walking the tree and
141
+ * excluding what does not look like source, which means a hand-maintained list
142
+ * of build directories that is wrong for the first language nobody thought of —
143
+ * and a check that is wrong for a whole ecosystem is a warning that ecosystem
144
+ * learns to ignore. `git ls-files` already answers "what does this repository
145
+ * consider its own", it is the author's own answer, and `node_modules` and
146
+ * `target/` fall out of it for free. Where git cannot answer — not a
147
+ * repository, not installed, a timeout — there is no denominator and therefore
148
+ * no finding: proving nothing and saying nothing is the same doctrine
149
+ * `sources.unverifiable-from-here` follows.
150
+ *
151
+ * TOP-LEVEL granularity, not a percentage threshold. A ratio needs a line
152
+ * drawn somewhere, and an invented threshold is exactly the number this
153
+ * codebase refuses to write into other people's dashboards; a named directory
154
+ * needs no threshold and is answerable — either it holds nothing this document
155
+ * owes, and the hand-back says so in one sentence, or the walk stopped early.
156
+ * The ratio still rides along in the message as a dial, where it informs
157
+ * without grading.
158
+ *
159
+ * Two kinds of tracked file are NOT the service, and the denominator leaves
160
+ * them out — both by a rule that needs no list of what source looks like:
161
+ *
162
+ * - loam's OWN files: `loam.json` and the agent files `loam init` recorded in
163
+ * it (`SourcesRepo.loamOwned`). loam wrote them and knows they hold nothing
164
+ * a spec owes; counting them made the warning fire in every service repo
165
+ * straight after a fresh vouch, with no honest way to clear it — listing
166
+ * loam.json in `sources` would stale the digest on every `loam init`.
167
+ * - `.gitignore`, at any depth: it is the file that DEFINES this check's
168
+ * denominator — what git considers the repository's own — so it is the
169
+ * measuring instrument, not a part of the service anybody could owe a
170
+ * reading of. The line is deliberately that narrow: `package.json`, a
171
+ * README or `.github/` are the author's call (they can hold what a spec
172
+ * owes), so they stay in and are answered in the hand-back as before.
173
+ */
174
+ async function walkFindings(repo, covered, label) {
175
+ const owned = new Set(repo.loamOwned);
176
+ const tracked = (await gitTrackedFiles(repo.dir))?.filter((p) => !owned.has(p) && p !== ".gitignore" && !p.endsWith("/.gitignore"));
177
+ if (tracked === undefined || tracked.length === 0)
178
+ return [];
179
+ // The honest intersection, not "every file under a directory somebody
180
+ // touched": reading one file in src/ does not make the other four hundred
181
+ // read, and a coverage number that says it does is worse than none.
182
+ const coveredSet = new Set(covered);
183
+ const hit = tracked.filter((p) => coveredSet.has(p)).length;
184
+ const ratio = `${String(hit)} of ${String(tracked.length)} tracked file(s)`;
185
+ const touched = new Set(covered.map(topLevel));
186
+ const untouched = [...new Set(tracked.map(topLevel))].filter((t) => !touched.has(t)).sort();
187
+ if (untouched.length === 0) {
188
+ return [
189
+ {
190
+ severity: "ok",
191
+ code: "sources.walked",
192
+ message: `${label}: sources reach into every top-level path this repository tracks (${ratio})`,
193
+ },
194
+ ];
195
+ }
196
+ return [
197
+ {
198
+ severity: "warn",
199
+ code: "sources.unwalked",
200
+ message: `${label}: sources cover ${ratio}, and ${String(untouched.length)} top-level path(s) were never opened. ` +
201
+ `Either they hold nothing this document owes — say which, and why, in the hand-back — or the walk stopped early ` +
202
+ `and the baseline describes part of a service.`,
203
+ details: untouched,
204
+ text: { detailPrefix: "- " },
205
+ },
206
+ ];
207
+ }
208
+ /**
209
+ * The paths the digest walk would not follow. Never silent: a symlink dropped
210
+ * on the floor is a file whose content nobody is watching, while the document
211
+ * beside it says `verified` — the digest cannot go stale over bytes it never
212
+ * hashed, so the one thing the stamp promises is quietly untrue for them.
213
+ *
214
+ * A warning, not an error, and for the same reason staleness is: the doc may be
215
+ * perfectly right about the code behind that link. What loam can say is that it
216
+ * is not watching it.
217
+ */
218
+ function skippedFindings(skipped, label) {
219
+ if (skipped.length === 0)
220
+ return [];
221
+ return [
222
+ {
223
+ severity: "warn",
224
+ code: "sources.skipped",
225
+ message: `${label}: ${skipped.length} path(s) under the listed sources were not hashed — the digest says nothing about what is behind them`,
226
+ details: skipped.map((s) => `${s.path} — ${s.reason}`),
227
+ text: { detailPrefix: "- " },
228
+ },
229
+ ];
230
+ }
231
+ /** The characters that made an entry a pattern under the glob dialect loam no longer ships. */
232
+ const PATTERN_CHARS = /[*?[]/;
233
+ /**
234
+ * The `sources` entries that look like glob patterns — anything containing
235
+ * `*`, `?` or `[`. Patterns are refused loudly everywhere sources are consumed
236
+ * (`loam vouch` refuses the run, `loam validate` grades an error), never
237
+ * resolved: the glob dialect loam used to ship silently differed from the
238
+ * gitignore/minimatch conventions authors assume — bracket classes literal,
239
+ * its own `**` handling — so a pattern quietly digested a different file set
240
+ * than intended, corrupting the staleness signal in both directions. A
241
+ * directory already means "everything beneath it", so the fix is to name one.
242
+ *
243
+ * The cost accepted with the rule: a real file with `[` in its name (a Next.js
244
+ * route, say) cannot be listed on its own — its parent directory covers it.
245
+ */
246
+ export function patternSources(sources) {
247
+ return sources.filter((s) => PATTERN_CHARS.test(s.trim()));
248
+ }
249
+ /** The `sources` entries that resolve to nothing in this repo. */
250
+ export function missingSources(repoDir, sources) {
251
+ return sources.filter((s) => !sourceExists(repoDir, s));
252
+ }
253
+ /** Entries that are absolute, traverse upward, or escape through a symlink. */
254
+ export function unsafeSources(repoDir, sources) {
255
+ return sources.filter((source) => {
256
+ const cleaned = source.trim();
257
+ if (cleaned.length === 0)
258
+ return false;
259
+ try {
260
+ resolveInside(repoDir, cleaned, `source '${source}'`);
261
+ return false;
262
+ }
263
+ catch {
264
+ return true;
265
+ }
266
+ });
267
+ }
268
+ /** Does a `sources` entry point at something real? Literal paths only, checked exactly. */
269
+ function sourceExists(repoDir, source) {
270
+ const cleaned = source.trim();
271
+ if (cleaned.length === 0)
272
+ return false;
273
+ try {
274
+ return existsSync(resolveInside(repoDir, cleaned, `source '${source}'`));
275
+ }
276
+ catch {
277
+ return false;
278
+ }
279
+ }
280
+ //# sourceMappingURL=sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../../src/core/provenance/sources.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The `sources` list: vetting the entries an author wrote — patterns, escapes,\n * missing paths, the refusal vocabulary `loam vouch` and `loam validate` share\n * — and grading the vetted list against the service repo: resolved, unvouched,\n * current, stale, and whether the walk reached the whole repository. Vetting\n * and grading are one doctrine about one field, so they live in one file.\n */\nimport { existsSync } from \"node:fs\";\nimport { listField, stringField, type Frontmatter } from \"../document/frontmatter.js\";\nimport type { Finding } from \"../vocabulary/report.js\";\nimport { resolveInside } from \"../kernel/path-safety.js\";\nimport { decodeSourceIndex, movedSources, sourcesDigest } from \"./stamp.js\";\nimport type { SkippedSource } from \"./walk.js\";\nimport { gitTrackedFiles } from \"./git.js\";\n\n/**\n * The service repository `sources` resolve against, as the walk check needs\n * it: where it is, and which files in it are loam's own.\n */\nexport interface SourcesRepo {\n dir: string;\n /**\n * Repo-relative paths loam wrote and owns there — its `loam.json` and the\n * agent files `loam init` recorded in it. No `sources` list owes a reading of\n * them, so `walkFindings` leaves them out of its denominator.\n */\n loamOwned: readonly string[];\n}\n\nexport async function sourceFindings(\n fm: Frontmatter,\n service: string,\n label: string,\n repo: SourcesRepo | undefined,\n): Promise<Finding[]> {\n const sources = listField(fm, \"sources\");\n if (sources.length === 0) {\n return [\n {\n severity: \"warn\",\n code: \"sources.absent\",\n message: `${label} names no sources — nothing ties it to the code, so nothing can tell you when it goes out of date`,\n },\n ];\n }\n // Someone else's repository: the paths describe a tree loam is not standing in.\n if (repo === undefined) return [];\n const repoDir = repo.dir;\n\n // Before existence: a pattern entry would \"not exist\" as a literal path, and\n // grading it missing would send the author fixing the wrong thing.\n const patterns = patternSources(sources);\n if (patterns.length > 0) {\n return [\n {\n severity: \"error\",\n code: \"sources.path-missing\",\n message: `${label}: ${patterns.length} source(s) are glob patterns — ${patterns.join(\", \")}. Patterns are no longer supported: name files or directories (a directory already covers everything beneath it).`,\n details: patterns,\n text: { detailPrefix: \"- \" },\n },\n ];\n }\n\n const unsafe = unsafeSources(repoDir, sources);\n if (unsafe.length > 0) {\n return [\n {\n severity: \"error\",\n code: \"sources.path-outside\",\n message: `${label}: ${unsafe.length} source(s) escape the service repo — ${unsafe.join(\", \")}. Sources must be relative paths contained by this repository, including through symlinks.`,\n details: unsafe,\n text: { detailPrefix: \"- \" },\n },\n ];\n }\n\n const missing = missingSources(repoDir, sources);\n if (missing.length > 0) {\n return [\n {\n severity: \"error\",\n code: \"sources.path-missing\",\n message: `${label}: ${missing.length} source(s) do not exist — ${missing.join(\", \")}`,\n details: missing,\n text: { detailPrefix: \"- \" },\n },\n ];\n }\n const resolved: Finding = {\n severity: \"ok\",\n code: \"sources.resolved\",\n message: `${label}: ${sources.length} source(s) resolve`,\n };\n\n // The walk happens here rather than inside the staleness branch below, even\n // though only staleness needs the hashes: what the walk REFUSED to follow is\n // a hole in the tie to the code whether or not anybody has vouched yet, and\n // an unvouched service is exactly where a reader is about to decide the\n // sources list is honest.\n const { digest, files, index, skipped } = await sourcesDigest(repoDir, sources);\n const findings: Finding[] = [\n resolved,\n ...skippedFindings(skipped, label),\n ...(await walkFindings(repo, files, label)),\n ];\n\n // The paths are there; the question staleness answers is whether what is AT\n // them is still what somebody read.\n const stamped = stringField(fm, \"sources_digest\");\n if (stamped === undefined) {\n return [\n ...findings,\n {\n severity: \"warn\",\n code: \"sources.unvouched\",\n message: `${label}: no sources_digest — nobody has vouched for this against the code, so nothing can tell you when it goes stale. Run \\`loam vouch --service ${service}\\`.`,\n },\n ];\n }\n\n const since = stringField(fm, \"last_verified\") ?? \"it was stamped\";\n if (digest === stamped) {\n return [\n ...findings,\n {\n severity: \"ok\",\n code: \"sources.current\",\n message: `${label}: sources unchanged since ${since} (${files.length} file(s), digest ${digest})`,\n },\n ];\n }\n\n // What MOVED, when the stamp recorded enough to say. Repeating the frontmatter's\n // own `sources` entries back at a reader — which is all this finding could do\n // before `sources_files` existed — answers a question nobody asked: they wrote\n // that list, and \"one of these five directories changed somehow\" is where the\n // search starts, not where it ends.\n const moved = movedSources(decodeSourceIndex(stringField(fm, \"sources_files\")), index);\n return [\n ...findings,\n {\n // A warning, not an error: the doc may still be right, and only a person\n // can say. What loam knows is that nobody has looked since the code moved.\n severity: \"warn\",\n code: \"sources.stale\",\n message: `${label}: sources changed since ${since}${moved.summary} — run \\`loam vouch --pack --service ${service}\\` for the reading list, then \\`loam vouch --service ${service}\\``,\n details: moved.paths ?? sources,\n text: { detailPrefix: \"- \" },\n },\n ];\n}\n\n/** The first path segment — the top-level directory, or a root file's own name. */\nfunction topLevel(path: string): string {\n const cut = path.indexOf(\"/\");\n return cut === -1 ? path : path.slice(0, cut);\n}\n\n/**\n * Was the service WALKED, or only the part somebody wrote about?\n *\n * Every other check loam owns is computed from the documents, so a corpus can\n * agree with itself perfectly while describing a third of a service — the\n * failure `UNCHECKED` names as COMPLETENESS and then, correctly, declines to\n * grade. This is the one measurement that escapes that circle, because it\n * compares the document's `sources` against the REPOSITORY: a top-level path\n * git tracks and no source reaches into is a part of the service nobody opened.\n *\n * git is the denominator on purpose. The alternative is walking the tree and\n * excluding what does not look like source, which means a hand-maintained list\n * of build directories that is wrong for the first language nobody thought of —\n * and a check that is wrong for a whole ecosystem is a warning that ecosystem\n * learns to ignore. `git ls-files` already answers \"what does this repository\n * consider its own\", it is the author's own answer, and `node_modules` and\n * `target/` fall out of it for free. Where git cannot answer — not a\n * repository, not installed, a timeout — there is no denominator and therefore\n * no finding: proving nothing and saying nothing is the same doctrine\n * `sources.unverifiable-from-here` follows.\n *\n * TOP-LEVEL granularity, not a percentage threshold. A ratio needs a line\n * drawn somewhere, and an invented threshold is exactly the number this\n * codebase refuses to write into other people's dashboards; a named directory\n * needs no threshold and is answerable — either it holds nothing this document\n * owes, and the hand-back says so in one sentence, or the walk stopped early.\n * The ratio still rides along in the message as a dial, where it informs\n * without grading.\n *\n * Two kinds of tracked file are NOT the service, and the denominator leaves\n * them out — both by a rule that needs no list of what source looks like:\n *\n * - loam's OWN files: `loam.json` and the agent files `loam init` recorded in\n * it (`SourcesRepo.loamOwned`). loam wrote them and knows they hold nothing\n * a spec owes; counting them made the warning fire in every service repo\n * straight after a fresh vouch, with no honest way to clear it — listing\n * loam.json in `sources` would stale the digest on every `loam init`.\n * - `.gitignore`, at any depth: it is the file that DEFINES this check's\n * denominator — what git considers the repository's own — so it is the\n * measuring instrument, not a part of the service anybody could owe a\n * reading of. The line is deliberately that narrow: `package.json`, a\n * README or `.github/` are the author's call (they can hold what a spec\n * owes), so they stay in and are answered in the hand-back as before.\n */\nasync function walkFindings(repo: SourcesRepo, covered: string[], label: string): Promise<Finding[]> {\n const owned = new Set(repo.loamOwned);\n const tracked = (await gitTrackedFiles(repo.dir))?.filter(\n (p) => !owned.has(p) && p !== \".gitignore\" && !p.endsWith(\"/.gitignore\"),\n );\n if (tracked === undefined || tracked.length === 0) return [];\n\n // The honest intersection, not \"every file under a directory somebody\n // touched\": reading one file in src/ does not make the other four hundred\n // read, and a coverage number that says it does is worse than none.\n const coveredSet = new Set(covered);\n const hit = tracked.filter((p) => coveredSet.has(p)).length;\n const ratio = `${String(hit)} of ${String(tracked.length)} tracked file(s)`;\n\n const touched = new Set(covered.map(topLevel));\n const untouched = [...new Set(tracked.map(topLevel))].filter((t) => !touched.has(t)).sort();\n if (untouched.length === 0) {\n return [\n {\n severity: \"ok\",\n code: \"sources.walked\",\n message: `${label}: sources reach into every top-level path this repository tracks (${ratio})`,\n },\n ];\n }\n return [\n {\n severity: \"warn\",\n code: \"sources.unwalked\",\n message:\n `${label}: sources cover ${ratio}, and ${String(untouched.length)} top-level path(s) were never opened. ` +\n `Either they hold nothing this document owes — say which, and why, in the hand-back — or the walk stopped early ` +\n `and the baseline describes part of a service.`,\n details: untouched,\n text: { detailPrefix: \"- \" },\n },\n ];\n}\n\n/**\n * The paths the digest walk would not follow. Never silent: a symlink dropped\n * on the floor is a file whose content nobody is watching, while the document\n * beside it says `verified` — the digest cannot go stale over bytes it never\n * hashed, so the one thing the stamp promises is quietly untrue for them.\n *\n * A warning, not an error, and for the same reason staleness is: the doc may be\n * perfectly right about the code behind that link. What loam can say is that it\n * is not watching it.\n */\nfunction skippedFindings(skipped: SkippedSource[], label: string): Finding[] {\n if (skipped.length === 0) return [];\n return [\n {\n severity: \"warn\",\n code: \"sources.skipped\",\n message: `${label}: ${skipped.length} path(s) under the listed sources were not hashed — the digest says nothing about what is behind them`,\n details: skipped.map((s) => `${s.path} — ${s.reason}`),\n text: { detailPrefix: \"- \" },\n },\n ];\n}\n\n/** The characters that made an entry a pattern under the glob dialect loam no longer ships. */\nconst PATTERN_CHARS = /[*?[]/;\n\n/**\n * The `sources` entries that look like glob patterns — anything containing\n * `*`, `?` or `[`. Patterns are refused loudly everywhere sources are consumed\n * (`loam vouch` refuses the run, `loam validate` grades an error), never\n * resolved: the glob dialect loam used to ship silently differed from the\n * gitignore/minimatch conventions authors assume — bracket classes literal,\n * its own `**` handling — so a pattern quietly digested a different file set\n * than intended, corrupting the staleness signal in both directions. A\n * directory already means \"everything beneath it\", so the fix is to name one.\n *\n * The cost accepted with the rule: a real file with `[` in its name (a Next.js\n * route, say) cannot be listed on its own — its parent directory covers it.\n */\nexport function patternSources(sources: string[]): string[] {\n return sources.filter((s) => PATTERN_CHARS.test(s.trim()));\n}\n\n/** The `sources` entries that resolve to nothing in this repo. */\nexport function missingSources(repoDir: string, sources: string[]): string[] {\n return sources.filter((s) => !sourceExists(repoDir, s));\n}\n\n/** Entries that are absolute, traverse upward, or escape through a symlink. */\nexport function unsafeSources(repoDir: string, sources: string[]): string[] {\n return sources.filter((source) => {\n const cleaned = source.trim();\n if (cleaned.length === 0) return false;\n try {\n resolveInside(repoDir, cleaned, `source '${source}'`);\n return false;\n } catch {\n return true;\n }\n });\n}\n\n/** Does a `sources` entry point at something real? Literal paths only, checked exactly. */\nfunction sourceExists(repoDir: string, source: string): boolean {\n const cleaned = source.trim();\n if (cleaned.length === 0) return false;\n try {\n return existsSync(resolveInside(repoDir, cleaned, `source '${source}'`));\n } catch {\n return false;\n }\n}\n"]}