@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,363 @@
1
+ import { existsSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { agentsStaleFinding, binaryBehindFinding } from "../../core/agent/agents-stamp.js";
4
+ import { inOrder } from "../../core/kernel/concurrency.js";
5
+ import { resolveServiceTarget } from "../../core/repo/service-target.js";
6
+ import { loamOwnedFiles } from "../../core/envelope/config.js";
7
+ import { configOrRefuse, emitJson, fail, NO_SERVICE_MESSAGE } from "../../core/envelope/json.js";
8
+ import { DocsRepoUnavailableError } from "../../core/repo/state.js";
9
+ import { agentsPath as agentsFile, landscapePath as landscapeFile } from "../../core/repo/paths.js";
10
+ import { listFeatures, listServices, missingFeatureMessage, resolveFeature } from "../../core/repo/repo.js";
11
+ import { countSeverity, reportValid, targetJson } from "../../core/vocabulary/report.js";
12
+ import { LOAM_VERSION } from "../../core/envelope/version.js";
13
+ import { FleetContext } from "../../core/fleet-context.js";
14
+ import { fixesFor } from "../policy/format.js";
15
+ import { docsRepoReady, reportDocsRepoError, reportRepositoryUnavailable, } from "../policy/gate.js";
16
+ import { interruptedCommitFinding } from "../../core/staging/recovery/finding.js";
17
+ import { scopeJson, scopeLine, scopeSince } from "../../core/diff/scope/changed-paths.js";
18
+ import { validateLandscape } from "./fleet/landscape.js";
19
+ import { prefetchFleetDocuments, readLandscape } from "./fleet/load.js";
20
+ import { buildScorecard } from "./fleet/scorecard/scorecard.js";
21
+ import { printScorecard } from "./fleet/scorecard/print.js";
22
+ import { validateFeature } from "./feature.js";
23
+ import { validateService } from "./service/service.js";
24
+ import { scopedLandscapeFindings } from "./scope.js";
25
+ import { introducedBinding, introducedJson, introducedLead } from "./checks/introduced.js";
26
+ import { ambiguousTarget, capDetails, guarded, summary, unverifiableSubjects } from "./report.js";
27
+ import { renderText } from "./render/text.js";
28
+ export function registerValidate(program) {
29
+ program
30
+ .command("validate")
31
+ .argument("[target]", "service or feature id (a feature wins when both match; --service/--feature force the reading)")
32
+ .description("Validate a service (C4 + requirement coverage) or a feature (delta + coverage)")
33
+ .option("--service <id>", "service to validate (defaults to the configured service)")
34
+ .option("--feature <id>", "validate a feature delta instead of a service")
35
+ .option("--all", "validate every service and every active feature")
36
+ .option("--base <ref>", "with --all: grade only the targets changed since a base git ref of the docs repo — the adoption ratchet")
37
+ .option("--strict", "exit 1 on any warning too — a per-invocation CI lever; the report and --json payload do not change")
38
+ .option("--errors-only", "print only errors and warnings — a rendering lever; the --json payload does not change")
39
+ .option("--json", "emit the machine contract instead of the human view")
40
+ .action(async (target, opts) => {
41
+ const json = opts.json === true;
42
+ if (target !== undefined && (opts.all || opts.service || opts.feature)) {
43
+ fail(json, "invalid-option", `'${target}' already names the target; drop --all/--service/--feature.`);
44
+ return;
45
+ }
46
+ if (opts.all && (opts.service || opts.feature)) {
47
+ fail(json, "invalid-option", "--all validates everything; drop --service/--feature.");
48
+ return;
49
+ }
50
+ // Two targets is no target: silently validating only the feature taught
51
+ // callers that --service had been honoured when it had been dropped.
52
+ if (opts.service && opts.feature) {
53
+ fail(json, "invalid-option", "--service and --feature name different targets; pass one or the other.");
54
+ return;
55
+ }
56
+ // `--base` NARROWS a whole-fleet run; it does not name one. Beside a
57
+ // positional, `--service` or `--feature` it is a scope over a scope — a
58
+ // contradiction rather than a narrowing, whose "this service if it
59
+ // changed" reading nobody could tell apart from a green over a service
60
+ // never looked at. `--base` and not `--since`: `--base <ref>` is already
61
+ // loam's word for a base git ref of the docs repo on diff and vouch.
62
+ if (opts.base !== undefined && opts.all !== true) {
63
+ fail(json, "invalid-option", target !== undefined || opts.service || opts.feature
64
+ ? "--base narrows --all to what changed since a ref; a named target is already a scope. Pass one or the other."
65
+ : "--base narrows --all to what changed since a ref — pass --all with it.");
66
+ return;
67
+ }
68
+ const config = await configOrRefuse(json);
69
+ if (config === null)
70
+ return;
71
+ const { docsDir } = config;
72
+ // Before anything is enumerated: a docsDir that is not a docs repo must
73
+ // refuse, not report an empty fleet. See docsRepoReady. `--feature` is the
74
+ // one mode that never enumerates services, so it asks for less.
75
+ if (!docsRepoReady(json, docsDir, opts.feature ? "docs" : "services"))
76
+ return;
77
+ // One invocation, one filesystem snapshot. Nothing is global: a later
78
+ // command gets a fresh index and therefore cannot observe stale files.
79
+ const fleet = new FleetContext();
80
+ // `sources` are paths into a service's own repository, so they only mean
81
+ // something when loam is standing in that repository — which is exactly
82
+ // what loam.json's `service` records.
83
+ const repoOf = (service) => config.service === service ? process.cwd() : undefined;
84
+ // What loam itself wrote into that repository, which no `sources` list owes a reading of.
85
+ const loamOwned = loamOwnedFiles(config);
86
+ /**
87
+ * One service target, from a name the enumeration or the grammar approved.
88
+ * `land` is --all's landscape, read once for the whole run and handed to
89
+ * the service. Null is PASSED — it means "there is no landscape file" —
90
+ * so the test is `=== undefined`, never truthiness: a repo with no
91
+ * landscape would otherwise re-load per service and double-report.
92
+ *
93
+ * `landscapeReported` says whether this run ALSO emits a landscape target
94
+ * to carry the map's parse errors, and it is the caller's to state: a
95
+ * preloaded map does not imply one. It used to be read off `land`, and
96
+ * under `--base` the landscape is a target only when the branch changed
97
+ * `architecture/` — so a broken committed map and a branch touching only
98
+ * a service told that service "reported once, on the landscape target"
99
+ * with no details, and the parser output was reported nowhere.
100
+ */
101
+ const serviceTarget = (id, land, landscapeReported = false) => guarded({ kind: "service", id }, docsDir, () => validateService({
102
+ docsDir, service: id, repoDir: repoOf(id), loamOwned, gherkinDir: config.gherkinDir, contracts: config.contracts, fleet,
103
+ ...(land === undefined ? {} : { preloaded: land }),
104
+ landscapeReported,
105
+ }));
106
+ /** One feature target; `land` as above, and left undefined it means "load it if you need it". */
107
+ const featureTarget = (feature, land) => guarded({ kind: "feature", id: feature.id }, docsDir, () => validateFeature(docsDir, feature, land, fleet));
108
+ const targets = [];
109
+ /** What the positional argument turned out to name, for the JSON payload. */
110
+ let resolvedKind;
111
+ /** The `--base` narrowing, once it is known. Null on every unscoped run — including every run without --base. */
112
+ let scope = null;
113
+ /** The features a bare run validated in place of a bound service they introduce. Null on every other run. */
114
+ let introduced = null;
115
+ try {
116
+ if (opts.all) {
117
+ // ONE workspace per document kind for the whole run — the block moved
118
+ // to `fleet/load.ts` (`prefetchFleetDocuments`), which is where the
119
+ // rule about which shape parses in which workspace belongs.
120
+ const lp = landscapeFile(docsDir);
121
+ const enumerated = await listServices(docsDir, fleet);
122
+ const active = await listFeatures(docsDir, {}, fleet);
123
+ // `--base` narrows the enumerations and nothing else: a kept target is
124
+ // graded by exactly the checks `--all` would have run on it, at the
125
+ // same severities, through the same `--strict`. It matches through the
126
+ // ENUMERATIONS' own directories — changed-paths.ts says why a split
127
+ // on "/" silently drops every filed service.
128
+ if (opts.base !== undefined) {
129
+ const narrowed = await scopeSince({ docsDir, ref: opts.base, services: enumerated, features: active });
130
+ if (narrowed.kind === "refused") {
131
+ fail(json, narrowed.code, narrowed.message);
132
+ return;
133
+ }
134
+ scope = narrowed;
135
+ }
136
+ const services = scope === null ? enumerated : scope.services;
137
+ const features = scope === null ? active : scope.features;
138
+ await prefetchFleetDocuments({ docsDir, fleet, services, features });
139
+ // Read whether or not the landscape is a TARGET: every service check
140
+ // below joins against it, so a scoped run needs the map in hand even
141
+ // when it does not grade the map itself. Through the fleet index, so
142
+ // the single-service path — which now reads the same project — answers
143
+ // out of the same memo rather than parsing it a second time.
144
+ const land = existsSync(lp) ? await readLandscape(() => fleet.architecture(docsDir)) : null;
145
+ // The fleet-level cross-check first: it frames everything below it, and a
146
+ // service nobody drew is worth knowing before its own findings scroll past.
147
+ // Under `--base` it is a target only when `architecture/` changed — the
148
+ // landscape owns no service directory, so that is its whole footprint —
149
+ // and even then not whole: `scope.ts` drops what grades a file the
150
+ // branch left alone and adds the call edges it wrote.
151
+ const landscapeIsTarget = scope === null || scope.landscape;
152
+ if (landscapeIsTarget) {
153
+ const landscape = await validateLandscape(docsDir, land, fleet);
154
+ targets.push(landscape);
155
+ // The agent contract check, --all only: AGENTS.md is written once and
156
+ // never refreshed (the ownership contract), so the one thing the
157
+ // docs-repo-wide mode owes it is detection — a stamp older than the
158
+ // binary means agents are branching on tables the binary no longer
159
+ // honours. It grades the repo, not any service, so it rides on the
160
+ // landscape target.
161
+ const agentsPath = agentsFile(docsDir);
162
+ const agentsText = existsSync(agentsPath) ? await readFile(agentsPath, "utf8") : null;
163
+ const agents = agentsStaleFinding(agentsText, LOAM_VERSION);
164
+ if (agents !== null)
165
+ landscape.findings.push(agents);
166
+ // The other direction, and the one that changes what a PASS means:
167
+ // this binary predates the corpus, so a directive it cannot parse is
168
+ // read as prose and produces no join to fail.
169
+ const behind = binaryBehindFinding(agentsText, LOAM_VERSION);
170
+ if (behind !== null)
171
+ landscape.findings.push(behind);
172
+ if (scope !== null) {
173
+ landscape.findings = await scopedLandscapeFindings(landscape.findings, {
174
+ docsDir, scope, land, services: enumerated, fleet,
175
+ });
176
+ }
177
+ }
178
+ targets.push(...(await inOrder(services, (svc) => serviceTarget(svc.id, land, landscapeIsTarget))));
179
+ targets.push(...(await inOrder(features, (feat) => featureTarget(feat, land))));
180
+ }
181
+ else if (opts.feature) {
182
+ const feature = await resolveFeature(docsDir, opts.feature, "exclude", fleet);
183
+ if (!feature) {
184
+ fail(json, "unknown-target", await missingFeatureMessage(docsDir, opts.feature, fleet));
185
+ return;
186
+ }
187
+ targets.push(await featureTarget(feature));
188
+ }
189
+ else if (target !== undefined) {
190
+ // The positional reads the way `show` reads one: try the feature first
191
+ // (ids like FEAT-101 are distinctive, service names are arbitrary), then
192
+ // the service. --service/--feature stay as the explicit spellings for a
193
+ // name that could be both — and when both readings exist, the run says
194
+ // so out loud instead of silently taking one (`target.ambiguous`).
195
+ const feature = await resolveFeature(docsDir, target, "exclude", fleet);
196
+ const isService = (await listServices(docsDir, fleet)).some((s) => s.id === target);
197
+ if (feature) {
198
+ resolvedKind = "feature";
199
+ const report = await featureTarget(feature);
200
+ if (isService)
201
+ report.findings.unshift(ambiguousTarget(target, "feature"));
202
+ targets.push(report);
203
+ }
204
+ else {
205
+ // Neither reading exists. An archived feature is its own diagnosis
206
+ // ("already archived", not "no such thing"); anything else reads as a
207
+ // service, so the did-you-mean hints in service.unknown fire.
208
+ if (!isService && (await resolveFeature(docsDir, target, "only", fleet)) !== null) {
209
+ fail(json, "unknown-target", await missingFeatureMessage(docsDir, target, fleet));
210
+ return;
211
+ }
212
+ resolvedKind = "service";
213
+ const resolved = await resolveServiceTarget(docsDir, target, "target", fleet);
214
+ if (!resolved.ok)
215
+ return fail(json, "invalid-option", resolved.problem);
216
+ targets.push(await serviceTarget(resolved.id));
217
+ }
218
+ }
219
+ else {
220
+ const service = opts.service ?? config.service;
221
+ if (!service)
222
+ return fail(json, "invalid-option", NO_SERVICE_MESSAGE);
223
+ const resolved = await resolveServiceTarget(docsDir, service, "--service", fleet);
224
+ if (!resolved.ok)
225
+ return fail(json, "invalid-option", resolved.problem);
226
+ // A bound service a feature in flight introduces has no services/ directory yet, so its documents are
227
+ // validated where they are — the binding's reading only, since `--service` forces a service target.
228
+ introduced = opts.service === undefined ? await introducedBinding(docsDir, resolved, fleet) : null;
229
+ if (introduced === null)
230
+ targets.push(await serviceTarget(resolved.id));
231
+ else
232
+ targets.push(...(await inOrder(introduced.features, (feat) => featureTarget(feat))));
233
+ }
234
+ }
235
+ catch (err) {
236
+ // The docs repo went away between the gate above and the enumeration.
237
+ if (err instanceof DocsRepoUnavailableError) {
238
+ reportDocsRepoError(json, err);
239
+ return;
240
+ }
241
+ // An IO failure that `guarded` could not localise to one target — it
242
+ // happened in the ENUMERATION, which reads every living spec's
243
+ // frontmatter to build the service list. There is no partial report to
244
+ // give: without the list, no service was checked, including the ones
245
+ // that are fine. Say which file, and refuse; the one thing that must
246
+ // not happen is a stack trace on stdout's sibling stream and an
247
+ // `internal` envelope that names nothing.
248
+ reportRepositoryUnavailable(json, err, "the service list itself is unknown and nothing was validated", docsDir);
249
+ return;
250
+ }
251
+ // By subject, not by finding — the rule lives with the rollup in report.ts.
252
+ const unverifiable = unverifiableSubjects(targets);
253
+ // A journal in the repo outranks everything graded above: the docs may
254
+ // be half-merged, and in CI a green over them merges. Led, not appended
255
+ // — it is the reason nothing below can be trusted — and attached to the
256
+ // first target because a finding lives in one. `lead` keeps it leading
257
+ // in the fleet report too, which orders targets by kind rather than by
258
+ // position (render/text.ts) and would otherwise print it wherever the
259
+ // first target landed.
260
+ const interrupted = await interruptedCommitFinding(docsDir);
261
+ if (interrupted !== null && targets.length > 0) {
262
+ targets[0].findings.unshift({ ...interrupted, text: { ...interrupted.text, lead: true } });
263
+ }
264
+ // The fleet scorecard, --all only: recomputed per invocation off the same
265
+ // memoized reads this run already made — loam stores no history — and it
266
+ // fails closed per axis, never whole (fleet/scorecard/scorecard.ts).
267
+ //
268
+ // Suppressed under `--base`: its denominators are the graded targets, so
269
+ // over a narrowed set it reads "2 of 2 services documented" for a fleet
270
+ // where ten more are not — and its axes license report.ts's grouping,
271
+ // which would drop real warnings because an unlooked-at axis reads zero.
272
+ const scorecard = opts.all && scope === null
273
+ ? await buildScorecard({ docsDir, targets, fleet, boundService: config.service })
274
+ : null;
275
+ const valid = reportValid(targets);
276
+ const capped = targets.map(capDetails);
277
+ // One rollup for both views: the --json summary and the text footer
278
+ // print this object, never a count of their own.
279
+ const totals = summary(targets);
280
+ if (json) {
281
+ emitJson({
282
+ command: "validate",
283
+ valid,
284
+ summary: totals,
285
+ ...(resolvedKind === undefined ? {} : { resolvedKind }),
286
+ // What this run looked at. Only under `--base`, so an unscoped payload
287
+ // is today's document and its ABSENCE says `summary` counts the whole
288
+ // fleet — scopeJson has why a scoped one may not stay silent.
289
+ ...(scope === null ? {} : { scope: scopeJson(scope) }),
290
+ // Only when a bare run validated the features introducing the bound service: why `targets` holds no service.
291
+ ...(introduced === null ? {} : { boundService: introducedJson(introduced) }),
292
+ // Emitted in every mode now that it is derived per service: a
293
+ // single-service run knows exactly as much about its own blind spot
294
+ // as `--all` knows about the fleet's.
295
+ sourcesUnverifiableFromHere: unverifiable,
296
+ ...(scorecard === null ? {} : { scorecard }),
297
+ // What to do about every code this run raised — the one thing the
298
+ // payload could not previously answer. `validate` is step 1 of every
299
+ // generated protocol and the command an agent reads first, and until
300
+ // now it replied in prose: a finding names a code and says what is
301
+ // wrong, and nothing in it said that `loam explain <code>` knows what
302
+ // to do next.
303
+ //
304
+ // A top-level MAP, not a field on each finding, for the reason
305
+ // report.ts's DETAIL_LIMIT gives about evidence: a hundred-service
306
+ // fleet raising one code a hundred times would ship the same
307
+ // sentence a hundred times, in the interface an agent pipes into a
308
+ // context window. The consumer joins `findings[].code` to
309
+ // `fixes[code]` — one lookup, no round trip, no repetition.
310
+ //
311
+ // Keyed ONLY by codes a non-`ok` finding raised. A confirmation has
312
+ // nothing to fix, and on a clean fleet the `ok` codes are the
313
+ // overwhelming majority of findings; attaching fixes to them would
314
+ // pay the whole vocabulary's byte cost to tell a reader that nothing
315
+ // is wrong. `targets` is read here rather than `capped` because
316
+ // capping truncates evidence, not findings — the two raise the same
317
+ // codes, and reading the uncapped set keeps this rollup computed off
318
+ // the same targets as `summary()`.
319
+ //
320
+ // Not behind a flag, deliberately. It is additive, so no consumer
321
+ // that ignores it is affected; it is small, because it carries only
322
+ // the handful of codes this run actually raised rather than the
323
+ // 227-row vocabulary; and a flag would mean an agent has to already
324
+ // know the fixes exist in order to ask for them — which is the exact
325
+ // gap being closed. It is emitted on a green run too, as `{}`, so a
326
+ // consumer never has to branch on the key's presence before looking
327
+ // a code up in it.
328
+ fixes: fixesFor(targets.flatMap((t) => t.findings.filter((f) => f.severity !== "ok").map((f) => f.code))),
329
+ targets: capped.map(targetJson),
330
+ });
331
+ }
332
+ else {
333
+ // The scope FIRST: a reader has to know what the report below is a
334
+ // report ABOUT, and in the zero-target case there is nothing below at
335
+ // all — printed after the findings, the one run that most needs words
336
+ // would read as a green over the whole system.
337
+ if (scope !== null)
338
+ console.log(scopeLine(scope));
339
+ // First for the same reason: what follows is a feature's report, not the service's.
340
+ if (introduced !== null)
341
+ console.log(`${introducedLead(introduced).join("\n")}\n`);
342
+ renderText(capped, {
343
+ all: opts.all === true,
344
+ errorsOnly: opts.errorsOnly === true,
345
+ summary: totals,
346
+ unverifiable,
347
+ scorecard,
348
+ });
349
+ if (scorecard !== null)
350
+ printScorecard(scorecard);
351
+ }
352
+ // --strict is a per-invocation CI lever: it fails the run on any error or
353
+ // warning (ok-severity confirmations never trip it — virtually every
354
+ // clean target emits some), and changes nothing else — `valid` keeps meaning "no
355
+ // errors" in text and JSON alike, so two pipelines reading the same repo
356
+ // may grade the same report differently and both are telling the truth.
357
+ const strictFailed = opts.strict === true &&
358
+ countSeverity(targets, "error") + countSeverity(targets, "warn") > 0;
359
+ if (!valid || strictFailed)
360
+ process.exitCode = 1;
361
+ });
362
+ }
363
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/commands/validate/validate.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loam validate` — argument grammar, target selection, and the run's one\n * filesystem snapshot.\n *\n * The checks themselves live beside it, one module per target kind\n * (`landscape.ts`, `service/`, `feature/`) over the document checks they share\n * (`requirements.ts`). Every one of them produces findings and none of them\n * print: printing is `report.ts`'s, and it happens once, after the last target\n * is graded.\n */\nimport type { Command } from \"commander\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { agentsStaleFinding, binaryBehindFinding } from \"../../core/agent/agents-stamp.js\";\nimport { inOrder } from \"../../core/kernel/concurrency.js\";\nimport type { RawServiceId } from \"../../core/kernel/ids/service.js\";\nimport { resolveServiceTarget } from \"../../core/repo/service-target.js\";\nimport type { LoadedDoc } from \"../../core/c4/likec4.js\";\nimport type { FeatureEntry } from \"../../core/repo/entries.js\";\nimport { loamOwnedFiles } from \"../../core/envelope/config.js\";\nimport { configOrRefuse, emitJson, fail, NO_SERVICE_MESSAGE } from \"../../core/envelope/json.js\";\nimport { DocsRepoUnavailableError } from \"../../core/repo/state.js\";\nimport { agentsPath as agentsFile, landscapePath as landscapeFile } from \"../../core/repo/paths.js\";\nimport { listFeatures, listServices, missingFeatureMessage, resolveFeature } from \"../../core/repo/repo.js\";\nimport { countSeverity, reportValid, targetJson, type TargetReport } from \"../../core/vocabulary/report.js\";\nimport { LOAM_VERSION } from \"../../core/envelope/version.js\";\nimport { FleetContext } from \"../../core/fleet-context.js\";\nimport { fixesFor } from \"../policy/format.js\";\nimport {\n docsRepoReady,\n reportDocsRepoError,\n reportRepositoryUnavailable,\n} from \"../policy/gate.js\";\nimport { interruptedCommitFinding } from \"../../core/staging/recovery/finding.js\";\nimport { scopeJson, scopeLine, scopeSince, type ValidateScope } from \"../../core/diff/scope/changed-paths.js\";\nimport { validateLandscape } from \"./fleet/landscape.js\";\nimport { prefetchFleetDocuments, readLandscape } from \"./fleet/load.js\";\nimport { buildScorecard } from \"./fleet/scorecard/scorecard.js\";\nimport { printScorecard } from \"./fleet/scorecard/print.js\";\nimport { validateFeature } from \"./feature.js\";\nimport { validateService } from \"./service/service.js\";\nimport { scopedLandscapeFindings } from \"./scope.js\";\nimport { introducedBinding, introducedJson, introducedLead, type IntroducedBinding } from \"./checks/introduced.js\";\nimport { ambiguousTarget, capDetails, guarded, summary, unverifiableSubjects } from \"./report.js\";\nimport { renderText } from \"./render/text.js\";\n\ninterface ValidateOptions {\n service?: string;\n feature?: string;\n all?: boolean;\n base?: string;\n strict?: boolean;\n errorsOnly?: boolean;\n json?: boolean;\n}\n\nexport function registerValidate(program: Command): void {\n program\n .command(\"validate\")\n .argument(\"[target]\", \"service or feature id (a feature wins when both match; --service/--feature force the reading)\")\n .description(\"Validate a service (C4 + requirement coverage) or a feature (delta + coverage)\")\n .option(\"--service <id>\", \"service to validate (defaults to the configured service)\")\n .option(\"--feature <id>\", \"validate a feature delta instead of a service\")\n .option(\"--all\", \"validate every service and every active feature\")\n .option(\"--base <ref>\", \"with --all: grade only the targets changed since a base git ref of the docs repo — the adoption ratchet\")\n .option(\"--strict\", \"exit 1 on any warning too — a per-invocation CI lever; the report and --json payload do not change\")\n .option(\"--errors-only\", \"print only errors and warnings — a rendering lever; the --json payload does not change\")\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .action(async (target: string | undefined, opts: ValidateOptions) => {\n const json = opts.json === true;\n\n if (target !== undefined && (opts.all || opts.service || opts.feature)) {\n fail(json, \"invalid-option\", `'${target}' already names the target; drop --all/--service/--feature.`);\n return;\n }\n if (opts.all && (opts.service || opts.feature)) {\n fail(json, \"invalid-option\", \"--all validates everything; drop --service/--feature.\");\n return;\n }\n // Two targets is no target: silently validating only the feature taught\n // callers that --service had been honoured when it had been dropped.\n if (opts.service && opts.feature) {\n fail(json, \"invalid-option\", \"--service and --feature name different targets; pass one or the other.\");\n return;\n }\n // `--base` NARROWS a whole-fleet run; it does not name one. Beside a\n // positional, `--service` or `--feature` it is a scope over a scope — a\n // contradiction rather than a narrowing, whose \"this service if it\n // changed\" reading nobody could tell apart from a green over a service\n // never looked at. `--base` and not `--since`: `--base <ref>` is already\n // loam's word for a base git ref of the docs repo on diff and vouch.\n if (opts.base !== undefined && opts.all !== true) {\n fail(\n json,\n \"invalid-option\",\n target !== undefined || opts.service || opts.feature\n ? \"--base narrows --all to what changed since a ref; a named target is already a scope. Pass one or the other.\"\n : \"--base narrows --all to what changed since a ref — pass --all with it.\",\n );\n return;\n }\n\n const config = await configOrRefuse(json);\n if (config === null) return;\n const { docsDir } = config;\n // Before anything is enumerated: a docsDir that is not a docs repo must\n // refuse, not report an empty fleet. See docsRepoReady. `--feature` is the\n // one mode that never enumerates services, so it asks for less.\n if (!docsRepoReady(json, docsDir, opts.feature ? \"docs\" : \"services\")) return;\n // One invocation, one filesystem snapshot. Nothing is global: a later\n // command gets a fresh index and therefore cannot observe stale files.\n const fleet = new FleetContext();\n\n // `sources` are paths into a service's own repository, so they only mean\n // something when loam is standing in that repository — which is exactly\n // what loam.json's `service` records.\n const repoOf = (service: string): string | undefined =>\n config.service === service ? process.cwd() : undefined;\n // What loam itself wrote into that repository, which no `sources` list owes a reading of.\n const loamOwned = loamOwnedFiles(config);\n\n /**\n * One service target, from a name the enumeration or the grammar approved.\n * `land` is --all's landscape, read once for the whole run and handed to\n * the service. Null is PASSED — it means \"there is no landscape file\" —\n * so the test is `=== undefined`, never truthiness: a repo with no\n * landscape would otherwise re-load per service and double-report.\n *\n * `landscapeReported` says whether this run ALSO emits a landscape target\n * to carry the map's parse errors, and it is the caller's to state: a\n * preloaded map does not imply one. It used to be read off `land`, and\n * under `--base` the landscape is a target only when the branch changed\n * `architecture/` — so a broken committed map and a branch touching only\n * a service told that service \"reported once, on the landscape target\"\n * with no details, and the parser output was reported nowhere.\n */\n const serviceTarget = (id: RawServiceId, land?: LoadedDoc | null, landscapeReported = false): Promise<TargetReport> =>\n guarded({ kind: \"service\", id }, docsDir, () =>\n validateService({\n docsDir, service: id, repoDir: repoOf(id), loamOwned, gherkinDir: config.gherkinDir, contracts: config.contracts, fleet,\n ...(land === undefined ? {} : { preloaded: land }),\n landscapeReported,\n }),\n );\n /** One feature target; `land` as above, and left undefined it means \"load it if you need it\". */\n const featureTarget = (feature: FeatureEntry, land?: LoadedDoc | null): Promise<TargetReport> =>\n guarded({ kind: \"feature\", id: feature.id }, docsDir, () => validateFeature(docsDir, feature, land, fleet));\n\n const targets: TargetReport[] = [];\n /** What the positional argument turned out to name, for the JSON payload. */\n let resolvedKind: \"service\" | \"feature\" | undefined;\n /** The `--base` narrowing, once it is known. Null on every unscoped run — including every run without --base. */\n let scope: ValidateScope | null = null;\n /** The features a bare run validated in place of a bound service they introduce. Null on every other run. */\n let introduced: IntroducedBinding | null = null;\n\n try {\n if (opts.all) {\n // ONE workspace per document kind for the whole run — the block moved\n // to `fleet/load.ts` (`prefetchFleetDocuments`), which is where the\n // rule about which shape parses in which workspace belongs.\n const lp = landscapeFile(docsDir);\n const enumerated = await listServices(docsDir, fleet);\n const active = await listFeatures(docsDir, {}, fleet);\n // `--base` narrows the enumerations and nothing else: a kept target is\n // graded by exactly the checks `--all` would have run on it, at the\n // same severities, through the same `--strict`. It matches through the\n // ENUMERATIONS' own directories — changed-paths.ts says why a split\n // on \"/\" silently drops every filed service.\n if (opts.base !== undefined) {\n const narrowed = await scopeSince({ docsDir, ref: opts.base, services: enumerated, features: active });\n if (narrowed.kind === \"refused\") {\n fail(json, narrowed.code, narrowed.message);\n return;\n }\n scope = narrowed;\n }\n const services = scope === null ? enumerated : scope.services;\n const features = scope === null ? active : scope.features;\n await prefetchFleetDocuments({ docsDir, fleet, services, features });\n // Read whether or not the landscape is a TARGET: every service check\n // below joins against it, so a scoped run needs the map in hand even\n // when it does not grade the map itself. Through the fleet index, so\n // the single-service path — which now reads the same project — answers\n // out of the same memo rather than parsing it a second time.\n const land = existsSync(lp) ? await readLandscape(() => fleet.architecture(docsDir)) : null;\n // The fleet-level cross-check first: it frames everything below it, and a\n // service nobody drew is worth knowing before its own findings scroll past.\n // Under `--base` it is a target only when `architecture/` changed — the\n // landscape owns no service directory, so that is its whole footprint —\n // and even then not whole: `scope.ts` drops what grades a file the\n // branch left alone and adds the call edges it wrote.\n const landscapeIsTarget = scope === null || scope.landscape;\n if (landscapeIsTarget) {\n const landscape = await validateLandscape(docsDir, land, fleet);\n targets.push(landscape);\n // The agent contract check, --all only: AGENTS.md is written once and\n // never refreshed (the ownership contract), so the one thing the\n // docs-repo-wide mode owes it is detection — a stamp older than the\n // binary means agents are branching on tables the binary no longer\n // honours. It grades the repo, not any service, so it rides on the\n // landscape target.\n const agentsPath = agentsFile(docsDir);\n const agentsText = existsSync(agentsPath) ? await readFile(agentsPath, \"utf8\") : null;\n const agents = agentsStaleFinding(agentsText, LOAM_VERSION);\n if (agents !== null) landscape.findings.push(agents);\n // The other direction, and the one that changes what a PASS means:\n // this binary predates the corpus, so a directive it cannot parse is\n // read as prose and produces no join to fail.\n const behind = binaryBehindFinding(agentsText, LOAM_VERSION);\n if (behind !== null) landscape.findings.push(behind);\n if (scope !== null) {\n landscape.findings = await scopedLandscapeFindings(landscape.findings, {\n docsDir, scope, land, services: enumerated, fleet,\n });\n }\n }\n targets.push(...(await inOrder(services, (svc) => serviceTarget(svc.id, land, landscapeIsTarget))));\n targets.push(...(await inOrder(features, (feat) => featureTarget(feat, land))));\n } else if (opts.feature) {\n const feature = await resolveFeature(docsDir, opts.feature, \"exclude\", fleet);\n if (!feature) {\n fail(json, \"unknown-target\", await missingFeatureMessage(docsDir, opts.feature, fleet));\n return;\n }\n targets.push(await featureTarget(feature));\n } else if (target !== undefined) {\n // The positional reads the way `show` reads one: try the feature first\n // (ids like FEAT-101 are distinctive, service names are arbitrary), then\n // the service. --service/--feature stay as the explicit spellings for a\n // name that could be both — and when both readings exist, the run says\n // so out loud instead of silently taking one (`target.ambiguous`).\n const feature = await resolveFeature(docsDir, target, \"exclude\", fleet);\n const isService = (await listServices(docsDir, fleet)).some((s) => s.id === target);\n if (feature) {\n resolvedKind = \"feature\";\n const report = await featureTarget(feature);\n if (isService) report.findings.unshift(ambiguousTarget(target, \"feature\"));\n targets.push(report);\n } else {\n // Neither reading exists. An archived feature is its own diagnosis\n // (\"already archived\", not \"no such thing\"); anything else reads as a\n // service, so the did-you-mean hints in service.unknown fire.\n if (!isService && (await resolveFeature(docsDir, target, \"only\", fleet)) !== null) {\n fail(json, \"unknown-target\", await missingFeatureMessage(docsDir, target, fleet));\n return;\n }\n resolvedKind = \"service\";\n const resolved = await resolveServiceTarget(docsDir, target, \"target\", fleet);\n if (!resolved.ok) return fail(json, \"invalid-option\", resolved.problem);\n targets.push(await serviceTarget(resolved.id));\n }\n } else {\n const service = opts.service ?? config.service;\n if (!service) return fail(json, \"invalid-option\", NO_SERVICE_MESSAGE);\n const resolved = await resolveServiceTarget(docsDir, service, \"--service\", fleet);\n if (!resolved.ok) return fail(json, \"invalid-option\", resolved.problem);\n // A bound service a feature in flight introduces has no services/ directory yet, so its documents are\n // validated where they are — the binding's reading only, since `--service` forces a service target.\n introduced = opts.service === undefined ? await introducedBinding(docsDir, resolved, fleet) : null;\n if (introduced === null) targets.push(await serviceTarget(resolved.id));\n else targets.push(...(await inOrder(introduced.features, (feat) => featureTarget(feat))));\n }\n } catch (err) {\n // The docs repo went away between the gate above and the enumeration.\n if (err instanceof DocsRepoUnavailableError) {\n reportDocsRepoError(json, err);\n return;\n }\n // An IO failure that `guarded` could not localise to one target — it\n // happened in the ENUMERATION, which reads every living spec's\n // frontmatter to build the service list. There is no partial report to\n // give: without the list, no service was checked, including the ones\n // that are fine. Say which file, and refuse; the one thing that must\n // not happen is a stack trace on stdout's sibling stream and an\n // `internal` envelope that names nothing.\n reportRepositoryUnavailable(\n json,\n err,\n \"the service list itself is unknown and nothing was validated\",\n docsDir,\n );\n return;\n }\n\n // By subject, not by finding — the rule lives with the rollup in report.ts.\n const unverifiable = unverifiableSubjects(targets);\n // A journal in the repo outranks everything graded above: the docs may\n // be half-merged, and in CI a green over them merges. Led, not appended\n // — it is the reason nothing below can be trusted — and attached to the\n // first target because a finding lives in one. `lead` keeps it leading\n // in the fleet report too, which orders targets by kind rather than by\n // position (render/text.ts) and would otherwise print it wherever the\n // first target landed.\n const interrupted = await interruptedCommitFinding(docsDir);\n if (interrupted !== null && targets.length > 0) {\n targets[0]!.findings.unshift({ ...interrupted, text: { ...interrupted.text, lead: true } });\n }\n\n // The fleet scorecard, --all only: recomputed per invocation off the same\n // memoized reads this run already made — loam stores no history — and it\n // fails closed per axis, never whole (fleet/scorecard/scorecard.ts).\n //\n // Suppressed under `--base`: its denominators are the graded targets, so\n // over a narrowed set it reads \"2 of 2 services documented\" for a fleet\n // where ten more are not — and its axes license report.ts's grouping,\n // which would drop real warnings because an unlooked-at axis reads zero.\n const scorecard =\n opts.all && scope === null\n ? await buildScorecard({ docsDir, targets, fleet, boundService: config.service })\n : null;\n\n const valid = reportValid(targets);\n const capped = targets.map(capDetails);\n // One rollup for both views: the --json summary and the text footer\n // print this object, never a count of their own.\n const totals = summary(targets);\n if (json) {\n emitJson({\n command: \"validate\",\n valid,\n summary: totals,\n ...(resolvedKind === undefined ? {} : { resolvedKind }),\n // What this run looked at. Only under `--base`, so an unscoped payload\n // is today's document and its ABSENCE says `summary` counts the whole\n // fleet — scopeJson has why a scoped one may not stay silent.\n ...(scope === null ? {} : { scope: scopeJson(scope) }),\n // Only when a bare run validated the features introducing the bound service: why `targets` holds no service.\n ...(introduced === null ? {} : { boundService: introducedJson(introduced) }),\n // Emitted in every mode now that it is derived per service: a\n // single-service run knows exactly as much about its own blind spot\n // as `--all` knows about the fleet's.\n sourcesUnverifiableFromHere: unverifiable,\n ...(scorecard === null ? {} : { scorecard }),\n // What to do about every code this run raised — the one thing the\n // payload could not previously answer. `validate` is step 1 of every\n // generated protocol and the command an agent reads first, and until\n // now it replied in prose: a finding names a code and says what is\n // wrong, and nothing in it said that `loam explain <code>` knows what\n // to do next.\n //\n // A top-level MAP, not a field on each finding, for the reason\n // report.ts's DETAIL_LIMIT gives about evidence: a hundred-service\n // fleet raising one code a hundred times would ship the same\n // sentence a hundred times, in the interface an agent pipes into a\n // context window. The consumer joins `findings[].code` to\n // `fixes[code]` — one lookup, no round trip, no repetition.\n //\n // Keyed ONLY by codes a non-`ok` finding raised. A confirmation has\n // nothing to fix, and on a clean fleet the `ok` codes are the\n // overwhelming majority of findings; attaching fixes to them would\n // pay the whole vocabulary's byte cost to tell a reader that nothing\n // is wrong. `targets` is read here rather than `capped` because\n // capping truncates evidence, not findings — the two raise the same\n // codes, and reading the uncapped set keeps this rollup computed off\n // the same targets as `summary()`.\n //\n // Not behind a flag, deliberately. It is additive, so no consumer\n // that ignores it is affected; it is small, because it carries only\n // the handful of codes this run actually raised rather than the\n // 227-row vocabulary; and a flag would mean an agent has to already\n // know the fixes exist in order to ask for them — which is the exact\n // gap being closed. It is emitted on a green run too, as `{}`, so a\n // consumer never has to branch on the key's presence before looking\n // a code up in it.\n fixes: fixesFor(\n targets.flatMap((t) => t.findings.filter((f) => f.severity !== \"ok\").map((f) => f.code)),\n ),\n targets: capped.map(targetJson),\n });\n } else {\n // The scope FIRST: a reader has to know what the report below is a\n // report ABOUT, and in the zero-target case there is nothing below at\n // all — printed after the findings, the one run that most needs words\n // would read as a green over the whole system.\n if (scope !== null) console.log(scopeLine(scope));\n // First for the same reason: what follows is a feature's report, not the service's.\n if (introduced !== null) console.log(`${introducedLead(introduced).join(\"\\n\")}\\n`);\n renderText(capped, {\n all: opts.all === true,\n errorsOnly: opts.errorsOnly === true,\n summary: totals,\n unverifiable,\n scorecard,\n });\n if (scorecard !== null) printScorecard(scorecard);\n }\n // --strict is a per-invocation CI lever: it fails the run on any error or\n // warning (ok-severity confirmations never trip it — virtually every\n // clean target emits some), and changes nothing else — `valid` keeps meaning \"no\n // errors\" in text and JSON alike, so two pipelines reading the same repo\n // may grade the same report differently and both are telling the truth.\n const strictFailed =\n opts.strict === true &&\n countSeverity(targets, \"error\") + countSeverity(targets, \"warn\") > 0;\n if (!valid || strictFailed) process.exitCode = 1;\n });\n}\n"]}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * `loam verify <FEAT> --diff-answers a.json b.json` — the command surface of
3
+ * the cross-examination lens.
4
+ *
5
+ * A third read form beside the report and frozen views: it takes no lock,
6
+ * needs no service binding, and writes nothing. The payload deliberately
7
+ * carries NO `verified`, `verdict` or `attested` key — their absence is the
8
+ * doctrine made structural (`core/verify/cross/diff.ts` holds the
9
+ * reasoning): this surface ranks review, it grades nothing.
10
+ *
11
+ * Both files validate through the same `checkAnswers` the record path uses,
12
+ * against the same scoped checklist, with `runnerOwned` unset: under a diff
13
+ * both agents answer everything in scope, `scenario.tested` included — that
14
+ * is the attested channel, and this command records nothing. If a future
15
+ * wave ever makes scenario claims runner-only even without `--results`,
16
+ * blind agents can no longer answer them and this command starts refusing;
17
+ * `checkAnswers`' own `runnerOwned` note carries the same warning where that
18
+ * editor will see it.
19
+ */
20
+ import { createHash } from "node:crypto";
21
+ import { readFile } from "node:fs/promises";
22
+ import { resolve } from "node:path";
23
+ import { emitJson, fail, repoPath } from "../../../core/envelope/json.js";
24
+ import { isRecord } from "../../../core/kernel/records.js";
25
+ import { answerEntries, checkAnswers } from "../../../core/verify/answers.js";
26
+ import {} from "../../../core/verify/checklist.js";
27
+ import { crossExamine, disjointNotice } from "../../../core/verify/cross/diff.js";
28
+ import { plural } from "../../policy/format.js";
29
+ import {} from "../report.js";
30
+ /**
31
+ * The honest half of a lens-narrowed mismatch. `checkAnswers` is handed only
32
+ * the scoped claims, so an answer naming another service's claim — which IS
33
+ * on the feature's checklist — would otherwise be called "not on the
34
+ * checklist": the same false diagnosis `runnerOwned` exists to prevent on the
35
+ * recording path. When the stray ids are real claims the lens filtered out,
36
+ * say that, and say what the lens narrowed.
37
+ */
38
+ function offLensNote(scope, raw) {
39
+ if (scope.lens === undefined)
40
+ return "";
41
+ const entries = answerEntries(raw) ?? [];
42
+ const scoped = new Set(scope.scoped.map((c) => c.id));
43
+ const onChecklist = new Set(scope.checklist.claims.map((c) => c.id));
44
+ const foreign = [
45
+ ...new Set(entries
46
+ .filter(isRecord)
47
+ .map((entry) => entry["id"])
48
+ .filter((id) => typeof id === "string" && onChecklist.has(id) && !scoped.has(id))),
49
+ ];
50
+ if (foreign.length === 0)
51
+ return "";
52
+ return (` (${foreign.join(", ")}: on the ${scope.checklist.feature} checklist but owned by another service — ` +
53
+ `--service ${scope.lens} narrowed the comparison to ${scope.scoped.length} of ${scope.checklist.claims.length} claims)`);
54
+ }
55
+ /**
56
+ * Read, digest and validate ONE answer set. Fail-closed on purpose at every
57
+ * step: an unreadable or malformed file is a refusal naming which file and
58
+ * why — never a silently empty side, which would grade as "no disagreement"
59
+ * about claims nobody compared.
60
+ */
61
+ async function readSide(scope, file, side) {
62
+ const label = `${side} answer set (${file})`;
63
+ let bytes;
64
+ try {
65
+ // cwd-relative deliberately — record.ts's reason for the same choice: the
66
+ // answer sets are the caller's hand-offs, not repository artifacts, and
67
+ // nothing on any record will ever point at them.
68
+ bytes = await readFile(resolve(process.cwd(), file));
69
+ }
70
+ catch (err) {
71
+ return {
72
+ ok: false,
73
+ code: "answers-unreadable",
74
+ message: `${label}: cannot read: ${err instanceof Error ? err.message : String(err)}`,
75
+ };
76
+ }
77
+ let raw;
78
+ try {
79
+ raw = JSON.parse(bytes.toString("utf8"));
80
+ }
81
+ catch (err) {
82
+ return {
83
+ ok: false,
84
+ code: "answers-unreadable",
85
+ message: `${label}: not JSON: ${err instanceof Error ? err.message : String(err)}`,
86
+ };
87
+ }
88
+ const context = { feature: scope.checklist.feature, ...(scope.lens === undefined ? {} : { service: scope.lens }) };
89
+ const checked = checkAnswers(scope.scoped, raw, undefined, context);
90
+ if (!checked.ok) {
91
+ return { ok: false, code: checked.code, message: `${label}: ${checked.message}${offLensNote(scope, raw)}` };
92
+ }
93
+ // The digest is over the exact bytes read — the same reviewer-checkable
94
+ // promise `reportLine` makes for consumed reports: `shasum -a 256 <file>`
95
+ // answers whether the diff in hand read the file in hand.
96
+ return { ok: true, answers: checked.answers, digest: createHash("sha256").update(bytes).digest("hex") };
97
+ }
98
+ function sideLine(answer) {
99
+ if (answer.verdict === "confirmed")
100
+ return `confirmed (${answer.evidence.join(", ")})`;
101
+ return `unconfirmed${answer.note === undefined ? "" : ` — ${answer.note}`}`;
102
+ }
103
+ export async function diffAnswers(target, checklist, files, scope) {
104
+ const { docsDir, featureDir, json } = target;
105
+ const lens = scope.lens;
106
+ // The same lens the read view applies (report.ts): the claims that
107
+ // service's code answers, no repository binding asked for — a diff writes
108
+ // nothing, so there is nothing to bind.
109
+ const scoped = lens === undefined ? checklist.claims : checklist.claims.filter((c) => c.subject === lens);
110
+ // record.ts's refusal, mirrored: a lens that owns nothing here is almost
111
+ // always a typo'd service id, and validating two files against an empty
112
+ // claim set would call every honest answer off-checklist instead of naming
113
+ // the real mistake.
114
+ if (lens !== undefined && scoped.length === 0) {
115
+ return fail(json, "unknown-service", `The current ${checklist.feature} checklist has no claims owned by service '${lens}'.`);
116
+ }
117
+ const diffScope = { scoped, checklist, ...(lens === undefined ? {} : { lens }) };
118
+ // Sequential on purpose — a short-circuit, not a race: readSide never
119
+ // rejects, but when the first file refuses, the second is never read or
120
+ // parsed, so the refusal a caller sees always names the earliest problem
121
+ // and no work is spent on a file whose sibling already failed the run.
122
+ const a = await readSide(diffScope, files.a, "first");
123
+ if (!a.ok)
124
+ return fail(json, a.code, a.message);
125
+ const b = await readSide(diffScope, files.b, "second");
126
+ if (!b.ok)
127
+ return fail(json, b.code, b.message);
128
+ const cross = crossExamine(scoped, a.answers, b.answers);
129
+ const notice = disjointNotice(cross.rows);
130
+ if (json) {
131
+ emitJson({
132
+ command: "verify",
133
+ feature: checklist.feature,
134
+ path: repoPath(docsDir, featureDir),
135
+ digest: checklist.digest,
136
+ // Named only when narrowed — report.ts's rule: a consumer must never
137
+ // mistake one service's cross-examination for the feature's.
138
+ ...(lens === undefined ? {} : { service: lens, checklistClaims: checklist.claims.length }),
139
+ files: {
140
+ a: { path: files.a, digest: a.digest },
141
+ b: { path: files.b, digest: b.digest },
142
+ },
143
+ summary: cross.summary,
144
+ claims: cross.rows,
145
+ disagreements: cross.disagreements,
146
+ ...(notice === null ? {} : { notices: [notice] }),
147
+ });
148
+ return;
149
+ }
150
+ const scopeNote = lens === undefined ? "" : ` owned by ${lens} (of ${plural(checklist.claims.length, "claim")} on the checklist)`;
151
+ console.log(`${checklist.feature} — cross-examination over ${plural(cross.rows.length, "claim")}${scopeNote} (${files.a} vs ${files.b})\n`);
152
+ if (cross.rows.length === 0) {
153
+ // Only the whole-checklist form can get here: a lens that owns nothing
154
+ // refused `unknown-service` above.
155
+ console.log(" Nothing to cross-examine: this feature's delta, specs and openapi promise nothing yet.");
156
+ return;
157
+ }
158
+ for (const row of cross.rows) {
159
+ if (row.code === "cross.disagree") {
160
+ console.log(` ✗ cross.disagree ${row.id} [${row.subject}] ${row.claim}`);
161
+ console.log(` a: ${sideLine(row.a)}`);
162
+ console.log(` b: ${sideLine(row.b)}`);
163
+ }
164
+ else if (row.code === "cross.agree-unconfirmed") {
165
+ console.log(` = ${row.id} [${row.subject}] ${row.claim} (both unconfirmed)`);
166
+ }
167
+ else {
168
+ console.log(` = ${row.id} [${row.subject}] ${row.claim}${row.evidenceDisjoint === true ? " (disjoint evidence)" : ""}`);
169
+ }
170
+ }
171
+ console.log("");
172
+ if (notice !== null)
173
+ console.log(` ⚠ ${notice.code}: ${notice.message}`);
174
+ console.log(` ${cross.summary.agreeConfirmed} agree-confirmed, ${cross.summary.agreeUnconfirmed} agree-unconfirmed, ${cross.summary.disagree} disagree.`);
175
+ console.log("\n Agreement is not verification — nothing was written and no verdict changed.");
176
+ console.log(" Read the disagreements first, then the disjoint-evidence agreements.");
177
+ }
178
+ //# sourceMappingURL=diff.js.map