@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,75 @@
1
+ /**
2
+ * `glossary.unlinked` — a defined term that no document outside the glossary
3
+ * cites.
4
+ *
5
+ * The mirror of `permissions.unenforced` and `capability.unrealized`, and it
6
+ * earns its place for their reason: a vocabulary is worth what cites it. A term
7
+ * nobody links to is either a word the fleet never adopted or a definition left
8
+ * behind by a rename — both are drift, and neither is visible from inside the
9
+ * file. WARN, because the honest answer is often "not written up yet", and
10
+ * because a glossary must be safe to start: a fleet that defines twenty terms
11
+ * on a Monday and cites four of them is adopting the axis, not failing it.
12
+ *
13
+ * A TERM CITED ONLY BY OTHER TERMS IS STILL UNLINKED, and this is the judgement
14
+ * that keeps the warning worth anything. A glossary is a network of definitions,
15
+ * so `order-line` linking to `order` is normal and correct — and it proves
16
+ * nothing about whether the FLEET uses either word. The same reasoning
17
+ * `capability.requirement-inert-join` applies one axis over: a join written
18
+ * inside the tree is not evidence about the world outside it. The intra-glossary
19
+ * citations are listed in `details` rather than hidden, because they are the
20
+ * first thing a reader will otherwise go looking for.
21
+ *
22
+ * ONE FINDING FOR THE WHOLE GLOSSARY when nothing cites anything, and one per
23
+ * term otherwise. A fleet that has just created `glossary/` and written its
24
+ * first eight definitions would otherwise get eight identical warnings saying
25
+ * the same thing about the same afternoon's work.
26
+ */
27
+ import { backlinkIndex } from "../../../core/links/backlinks.js";
28
+ import { readGlossary } from "../../../core/glossary/tree.js";
29
+ import { glossaryDir } from "../../../core/repo/authored/paths.js";
30
+ import { repoPath } from "../../../core/envelope/json.js";
31
+ import { FleetContext } from "../../../core/fleet-context.js";
32
+ import {} from "../../../core/vocabulary/report.js";
33
+ export async function glossaryFindings(docsDir, fleet) {
34
+ const root = glossaryDir(docsDir);
35
+ const glossary = await readGlossary(root);
36
+ // The directory's existence is the axis's opt-in, exactly as
37
+ // `architecture/capabilities.yaml` and `capabilities/` are the business
38
+ // axis's. A fleet without one pays a single `existsSync` and hears nothing —
39
+ // and the whole fleet-wide link walk below is never built.
40
+ if (!glossary.present || glossary.terms.length === 0)
41
+ return [];
42
+ const index = await backlinkIndex(docsDir, fleet);
43
+ const inGlossary = (source) => source.startsWith(`${repoPath(docsDir, root)}/`);
44
+ const unlinked = glossary.terms
45
+ .map((term) => ({ term, cited: index.linkersOf(term.path) }))
46
+ .map(({ term, cited }) => ({ term, outside: cited.filter((s) => !inGlossary(s)), within: cited.filter(inGlossary) }))
47
+ .filter(({ outside }) => outside.length === 0);
48
+ if (unlinked.length === 0)
49
+ return [];
50
+ // The whole vocabulary uncited is one fact about one afternoon, not N facts.
51
+ if (unlinked.length === glossary.terms.length && glossary.terms.length > 1) {
52
+ return [
53
+ {
54
+ severity: "warn",
55
+ code: "glossary.unlinked",
56
+ message: `glossary: none of the ${glossary.terms.length} defined term(s) is linked from any document outside glossary/. ` +
57
+ "A term becomes checkable when a requirement, capability or intent cites it — " +
58
+ "`[Order](../../glossary/order.md)` — and until then the definitions are a document nothing joins to.",
59
+ details: unlinked.map(({ term }) => term.id),
60
+ },
61
+ ];
62
+ }
63
+ return unlinked.map(({ term, within }) => ({
64
+ severity: "warn",
65
+ code: "glossary.unlinked",
66
+ subject: term.id,
67
+ message: `glossary/${term.id}.md is linked from no document outside glossary/` +
68
+ (within.length === 0
69
+ ? " — either a word the fleet has not adopted, or a definition left behind by a rename."
70
+ : ", only from other terms — which says the glossary is consistent, not that the fleet uses the word.") +
71
+ ` Cite it as \`[${term.id}](<relative>/glossary/${term.id}.md)\` from the requirement or capability that uses it, or delete the definition.`,
72
+ ...(within.length === 0 ? {} : { details: within }),
73
+ }));
74
+ }
75
+ //# sourceMappingURL=glossary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glossary.js","sourceRoot":"","sources":["../../../../src/commands/validate/links/glossary.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `glossary.unlinked` — a defined term that no document outside the glossary\n * cites.\n *\n * The mirror of `permissions.unenforced` and `capability.unrealized`, and it\n * earns its place for their reason: a vocabulary is worth what cites it. A term\n * nobody links to is either a word the fleet never adopted or a definition left\n * behind by a rename — both are drift, and neither is visible from inside the\n * file. WARN, because the honest answer is often \"not written up yet\", and\n * because a glossary must be safe to start: a fleet that defines twenty terms\n * on a Monday and cites four of them is adopting the axis, not failing it.\n *\n * A TERM CITED ONLY BY OTHER TERMS IS STILL UNLINKED, and this is the judgement\n * that keeps the warning worth anything. A glossary is a network of definitions,\n * so `order-line` linking to `order` is normal and correct — and it proves\n * nothing about whether the FLEET uses either word. The same reasoning\n * `capability.requirement-inert-join` applies one axis over: a join written\n * inside the tree is not evidence about the world outside it. The intra-glossary\n * citations are listed in `details` rather than hidden, because they are the\n * first thing a reader will otherwise go looking for.\n *\n * ONE FINDING FOR THE WHOLE GLOSSARY when nothing cites anything, and one per\n * term otherwise. A fleet that has just created `glossary/` and written its\n * first eight definitions would otherwise get eight identical warnings saying\n * the same thing about the same afternoon's work.\n */\nimport { backlinkIndex } from \"../../../core/links/backlinks.js\";\nimport { readGlossary } from \"../../../core/glossary/tree.js\";\nimport { glossaryDir } from \"../../../core/repo/authored/paths.js\";\nimport { repoPath } from \"../../../core/envelope/json.js\";\nimport { FleetContext } from \"../../../core/fleet-context.js\";\nimport { type Finding } from \"../../../core/vocabulary/report.js\";\nimport type { DocsDir } from \"../../../core/kernel/ids/dirs.js\";\n\nexport async function glossaryFindings(docsDir: DocsDir, fleet: FleetContext): Promise<Finding[]> {\n const root = glossaryDir(docsDir);\n const glossary = await readGlossary(root);\n // The directory's existence is the axis's opt-in, exactly as\n // `architecture/capabilities.yaml` and `capabilities/` are the business\n // axis's. A fleet without one pays a single `existsSync` and hears nothing —\n // and the whole fleet-wide link walk below is never built.\n if (!glossary.present || glossary.terms.length === 0) return [];\n\n const index = await backlinkIndex(docsDir, fleet);\n const inGlossary = (source: string): boolean => source.startsWith(`${repoPath(docsDir, root)}/`);\n const unlinked = glossary.terms\n .map((term) => ({ term, cited: index.linkersOf(term.path) }))\n .map(({ term, cited }) => ({ term, outside: cited.filter((s) => !inGlossary(s)), within: cited.filter(inGlossary) }))\n .filter(({ outside }) => outside.length === 0);\n if (unlinked.length === 0) return [];\n\n // The whole vocabulary uncited is one fact about one afternoon, not N facts.\n if (unlinked.length === glossary.terms.length && glossary.terms.length > 1) {\n return [\n {\n severity: \"warn\",\n code: \"glossary.unlinked\",\n message:\n `glossary: none of the ${glossary.terms.length} defined term(s) is linked from any document outside glossary/. ` +\n \"A term becomes checkable when a requirement, capability or intent cites it — \" +\n \"`[Order](../../glossary/order.md)` — and until then the definitions are a document nothing joins to.\",\n details: unlinked.map(({ term }) => term.id),\n },\n ];\n }\n return unlinked.map(({ term, within }) => ({\n severity: \"warn\" as const,\n code: \"glossary.unlinked\",\n subject: term.id,\n message:\n `glossary/${term.id}.md is linked from no document outside glossary/` +\n (within.length === 0\n ? \" — either a word the fleet has not adopted, or a definition left behind by a rename.\"\n : \", only from other terms — which says the glossary is consistent, not that the fleet uses the word.\") +\n ` Cite it as \\`[${term.id}](<relative>/glossary/${term.id}.md)\\` from the requirement or capability that uses it, or delete the definition.`,\n ...(within.length === 0 ? {} : { details: within }),\n }));\n}\n"]}
@@ -0,0 +1,63 @@
1
+ import { plural } from "../../policy/format.js";
2
+ import { cappedNames } from "./rollups.js";
3
+ /**
4
+ * More than three services: three can be a coincidence of one team's
5
+ * services, and three lines are still read one by one. Past that the lines
6
+ * stop being read and start being scrolled.
7
+ */
8
+ const REPEAT_THRESHOLD = 3;
9
+ /**
10
+ * The groups over `services`, considering only the findings `shown` would
11
+ * print. The predicate is the listing's own, so a finding another lever
12
+ * already took out of the listing (`--errors-only`, an axis banner, a lead) is
13
+ * neither counted here nor printed twice.
14
+ */
15
+ export function repeatedFindings(services, shown) {
16
+ // Per key, the foldable finding of each service that raises the key exactly
17
+ // once — a Map iterates in insertion order, so the names keep the report's.
18
+ const byKey = new Map();
19
+ for (const t of services) {
20
+ for (const f of t.findings) {
21
+ if (f.severity === "ok" || !shown(f))
22
+ continue;
23
+ const key = `${f.severity} ${f.code}`;
24
+ const perService = byKey.get(key) ?? new Map();
25
+ // A second finding from the same service, or one carrying details, makes
26
+ // that service's entry unfoldable (null): its lines print as themselves.
27
+ const foldable = !perService.has(t.id) && (f.details ?? []).length === 0;
28
+ perService.set(t.id, foldable ? f : null);
29
+ byKey.set(key, perService);
30
+ }
31
+ }
32
+ const groups = [];
33
+ const collapsed = new Set();
34
+ for (const perService of byKey.values()) {
35
+ const folded = [...perService].filter((entry) => entry[1] !== null);
36
+ const [first] = folded;
37
+ if (first === undefined || folded.length <= REPEAT_THRESHOLD)
38
+ continue;
39
+ groups.push({ example: first[1], findings: folded.length, services: folded.map(([id]) => id) });
40
+ for (const [, f] of folded)
41
+ collapsed.add(f);
42
+ }
43
+ // A stable sort, so the report order survives inside each severity.
44
+ groups.sort((a, b) => severityRank(a.example) - severityRank(b.example));
45
+ return { groups, collapsed };
46
+ }
47
+ function severityRank(f) {
48
+ return f.severity === "error" ? 0 : 1;
49
+ }
50
+ /**
51
+ * Each group as its example — through `lineOf`, the listing's own line, so it
52
+ * keeps the severity marker and the `(code)` suffix exactly as any finding
53
+ * does — and one indented line saying how far it repeats. No member carries
54
+ * details (those are never folded), so nothing is left out of either line.
55
+ */
56
+ export function printRepeats(groups, lineOf) {
57
+ for (const g of groups) {
58
+ console.log(lineOf(g.example));
59
+ console.log(` same code ×${g.findings} on ${plural(g.services.length, "service")}: ` +
60
+ `${cappedNames(g.services)} — every finding is in --json`);
61
+ }
62
+ }
63
+ //# sourceMappingURL=repeats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repeats.js","sourceRoot":"","sources":["../../../../src/commands/validate/render/repeats.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Repeat grouping: on a fleet run, a warning or error that MORE THAN\n * `REPEAT_THRESHOLD` services raise prints once, as itself, followed by one\n * counted line naming the services — instead of once per service.\n *\n * A fleet mid-adoption raises the same finding on most of its services: forty\n * services with no `sources:` print forty near-identical warnings, and the one\n * warning that is actually different sits somewhere among them. The reader of\n * a CI log needs the pattern once and the exceptions individually; the per-\n * service copies are what the `--json` payload and a single-service run are\n * for, and both still carry every one.\n *\n * It is the same kind of lever as `--errors-only` and axis grouping\n * (`./text.ts`), and holds the same discipline: the report, the footer's\n * counts, `--json` and `--strict` are computed from the UNFILTERED findings,\n * and nothing is dropped — every finding a group stands for is counted on its\n * line and its service named there (capped, the remainder counted). Each\n * boundary below is chosen so a group cannot hide something a reader needs:\n *\n * - SERVICE targets only. A feature's block is that feature's work list, and\n * the landscape's findings are each about a different place on the map, so\n * neither is \"the same finding again\".\n * - Warnings and errors only. An `ok` line confirms a per-service fact (how\n * many elements, how many requirements), and `--errors-only` already exists\n * for a reader who wants confirmations gone.\n * - Keyed on severity AND code. `service.no-openapi` is an error or a warning\n * depending on what already points into the missing file; one key would file\n * an error under a ⚠.\n * - The threshold counts distinct SERVICES, not findings, and only a service\n * raising the finding exactly ONCE is folded. One service raising\n * `covers.unknown` five times is five broken lines in one document, and each\n * of them has to print — that is not a fleet-wide pattern, it is a worklist —\n * so its five lines stay in its own listing even when four other services\n * raise the code once each and are folded.\n * - A finding that carries `details` is never folded. Details are evidence\n * about one service (which links dangle into the missing file, which ids do\n * not resolve), and a counted line could only drop them.\n */\nimport type { Finding, TargetReport } from \"../../../core/vocabulary/report.js\";\nimport { plural } from \"../../policy/format.js\";\nimport { cappedNames } from \"./rollups.js\";\n\n/**\n * More than three services: three can be a coincidence of one team's\n * services, and three lines are still read one by one. Past that the lines\n * stop being read and start being scrolled.\n */\nconst REPEAT_THRESHOLD = 3;\n\nexport interface RepeatGroup {\n /** The group's first finding in report order — printed in full, as itself. */\n readonly example: Finding;\n /** How many findings the group stands for, the example included. */\n readonly findings: number;\n /** The distinct services raising it, in report order. */\n readonly services: readonly string[];\n}\n\nexport interface Repeats {\n /** Errors first, then warnings; within each, the order the report raised them in. */\n readonly groups: readonly RepeatGroup[];\n /** Every finding a group stands for — exactly what the per-service listing skips. */\n readonly collapsed: ReadonlySet<Finding>;\n}\n\n/**\n * The groups over `services`, considering only the findings `shown` would\n * print. The predicate is the listing's own, so a finding another lever\n * already took out of the listing (`--errors-only`, an axis banner, a lead) is\n * neither counted here nor printed twice.\n */\nexport function repeatedFindings(\n services: readonly TargetReport[],\n shown: (f: Finding) => boolean,\n): Repeats {\n // Per key, the foldable finding of each service that raises the key exactly\n // once — a Map iterates in insertion order, so the names keep the report's.\n const byKey = new Map<string, Map<string, Finding | null>>();\n for (const t of services) {\n for (const f of t.findings) {\n if (f.severity === \"ok\" || !shown(f)) continue;\n const key = `${f.severity} ${f.code}`;\n const perService = byKey.get(key) ?? new Map<string, Finding | null>();\n // A second finding from the same service, or one carrying details, makes\n // that service's entry unfoldable (null): its lines print as themselves.\n const foldable = !perService.has(t.id) && (f.details ?? []).length === 0;\n perService.set(t.id, foldable ? f : null);\n byKey.set(key, perService);\n }\n }\n const groups: RepeatGroup[] = [];\n const collapsed = new Set<Finding>();\n for (const perService of byKey.values()) {\n const folded = [...perService].filter((entry): entry is [string, Finding] => entry[1] !== null);\n const [first] = folded;\n if (first === undefined || folded.length <= REPEAT_THRESHOLD) continue;\n groups.push({ example: first[1], findings: folded.length, services: folded.map(([id]) => id) });\n for (const [, f] of folded) collapsed.add(f);\n }\n // A stable sort, so the report order survives inside each severity.\n groups.sort((a, b) => severityRank(a.example) - severityRank(b.example));\n return { groups, collapsed };\n}\n\nfunction severityRank(f: Finding): number {\n return f.severity === \"error\" ? 0 : 1;\n}\n\n/**\n * Each group as its example — through `lineOf`, the listing's own line, so it\n * keeps the severity marker and the `(code)` suffix exactly as any finding\n * does — and one indented line saying how far it repeats. No member carries\n * details (those are never folded), so nothing is left out of either line.\n */\nexport function printRepeats(groups: readonly RepeatGroup[], lineOf: (f: Finding) => string): void {\n for (const g of groups) {\n console.log(lineOf(g.example));\n console.log(\n ` same code ×${g.findings} on ${plural(g.services.length, \"service\")}: ` +\n `${cappedNames(g.services)} — every finding is in --json`,\n );\n }\n}\n"]}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * The lines of a fleet report that describe the WHOLE run rather than one
3
+ * finding: the summary that opens and closes it, the index of its errors, the
4
+ * unverifiable-sources line and the not-started axis banners.
5
+ *
6
+ * Every one of them is tallied off the UNFILTERED findings — the same walk the
7
+ * `--json` summary counts — and none of them is a finding, which is why they
8
+ * all print under `--errors-only` and why no rendering lever (axis grouping,
9
+ * repeat grouping) can move a number in any of them.
10
+ */
11
+ import { SEVERITY_MARK } from "../../../core/vocabulary/report.js";
12
+ import { plural } from "../../policy/format.js";
13
+ import { ADOPTION_AXES } from "../fleet/scorecard/adoption.js";
14
+ /**
15
+ * How many names a counted line spells before the rest become `+N more`.
16
+ *
17
+ * A counted line exists to keep a hundred-service fleet's report readable, and
18
+ * a line that names all hundred is the same wall of text moved sideways. Five
19
+ * is enough to recognise a pattern — "it is every platform service" — and the
20
+ * count beside the list says how much was left out, so nothing reads complete
21
+ * when it is not. `--json` always carries every one.
22
+ */
23
+ const NAME_LIMIT = 5;
24
+ /** `a, b, c, d, e +3 more` — the one spelling of a capped name list. */
25
+ export function cappedNames(names) {
26
+ const shown = names.slice(0, NAME_LIMIT).join(", ");
27
+ return names.length > NAME_LIMIT ? `${shown} +${names.length - NAME_LIMIT} more` : shown;
28
+ }
29
+ /** The counts line, printed above a fleet report and again as its footer. */
30
+ export function summaryLine(s) {
31
+ return (`${plural(s.services, "service")}, ${plural(s.features, "feature")} — ` +
32
+ `${plural(s.errors, "error")}, ${plural(s.warnings, "warning")}`);
33
+ }
34
+ /**
35
+ * Every error the run raised, one line per code, BEFORE the long listing.
36
+ *
37
+ * A fleet run that fails prints its errors wherever their targets happen to
38
+ * sit, and on a large fleet that is hundreds of lines in: a reader who opens
39
+ * the log at the top saw confirmations and warnings first and had to scroll to
40
+ * learn that, and why, the run was red. The index answers that in a few lines
41
+ * — which codes, how many, on what — and does NOT repeat the findings: each
42
+ * prints further down, under its own target or counted on a repeat group.
43
+ *
44
+ * Each error is named by WHERE it prints and, when narrower, what it is
45
+ * about: `FEAT-112 (order-service)` for a feature's per-service check, bare
46
+ * `payment-service` for a service's own. The subject alone sent a reader to
47
+ * the service section for an error printed under a feature; the target alone
48
+ * hid which service a feature or landscape finding is about. Most frequent
49
+ * first; ties keep the order the report raised them in, because a stable sort
50
+ * over the target walk is deterministic across runs and machines. The ×counts
51
+ * sum to the summary's error count by construction — both walk every error.
52
+ */
53
+ export function printErrorIndex(targets) {
54
+ const byCode = new Map();
55
+ for (const t of targets) {
56
+ for (const f of t.findings) {
57
+ if (f.severity !== "error")
58
+ continue;
59
+ const entry = byCode.get(f.code) ?? { count: 0, places: new Set() };
60
+ entry.count += 1;
61
+ const where = f.subject === undefined || f.subject === t.id ? t.id : `${t.id} (${f.subject})`;
62
+ entry.places.add(where);
63
+ byCode.set(f.code, entry);
64
+ }
65
+ }
66
+ if (byCode.size === 0)
67
+ return;
68
+ console.log("errors by code:");
69
+ const rows = [...byCode].sort(([, a], [, b]) => b.count - a.count);
70
+ for (const [raised, entry] of rows) {
71
+ console.log(` ${SEVERITY_MARK.error} ${raised} ×${entry.count}: ${cappedNames([...entry.places])}`);
72
+ }
73
+ }
74
+ /**
75
+ * The `--all` footer: the summary, the unverifiable-sources line and the axis
76
+ * banners. Printed last because CI logs are read from the tail.
77
+ */
78
+ export function printFooter(targets, footer) {
79
+ const { unverifiable, card, grouped, isGrouped } = footer;
80
+ console.log(`\n${summaryLine(footer.summary)}`);
81
+ // One line for the whole fleet, never one per service: honest about the blind
82
+ // spot without drowning the report in a hundred copies of it.
83
+ if (unverifiable > 0) {
84
+ const whose = unverifiable === 1 ? "1 service's" : `${unverifiable} services'`;
85
+ console.log(`⚠ sources.unverifiable-from-here: ${whose} sources can only be checked from their own repos`);
86
+ }
87
+ // The axis banners — one per not-started axis that actually grouped a
88
+ // warning, in the axes' fixed order, each naming its dropped codes with
89
+ // counts. Tallied off the UNFILTERED findings (the same walk the footer
90
+ // counts), and printed under --errors-only too: like the footer and the
91
+ // unverifiable line this is a rollup, not a finding.
92
+ if (card !== null && grouped.size > 0) {
93
+ const tally = new Map();
94
+ for (const t of targets) {
95
+ for (const f of t.findings) {
96
+ if (isGrouped(f))
97
+ tally.set(f.code, (tally.get(f.code) ?? 0) + 1);
98
+ }
99
+ }
100
+ for (const axis of ADOPTION_AXES) {
101
+ // Insertion order of `grouped` is the table's order, so the pairs render
102
+ // deterministically across runs and machines.
103
+ const pairs = [...grouped]
104
+ .filter(([code, a]) => a === axis && (tally.get(code) ?? 0) > 0)
105
+ .map(([code]) => [code, tally.get(code) ?? 0]);
106
+ if (pairs.length === 0)
107
+ continue;
108
+ const total = pairs.reduce((n, [, k]) => n + k, 0);
109
+ console.log(`⚠ ${axis} axis not started fleet-wide (0 of ${plural(card.services, "service")}), ` +
110
+ `expected during staged adoption — ${total} warning(s) grouped: ` +
111
+ `${pairs.map(([code, k]) => `${code}×${k}`).join(", ")}; every finding is unchanged in --json`);
112
+ }
113
+ }
114
+ }
115
+ //# sourceMappingURL=rollups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rollups.js","sourceRoot":"","sources":["../../../../src/commands/validate/render/rollups.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The lines of a fleet report that describe the WHOLE run rather than one\n * finding: the summary that opens and closes it, the index of its errors, the\n * unverifiable-sources line and the not-started axis banners.\n *\n * Every one of them is tallied off the UNFILTERED findings — the same walk the\n * `--json` summary counts — and none of them is a finding, which is why they\n * all print under `--errors-only` and why no rendering lever (axis grouping,\n * repeat grouping) can move a number in any of them.\n */\nimport { SEVERITY_MARK, type Finding, type TargetReport } from \"../../../core/vocabulary/report.js\";\nimport { plural } from \"../../policy/format.js\";\nimport { ADOPTION_AXES, type Adoption, type AdoptionAxis } from \"../fleet/scorecard/adoption.js\";\nimport type { ValidateSummary } from \"../report.js\";\n\n/**\n * How many names a counted line spells before the rest become `+N more`.\n *\n * A counted line exists to keep a hundred-service fleet's report readable, and\n * a line that names all hundred is the same wall of text moved sideways. Five\n * is enough to recognise a pattern — \"it is every platform service\" — and the\n * count beside the list says how much was left out, so nothing reads complete\n * when it is not. `--json` always carries every one.\n */\nconst NAME_LIMIT = 5;\n\n/** `a, b, c, d, e +3 more` — the one spelling of a capped name list. */\nexport function cappedNames(names: readonly string[]): string {\n const shown = names.slice(0, NAME_LIMIT).join(\", \");\n return names.length > NAME_LIMIT ? `${shown} +${names.length - NAME_LIMIT} more` : shown;\n}\n\n/** The counts line, printed above a fleet report and again as its footer. */\nexport function summaryLine(s: ValidateSummary): string {\n return (\n `${plural(s.services, \"service\")}, ${plural(s.features, \"feature\")} — ` +\n `${plural(s.errors, \"error\")}, ${plural(s.warnings, \"warning\")}`\n );\n}\n\n/**\n * Every error the run raised, one line per code, BEFORE the long listing.\n *\n * A fleet run that fails prints its errors wherever their targets happen to\n * sit, and on a large fleet that is hundreds of lines in: a reader who opens\n * the log at the top saw confirmations and warnings first and had to scroll to\n * learn that, and why, the run was red. The index answers that in a few lines\n * — which codes, how many, on what — and does NOT repeat the findings: each\n * prints further down, under its own target or counted on a repeat group.\n *\n * Each error is named by WHERE it prints and, when narrower, what it is\n * about: `FEAT-112 (order-service)` for a feature's per-service check, bare\n * `payment-service` for a service's own. The subject alone sent a reader to\n * the service section for an error printed under a feature; the target alone\n * hid which service a feature or landscape finding is about. Most frequent\n * first; ties keep the order the report raised them in, because a stable sort\n * over the target walk is deterministic across runs and machines. The ×counts\n * sum to the summary's error count by construction — both walk every error.\n */\nexport function printErrorIndex(targets: readonly TargetReport[]): void {\n const byCode = new Map<string, { count: number; places: Set<string> }>();\n for (const t of targets) {\n for (const f of t.findings) {\n if (f.severity !== \"error\") continue;\n const entry = byCode.get(f.code) ?? { count: 0, places: new Set<string>() };\n entry.count += 1;\n const where = f.subject === undefined || f.subject === t.id ? t.id : `${t.id} (${f.subject})`;\n entry.places.add(where);\n byCode.set(f.code, entry);\n }\n }\n if (byCode.size === 0) return;\n console.log(\"errors by code:\");\n const rows = [...byCode].sort(([, a], [, b]) => b.count - a.count);\n for (const [raised, entry] of rows) {\n console.log(` ${SEVERITY_MARK.error} ${raised} ×${entry.count}: ${cappedNames([...entry.places])}`);\n }\n}\n\n/** What the footer needs beyond the targets themselves. */\nexport interface Footer {\n summary: ValidateSummary;\n /** The fleet's unverifiable-sources subject count. */\n unverifiable: number;\n /** The scorecard facts that licensed axis grouping, or null when nothing was grouped. */\n card: { readonly adoption: Adoption; readonly services: number } | null;\n /** The warn codes axis grouping folded, by axis — empty when `card` is null. */\n grouped: ReadonlyMap<string, AdoptionAxis>;\n /**\n * The predicate the listing dropped findings by. Handed in rather than\n * re-derived from `grouped`, so the banner counts exactly the findings the\n * listing left out — two spellings of one rule are two rules.\n */\n isGrouped: (f: Finding) => boolean;\n}\n\n/**\n * The `--all` footer: the summary, the unverifiable-sources line and the axis\n * banners. Printed last because CI logs are read from the tail.\n */\nexport function printFooter(targets: readonly TargetReport[], footer: Footer): void {\n const { unverifiable, card, grouped, isGrouped } = footer;\n console.log(`\\n${summaryLine(footer.summary)}`);\n // One line for the whole fleet, never one per service: honest about the blind\n // spot without drowning the report in a hundred copies of it.\n if (unverifiable > 0) {\n const whose = unverifiable === 1 ? \"1 service's\" : `${unverifiable} services'`;\n console.log(\n `⚠ sources.unverifiable-from-here: ${whose} sources can only be checked from their own repos`,\n );\n }\n // The axis banners — one per not-started axis that actually grouped a\n // warning, in the axes' fixed order, each naming its dropped codes with\n // counts. Tallied off the UNFILTERED findings (the same walk the footer\n // counts), and printed under --errors-only too: like the footer and the\n // unverifiable line this is a rollup, not a finding.\n if (card !== null && grouped.size > 0) {\n const tally = new Map<string, number>();\n for (const t of targets) {\n for (const f of t.findings) {\n if (isGrouped(f)) tally.set(f.code, (tally.get(f.code) ?? 0) + 1);\n }\n }\n for (const axis of ADOPTION_AXES) {\n // Insertion order of `grouped` is the table's order, so the pairs render\n // deterministically across runs and machines.\n const pairs = [...grouped]\n .filter(([code, a]) => a === axis && (tally.get(code) ?? 0) > 0)\n .map(([code]) => [code, tally.get(code) ?? 0] as const);\n if (pairs.length === 0) continue;\n const total = pairs.reduce((n, [, k]) => n + k, 0);\n console.log(\n `⚠ ${axis} axis not started fleet-wide (0 of ${plural(card.services, \"service\")}), ` +\n `expected during staged adoption — ${total} warning(s) grouped: ` +\n `${pairs.map(([code, k]) => `${code}×${k}`).join(\", \")}; every finding is unchanged in --json`,\n );\n }\n }\n}\n"]}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * `loam validate`'s human view: how a graded report prints.
3
+ *
4
+ * Its own package since the fleet report grew an ORDER — lead findings, the
5
+ * counts and the error index, every feature, the fleet, the footer — and two
6
+ * levers that fold lines (axis banners, repeat groups). None of that changes a
7
+ * finding, a count or an exit code: `--json` and `--strict` read the targets
8
+ * this module is handed, never what it chose to print.
9
+ *
10
+ * The rollup is not recounted here. `RenderOptions.summary` IS the run's
11
+ * `summary()` (`../report.ts`), the same object `--json` carries, handed in by
12
+ * validate.ts — a renderer with its own count is how a footer starts printing
13
+ * a number its own findings contradict.
14
+ */
15
+ import { listCodes } from "../../../core/explain/lookup.js";
16
+ import { NOT_CHECKED_MARK, SEVERITY_MARK, subjectsWith, } from "../../../core/vocabulary/report.js";
17
+ import { EXPLAIN_FOOTER } from "../../policy/format.js";
18
+ import { groupedWarnCodes } from "../fleet/scorecard/adoption.js";
19
+ import { printRepeats, repeatedFindings } from "./repeats.js";
20
+ import { printErrorIndex, printFooter, summaryLine } from "./rollups.js";
21
+ /**
22
+ * `--errors-only` is a RENDERING lever, the way `--strict` is an exit-code
23
+ * lever: neither changes the report, and the `--json` payload is unaffected by
24
+ * both. On a fleet of a hundred services the clean run prints several hundred
25
+ * `ok` confirmations, and the two warnings that matter are somewhere inside it;
26
+ * anyone reading a CI log wants the exceptions, and anyone auditing wants all
27
+ * of it. Both are available, from the same run, and neither is the default.
28
+ *
29
+ * Axis grouping is the same kind of lever, one notch further: warnings whose
30
+ * SOLE cause is a fleet-wide not-started axis (the mechanical, fail-closed
31
+ * rule in fleet/scorecard/adoption.ts — warn severity, listed code, axis at
32
+ * zero) are dropped from the per-target listing and re-stated as one banner
33
+ * per axis after the footer. The report, the footer's counts, `--json` and
34
+ * `--strict` are all computed from the UNFILTERED findings, so nothing a
35
+ * machine or an exit code reads moves by a single bit. Repeat grouping
36
+ * (`./repeats.ts`) is the third, under the same rule.
37
+ */
38
+ export function renderText(targets, opts) {
39
+ const { all, errorsOnly } = opts;
40
+ // When the fleet-wide "not started" claim is measurable at all — each guard
41
+ // fails closed to ungrouped rendering. `!all` is structural, not just the
42
+ // call site's promise: the banners print after the footer that only `--all`
43
+ // reaches, so grouping outside `--all` would DROP warnings instead of
44
+ // moving them — the one thing this lever must never do. `services === 0`
45
+ // is the vacuous fleet: with no services every axis is 0 "fleet-wide", and
46
+ // a banner over "0 of 0 services" would hide the fleet-level warnings of a
47
+ // repo that merely has no fleet yet. And an unreadable service proves
48
+ // nothing about what it started: its all-false participation (contracts.ts)
49
+ // could MANUFACTURE the very N=0 that licenses suppression — beside an
50
+ // error saying that service could not be checked — so one
51
+ // `service.unreadable` subject disables grouping for the whole run.
52
+ const card = !all ||
53
+ opts.scorecard === null ||
54
+ opts.scorecard.services === 0 ||
55
+ subjectsWith(targets, "service.unreadable") > 0
56
+ ? null
57
+ : opts.scorecard;
58
+ const grouped = card === null ? new Map() : groupedWarnCodes(card.adoption);
59
+ const isGrouped = (f) => f.severity === "warn" && grouped.has(f.code);
60
+ // The explain pointer follows any report that printed work — a non-ok
61
+ // finding, listed or folded under an axis banner. Gated on the UNFILTERED
62
+ // findings like every other rollup, so `--errors-only` and grouping cannot
63
+ // print codes the pointer then fails to follow. It is computed HERE rather
64
+ // than beside the two places it prints because the code column below asks
65
+ // the same question and must not walk the findings a second time to answer
66
+ // it differently.
67
+ const pointer = targets.some((t) => t.findings.some((f) => f.severity !== "ok"));
68
+ // The lookup key on the line itself.
69
+ //
70
+ // Until now a text report printed messages and no codes, so the footer under
71
+ // it could only say codes were somewhere else — in `--json`, which a reader
72
+ // would have to re-run the whole command to see. The code is what `loam
73
+ // explain` takes, what a CI branch tests and what a bug report quotes, and
74
+ // withholding it from the one surface a person actually reads made the
75
+ // footer's own offer unreachable.
76
+ //
77
+ // Only where a code is genuinely answerable, and that guard is not
78
+ // decoration: a handful of emitted finding codes still have no fix-table row
79
+ // (test/explain.test.ts names them), and printing one beside a footer
80
+ // promising an explanation would send the reader to a refusal. The set is
81
+ // built ONCE per render, and only when something non-ok will be printed:
82
+ // `explainSubject` walks the shipped workflow bodies per code (the cost
83
+ // `fixesFor` measured from the other side, where a handful of lookups is the
84
+ // cheaper shape), while `listCodes()` walks them once for the whole
85
+ // vocabulary — and a fleet report has far more finding lines than the fleet
86
+ // has distinct codes. Measured: 2.7 ms for all 273 codes, once per report.
87
+ const explainable = pointer ? new Set(listCodes().map((listing) => listing.code)) : new Set();
88
+ const listed = (f) => !isGrouped(f) && (!errorsOnly || f.severity !== "ok");
89
+ if (!all) {
90
+ for (const t of targets)
91
+ printTarget(t, listed, explainable);
92
+ // Without the --all footer there would be nothing at all to print for a
93
+ // clean single target under --errors-only — and silence is the one output
94
+ // that must never mean "checked, fine".
95
+ if (errorsOnly && targets.every((t) => t.findings.every((f) => f.severity === "ok"))) {
96
+ console.log(`${targets.map((t) => t.id).join(", ")}: no errors or warnings`);
97
+ }
98
+ if (pointer)
99
+ console.log(`\n${EXPLAIN_FOOTER}`);
100
+ return;
101
+ }
102
+ printFleet(targets, { listed, explainable, summary: opts.summary });
103
+ printFooter(targets, { summary: opts.summary, unverifiable: opts.unverifiable, card, grouped, isGrouped });
104
+ if (pointer)
105
+ console.log(`\n${EXPLAIN_FOOTER}`);
106
+ }
107
+ /**
108
+ * The `--all` listing, in the order a reader needs it rather than the order
109
+ * the targets were graded in.
110
+ *
111
+ * Graded order put every service first and the features last, so on a real
112
+ * fleet the feature blocks — the work somebody is doing right now — and any
113
+ * error that made the run red sat under hundreds of per-service lines. Now:
114
+ * the findings that say nothing below can be trusted (`TextHint.lead`); the
115
+ * counts; the error index; each feature's block; then the fleet — the
116
+ * landscape, the groups repeat grouping folded, every service. The footer
117
+ * still closes it, because CI logs are read from the tail. A finding prints at
118
+ * most once: in full under its target, or — when repeat grouping folded it —
119
+ * counted on its group's line, the group's first member printed in full.
120
+ */
121
+ function printFleet(targets, view) {
122
+ const { listed, explainable } = view;
123
+ const lead = (f) => f.text?.lead === true;
124
+ const body = (f) => listed(f) && !lead(f);
125
+ const services = targets.filter((t) => t.kind === "service");
126
+ const repeats = repeatedFindings(services, body);
127
+ const block = (f) => body(f) && !repeats.collapsed.has(f);
128
+ const features = targets.filter((t) => t.kind === "feature");
129
+ const featuresPrint = features.some((t) => t.findings.some(block));
130
+ const fleetPrints = repeats.groups.length > 0 || targets.some((t) => t.kind !== "feature" && t.findings.some(block));
131
+ // The head prints only above something: on a run whose listing is empty (a
132
+ // clean fleet under --errors-only) the footer below is the whole report,
133
+ // and the same counts twice in a row would say nothing new.
134
+ if (targets.some((t) => t.findings.some(listed))) {
135
+ const leads = targets.flatMap((t) => t.findings.filter((f) => lead(f) && listed(f)));
136
+ for (const f of leads)
137
+ printFinding(f, explainable);
138
+ console.log(summaryLine(view.summary));
139
+ printErrorIndex(targets);
140
+ if (featuresPrint || fleetPrints)
141
+ console.log("");
142
+ }
143
+ for (const t of features)
144
+ printTarget(t, block, explainable);
145
+ // One blank line between the features and the fleet, so the last feature's
146
+ // indented coherence line is not read as the landscape's first.
147
+ if (featuresPrint && fleetPrints)
148
+ console.log("");
149
+ for (const t of targets)
150
+ if (t.kind === "landscape")
151
+ printTarget(t, block, explainable);
152
+ printRepeats(repeats.groups, (f) => findingLine(f, explainable));
153
+ for (const t of services)
154
+ printTarget(t, block, explainable);
155
+ }
156
+ /** One target's block: the findings `show` admits, under the target's own header. */
157
+ function printTarget(t, show, explainable) {
158
+ const shown = t.findings.filter(show);
159
+ if (shown.length === 0)
160
+ return;
161
+ // A feature announces itself; a service's findings already carry its name.
162
+ if (t.kind === "feature")
163
+ console.log(t.id);
164
+ let header;
165
+ for (const f of shown) {
166
+ const hint = f.text ?? {};
167
+ if (hint.header && hint.header !== header) {
168
+ header = hint.header;
169
+ console.log(` ${header}`);
170
+ }
171
+ printFinding(f, explainable);
172
+ }
173
+ }
174
+ /** A finding's line and its evidence. */
175
+ function printFinding(f, explainable) {
176
+ // The whole report goes to stdout, in the order it prints. Splitting errors
177
+ // onto stderr meant a piped stdout silently lost them from the middle of
178
+ // the report and 2>&1 could reorder it; the exit code carries failure,
179
+ // and stderr stays reserved for refusals (the fail() path).
180
+ console.log(findingLine(f, explainable));
181
+ for (const d of f.details ?? [])
182
+ console.log(` ${f.text?.detailPrefix ?? ""}${d}`);
183
+ }
184
+ /** The one spelling of a finding's line — the listing's and a repeat group's example's. */
185
+ function findingLine(f, explainable) {
186
+ const hint = f.text ?? {};
187
+ // The not-checked glyph replaces ✓ only. A hint can never print a ⚠ or a ✗
188
+ // as anything but itself: a check that did not run is an `ok` fact, and a
189
+ // stray hint on a real finding must not make it look like one.
190
+ const glyph = hint.marker === "not-checked" && f.severity === "ok" ? NOT_CHECKED_MARK : SEVERITY_MARK[f.severity];
191
+ const marker = hint.marker === false ? "" : `${glyph} `;
192
+ // `ok` confirmations stay clean, deliberately. A clean fleet run is
193
+ // several hundred ✓ lines and two warnings, and a code appended to every
194
+ // one of them would cost exactly the signal the exceptions carry — there
195
+ // is nothing to look up about a check that passed.
196
+ const code = f.severity !== "ok" && explainable.has(f.code) ? ` (${f.code})` : "";
197
+ return `${" ".repeat(hint.indent ?? 0)}${marker}${f.message}${code}`;
198
+ }
199
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../../../src/commands/validate/render/text.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loam validate`'s human view: how a graded report prints.\n *\n * Its own package since the fleet report grew an ORDER — lead findings, the\n * counts and the error index, every feature, the fleet, the footer — and two\n * levers that fold lines (axis banners, repeat groups). None of that changes a\n * finding, a count or an exit code: `--json` and `--strict` read the targets\n * this module is handed, never what it chose to print.\n *\n * The rollup is not recounted here. `RenderOptions.summary` IS the run's\n * `summary()` (`../report.ts`), the same object `--json` carries, handed in by\n * validate.ts — a renderer with its own count is how a footer starts printing\n * a number its own findings contradict.\n */\nimport { listCodes } from \"../../../core/explain/lookup.js\";\nimport {\n NOT_CHECKED_MARK,\n SEVERITY_MARK,\n subjectsWith,\n type Finding,\n type TargetReport,\n} from \"../../../core/vocabulary/report.js\";\nimport { EXPLAIN_FOOTER } from \"../../policy/format.js\";\nimport { groupedWarnCodes, type Adoption, type AdoptionAxis } from \"../fleet/scorecard/adoption.js\";\nimport type { ValidateSummary } from \"../report.js\";\nimport { printRepeats, repeatedFindings } from \"./repeats.js\";\nimport { printErrorIndex, printFooter, summaryLine } from \"./rollups.js\";\n\n/** What `renderText` needs of the run beyond the graded targets themselves. */\nexport interface RenderOptions {\n all: boolean;\n errorsOnly: boolean;\n /** The run's `summary()` — the very object the `--json` payload carries. */\n summary: ValidateSummary;\n /** The fleet's unverifiable-sources subject count, for the one-line rollup. */\n unverifiable: number;\n /**\n * The run's scorecard facts the renderer reads — ONE field, not a nullable\n * adoption beside a defaulted denominator, so \"adoption without its real\n * denominator\" is not constructible. Null on every single-target run and on\n * an `--all` run whose card failed closed, and null renders exactly as\n * before grouping existed: fail-open to today's behaviour, every warning\n * printed individually.\n */\n scorecard: { readonly adoption: Adoption; readonly services: number } | null;\n}\n\n/**\n * `--errors-only` is a RENDERING lever, the way `--strict` is an exit-code\n * lever: neither changes the report, and the `--json` payload is unaffected by\n * both. On a fleet of a hundred services the clean run prints several hundred\n * `ok` confirmations, and the two warnings that matter are somewhere inside it;\n * anyone reading a CI log wants the exceptions, and anyone auditing wants all\n * of it. Both are available, from the same run, and neither is the default.\n *\n * Axis grouping is the same kind of lever, one notch further: warnings whose\n * SOLE cause is a fleet-wide not-started axis (the mechanical, fail-closed\n * rule in fleet/scorecard/adoption.ts — warn severity, listed code, axis at\n * zero) are dropped from the per-target listing and re-stated as one banner\n * per axis after the footer. The report, the footer's counts, `--json` and\n * `--strict` are all computed from the UNFILTERED findings, so nothing a\n * machine or an exit code reads moves by a single bit. Repeat grouping\n * (`./repeats.ts`) is the third, under the same rule.\n */\nexport function renderText(targets: TargetReport[], opts: RenderOptions): void {\n const { all, errorsOnly } = opts;\n // When the fleet-wide \"not started\" claim is measurable at all — each guard\n // fails closed to ungrouped rendering. `!all` is structural, not just the\n // call site's promise: the banners print after the footer that only `--all`\n // reaches, so grouping outside `--all` would DROP warnings instead of\n // moving them — the one thing this lever must never do. `services === 0`\n // is the vacuous fleet: with no services every axis is 0 \"fleet-wide\", and\n // a banner over \"0 of 0 services\" would hide the fleet-level warnings of a\n // repo that merely has no fleet yet. And an unreadable service proves\n // nothing about what it started: its all-false participation (contracts.ts)\n // could MANUFACTURE the very N=0 that licenses suppression — beside an\n // error saying that service could not be checked — so one\n // `service.unreadable` subject disables grouping for the whole run.\n const card =\n !all ||\n opts.scorecard === null ||\n opts.scorecard.services === 0 ||\n subjectsWith(targets, \"service.unreadable\") > 0\n ? null\n : opts.scorecard;\n const grouped = card === null ? new Map<string, AdoptionAxis>() : groupedWarnCodes(card.adoption);\n const isGrouped = (f: Finding): boolean => f.severity === \"warn\" && grouped.has(f.code);\n\n // The explain pointer follows any report that printed work — a non-ok\n // finding, listed or folded under an axis banner. Gated on the UNFILTERED\n // findings like every other rollup, so `--errors-only` and grouping cannot\n // print codes the pointer then fails to follow. It is computed HERE rather\n // than beside the two places it prints because the code column below asks\n // the same question and must not walk the findings a second time to answer\n // it differently.\n const pointer = targets.some((t) => t.findings.some((f) => f.severity !== \"ok\"));\n // The lookup key on the line itself.\n //\n // Until now a text report printed messages and no codes, so the footer under\n // it could only say codes were somewhere else — in `--json`, which a reader\n // would have to re-run the whole command to see. The code is what `loam\n // explain` takes, what a CI branch tests and what a bug report quotes, and\n // withholding it from the one surface a person actually reads made the\n // footer's own offer unreachable.\n //\n // Only where a code is genuinely answerable, and that guard is not\n // decoration: a handful of emitted finding codes still have no fix-table row\n // (test/explain.test.ts names them), and printing one beside a footer\n // promising an explanation would send the reader to a refusal. The set is\n // built ONCE per render, and only when something non-ok will be printed:\n // `explainSubject` walks the shipped workflow bodies per code (the cost\n // `fixesFor` measured from the other side, where a handful of lookups is the\n // cheaper shape), while `listCodes()` walks them once for the whole\n // vocabulary — and a fleet report has far more finding lines than the fleet\n // has distinct codes. Measured: 2.7 ms for all 273 codes, once per report.\n const explainable = pointer ? new Set(listCodes().map((listing) => listing.code)) : new Set<string>();\n const listed = (f: Finding): boolean => !isGrouped(f) && (!errorsOnly || f.severity !== \"ok\");\n\n if (!all) {\n for (const t of targets) printTarget(t, listed, explainable);\n // Without the --all footer there would be nothing at all to print for a\n // clean single target under --errors-only — and silence is the one output\n // that must never mean \"checked, fine\".\n if (errorsOnly && targets.every((t) => t.findings.every((f) => f.severity === \"ok\"))) {\n console.log(`${targets.map((t) => t.id).join(\", \")}: no errors or warnings`);\n }\n if (pointer) console.log(`\\n${EXPLAIN_FOOTER}`);\n return;\n }\n printFleet(targets, { listed, explainable, summary: opts.summary });\n printFooter(targets, { summary: opts.summary, unverifiable: opts.unverifiable, card, grouped, isGrouped });\n if (pointer) console.log(`\\n${EXPLAIN_FOOTER}`);\n}\n\n/** What the fleet layout reads of the render already decided above. */\ninterface FleetView {\n /** Whether a finding prints at all — the `--errors-only` and axis-banner levers already applied. */\n listed: (f: Finding) => boolean;\n explainable: ReadonlySet<string>;\n summary: ValidateSummary;\n}\n\n/**\n * The `--all` listing, in the order a reader needs it rather than the order\n * the targets were graded in.\n *\n * Graded order put every service first and the features last, so on a real\n * fleet the feature blocks — the work somebody is doing right now — and any\n * error that made the run red sat under hundreds of per-service lines. Now:\n * the findings that say nothing below can be trusted (`TextHint.lead`); the\n * counts; the error index; each feature's block; then the fleet — the\n * landscape, the groups repeat grouping folded, every service. The footer\n * still closes it, because CI logs are read from the tail. A finding prints at\n * most once: in full under its target, or — when repeat grouping folded it —\n * counted on its group's line, the group's first member printed in full.\n */\nfunction printFleet(targets: readonly TargetReport[], view: FleetView): void {\n const { listed, explainable } = view;\n const lead = (f: Finding): boolean => f.text?.lead === true;\n const body = (f: Finding): boolean => listed(f) && !lead(f);\n const services = targets.filter((t) => t.kind === \"service\");\n const repeats = repeatedFindings(services, body);\n const block = (f: Finding): boolean => body(f) && !repeats.collapsed.has(f);\n const features = targets.filter((t) => t.kind === \"feature\");\n const featuresPrint = features.some((t) => t.findings.some(block));\n const fleetPrints = repeats.groups.length > 0 || targets.some((t) => t.kind !== \"feature\" && t.findings.some(block));\n\n // The head prints only above something: on a run whose listing is empty (a\n // clean fleet under --errors-only) the footer below is the whole report,\n // and the same counts twice in a row would say nothing new.\n if (targets.some((t) => t.findings.some(listed))) {\n const leads = targets.flatMap((t) => t.findings.filter((f) => lead(f) && listed(f)));\n for (const f of leads) printFinding(f, explainable);\n console.log(summaryLine(view.summary));\n printErrorIndex(targets);\n if (featuresPrint || fleetPrints) console.log(\"\");\n }\n for (const t of features) printTarget(t, block, explainable);\n // One blank line between the features and the fleet, so the last feature's\n // indented coherence line is not read as the landscape's first.\n if (featuresPrint && fleetPrints) console.log(\"\");\n for (const t of targets) if (t.kind === \"landscape\") printTarget(t, block, explainable);\n printRepeats(repeats.groups, (f) => findingLine(f, explainable));\n for (const t of services) printTarget(t, block, explainable);\n}\n\n/** One target's block: the findings `show` admits, under the target's own header. */\nfunction printTarget(t: TargetReport, show: (f: Finding) => boolean, explainable: ReadonlySet<string>): void {\n const shown = t.findings.filter(show);\n if (shown.length === 0) return;\n // A feature announces itself; a service's findings already carry its name.\n if (t.kind === \"feature\") console.log(t.id);\n let header: string | undefined;\n for (const f of shown) {\n const hint = f.text ?? {};\n if (hint.header && hint.header !== header) {\n header = hint.header;\n console.log(` ${header}`);\n }\n printFinding(f, explainable);\n }\n}\n\n/** A finding's line and its evidence. */\nfunction printFinding(f: Finding, explainable: ReadonlySet<string>): void {\n // The whole report goes to stdout, in the order it prints. Splitting errors\n // onto stderr meant a piped stdout silently lost them from the middle of\n // the report and 2>&1 could reorder it; the exit code carries failure,\n // and stderr stays reserved for refusals (the fail() path).\n console.log(findingLine(f, explainable));\n for (const d of f.details ?? []) console.log(` ${f.text?.detailPrefix ?? \"\"}${d}`);\n}\n\n/** The one spelling of a finding's line — the listing's and a repeat group's example's. */\nfunction findingLine(f: Finding, explainable: ReadonlySet<string>): string {\n const hint = f.text ?? {};\n // The not-checked glyph replaces ✓ only. A hint can never print a ⚠ or a ✗\n // as anything but itself: a check that did not run is an `ok` fact, and a\n // stray hint on a real finding must not make it look like one.\n const glyph = hint.marker === \"not-checked\" && f.severity === \"ok\" ? NOT_CHECKED_MARK : SEVERITY_MARK[f.severity];\n const marker = hint.marker === false ? \"\" : `${glyph} `;\n // `ok` confirmations stay clean, deliberately. A clean fleet run is\n // several hundred ✓ lines and two warnings, and a code appended to every\n // one of them would cost exactly the signal the exceptions carry — there\n // is nothing to look up about a check that passed.\n const code = f.severity !== \"ok\" && explainable.has(f.code) ? ` (${f.code})` : \"\";\n return `${\" \".repeat(hint.indent ?? 0)}${marker}${f.message}${code}`;\n}\n"]}