@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,116 @@
1
+ /**
2
+ * `landscape.service-isolated` — a service the fleet map draws and nothing
3
+ * reaches, graded on EVIDENCE rather than on the shape alone.
4
+ *
5
+ * The state is the one `loam seed --from fleet.yaml` leaves for every service
6
+ * nobody listed under `calls:`: a bound element with no edge. Nothing used to
7
+ * report it — `landscape.service-unmodelled` wants a missing element, and the
8
+ * element is present — so a service could be adopted with a full artifact set
9
+ * and stay invisible to every cross-service check while the run ended on
10
+ * `landscape.matched`.
11
+ *
12
+ * Why the evidence gate, and not "every edgeless bound element": a warning with
13
+ * no correct fix is the warning somebody silences. A worker or a cron that
14
+ * genuinely calls nothing has an edgeless element that is TRUE, and there is
15
+ * no tag loam reads for "deliberately isolated" (inventing one is the invented
16
+ * need the non-goals forbid). So this fires only when the service's own
17
+ * `model.likec4` parses and declares at least one call across its boundary —
18
+ * a JOIN between two authored documents: the model attests a call the map
19
+ * does not draw. The list comes from `attestedCalls`, the same derivation the
20
+ * adopt brief names those calls with, so the brief and this check can never
21
+ * disagree about which edges the map owes. Silent, on purpose, for a service
22
+ * with no model (seed's fleet), an unparseable model (`c4.invalid` owns it), a
23
+ * model reaching nothing, and an unmodelled service (`service-unmodelled` owns
24
+ * it).
25
+ *
26
+ * `#external` is never a SUBJECT, and that is now enforced rather than assumed.
27
+ * The claim used to rest on "an `#external` element is not an enumerated
28
+ * service" — true of the ordinary case and false of the reachable one: an
29
+ * element tagged `#external` and bound with `metadata { service '<id>' }` to a
30
+ * directory that exists resolved like any other, so a foreign box answered for
31
+ * one of our services (R4). The two neighbouring binding checks have always
32
+ * skipped the tag; the input set here does too, so "deliberately not ours"
33
+ * means the same thing in all three.
34
+ *
35
+ * The subject set ONLY, and that boundary is the whole of the rule. The filter
36
+ * also sat inside the `touched` walk for one round, which answers a different
37
+ * question — does the map draw any edge on this service — and got it wrong: a
38
+ * kind carrying the tag (`element topic { #external }`, the idiom
39
+ * `examples/docs/architecture/landscape.likec4` defends at length) puts
40
+ * `#external` on every element of that kind, so an edge drawn from a service's
41
+ * OWN topic stopped touching it and the warning fired on a service the map
42
+ * demonstrably reaches — while `loam adopt`, whose `landscape.touched` has no
43
+ * tag filter, said `touched: true` on the same tree. Two answers to one rule
44
+ * is the drift this file's banner promises there cannot be, so the walk below
45
+ * is the brief's predicate exactly, tag and all.
46
+ *
47
+ * A sub-package of its own because `fleet/` sits at the five-file cap, and it
48
+ * imports NOTHING from `fleet/`: a child reaching back into its parent while
49
+ * the parent calls the child is the package cycle `scripts/package-graph.mjs`
50
+ * refuses, which is why the input is one record the caller fills. The models
51
+ * are no longer read here either — `./attest.ts` reads each of them once for
52
+ * this check and the datastore census together.
53
+ */
54
+ import {} from "../../../../core/c4/likec4.js";
55
+ import { edgeTemplates, spellCall } from "../../../../core/c4/resolve/attested.js";
56
+ import {} from "../../../../core/vocabulary/report.js";
57
+ import {} from "./attest.js";
58
+ /** How many attested calls the message spells out before "…" — three reads; thirty is a wall. */
59
+ const NAMED_CALLS = 3;
60
+ export function isolationFindings(input) {
61
+ const { land, resolve, pathOf } = input;
62
+ // One pass over the relationships: a service is touched when EITHER endpoint
63
+ // resolves to it. An intra-service edge (`svc.api -> svc.db`) therefore
64
+ // counts, which is the brief's `landscape.touched` predicate exactly, and
65
+ // what keeps a self-model drawn as one service of container edges silent.
66
+ // NO tag filter here, deliberately — see the banner: an `#external` endpoint
67
+ // is still an edge the map draws on whatever it resolves to, and skipping one
68
+ // made this check contradict `loam adopt` on a service whose own topic (a
69
+ // kind-tagged `#external` element) was the endpoint.
70
+ const touched = new Set();
71
+ for (const r of land.relationships) {
72
+ for (const endpoint of [r.source, r.target])
73
+ touched.add(resolve(endpoint));
74
+ }
75
+ const findings = [];
76
+ for (const model of input.attested) {
77
+ if (!input.modelled.has(model.service) || touched.has(model.service))
78
+ continue;
79
+ const calls = model.calls;
80
+ if (calls.length === 0)
81
+ continue;
82
+ // `modelled.has` proves a non-external element resolves; the find is the
83
+ // same predicate spelled on the elements, and an empty answer fails closed
84
+ // rather than naming an element that is not there.
85
+ const element = land.elements.find((e) => resolve(e.id) === model.service && !input.external.has(e.id));
86
+ if (element === undefined)
87
+ continue;
88
+ const named = calls.slice(0, NAMED_CALLS).map(spellCall).join(", ") + (calls.length > NAMED_CALLS ? ", …" : "");
89
+ // The repair form follows the calls' direction (`edgeTemplates`): the
90
+ // outbound form alone, spelled here until 2026-09-03, sent an inbound
91
+ // call backwards.
92
+ const forms = edgeTemplates(element.id, calls)
93
+ .map((t) => `\`${t}\``)
94
+ .join(" or ");
95
+ findings.push({
96
+ severity: "warn",
97
+ code: "landscape.service-isolated",
98
+ subject: model.service,
99
+ message:
100
+ // "the fleet map (architecture/)", never the landscape FILE: the input
101
+ // is the whole PROJECT, so an edge added to `architecture/extra.likec4`
102
+ // and never to landscape.likec4 silences this finding — measured on both
103
+ // the seed lab and examples/docs. Naming one file told a reader the edge
104
+ // had to land there, which SCHEMA, `loam explain` and the brief all
105
+ // already contradicted (verification 2026-09-04).
106
+ `landscape: ${pathOf(model.service)}/ resolves to '${element.id}' and no edge in the fleet map ` +
107
+ `(architecture/) touches it, while ${pathOf(model.service)}/model.likec4 declares ${calls.length} ` +
108
+ `call(s) across its boundary ` +
109
+ `(${named}) — the service is drawn and invisible to every cross-service check. Draw each as one edge on ` +
110
+ `${element.id}: ${forms} for a call, ` +
111
+ `\`publishes\`/\`consumes\` for an event, naming the other party as the map already spells it`,
112
+ });
113
+ }
114
+ return findings;
115
+ }
116
+ //# sourceMappingURL=isolation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isolation.js","sourceRoot":"","sources":["../../../../../src/commands/validate/fleet/map/isolation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `landscape.service-isolated` — a service the fleet map draws and nothing\n * reaches, graded on EVIDENCE rather than on the shape alone.\n *\n * The state is the one `loam seed --from fleet.yaml` leaves for every service\n * nobody listed under `calls:`: a bound element with no edge. Nothing used to\n * report it — `landscape.service-unmodelled` wants a missing element, and the\n * element is present — so a service could be adopted with a full artifact set\n * and stay invisible to every cross-service check while the run ended on\n * `landscape.matched`.\n *\n * Why the evidence gate, and not \"every edgeless bound element\": a warning with\n * no correct fix is the warning somebody silences. A worker or a cron that\n * genuinely calls nothing has an edgeless element that is TRUE, and there is\n * no tag loam reads for \"deliberately isolated\" (inventing one is the invented\n * need the non-goals forbid). So this fires only when the service's own\n * `model.likec4` parses and declares at least one call across its boundary —\n * a JOIN between two authored documents: the model attests a call the map\n * does not draw. The list comes from `attestedCalls`, the same derivation the\n * adopt brief names those calls with, so the brief and this check can never\n * disagree about which edges the map owes. Silent, on purpose, for a service\n * with no model (seed's fleet), an unparseable model (`c4.invalid` owns it), a\n * model reaching nothing, and an unmodelled service (`service-unmodelled` owns\n * it).\n *\n * `#external` is never a SUBJECT, and that is now enforced rather than assumed.\n * The claim used to rest on \"an `#external` element is not an enumerated\n * service\" — true of the ordinary case and false of the reachable one: an\n * element tagged `#external` and bound with `metadata { service '<id>' }` to a\n * directory that exists resolved like any other, so a foreign box answered for\n * one of our services (R4). The two neighbouring binding checks have always\n * skipped the tag; the input set here does too, so \"deliberately not ours\"\n * means the same thing in all three.\n *\n * The subject set ONLY, and that boundary is the whole of the rule. The filter\n * also sat inside the `touched` walk for one round, which answers a different\n * question — does the map draw any edge on this service — and got it wrong: a\n * kind carrying the tag (`element topic { #external }`, the idiom\n * `examples/docs/architecture/landscape.likec4` defends at length) puts\n * `#external` on every element of that kind, so an edge drawn from a service's\n * OWN topic stopped touching it and the warning fired on a service the map\n * demonstrably reaches — while `loam adopt`, whose `landscape.touched` has no\n * tag filter, said `touched: true` on the same tree. Two answers to one rule\n * is the drift this file's banner promises there cannot be, so the walk below\n * is the brief's predicate exactly, tag and all.\n *\n * A sub-package of its own because `fleet/` sits at the five-file cap, and it\n * imports NOTHING from `fleet/`: a child reaching back into its parent while\n * the parent calls the child is the package cycle `scripts/package-graph.mjs`\n * refuses, which is why the input is one record the caller fills. The models\n * are no longer read here either — `./attest.ts` reads each of them once for\n * this check and the datastore census together.\n */\nimport { type LoadedDoc } from \"../../../../core/c4/likec4.js\";\nimport { edgeTemplates, spellCall } from \"../../../../core/c4/resolve/attested.js\";\nimport { type Finding } from \"../../../../core/vocabulary/report.js\";\nimport { type AttestedModel } from \"./attest.js\";\n\nexport interface IsolationInput {\n /** The parsed landscape. */\n land: LoadedDoc;\n /**\n * The services a NON-`#external` element resolves to — `service-unmodelled`'s\n * set with the tag filter applied, which is what keeps a foreign box from\n * answering for one of our directories.\n */\n modelled: ReadonlySet<string>;\n /** The ids of the map's `#external` elements: never a subject — and never what the message names. */\n external: ReadonlySet<string>;\n /** What each service's own model attests, read once by `./attest.ts` for this check and the store census. */\n attested: readonly AttestedModel[];\n /** The shared element→service resolver every edge join uses. */\n resolve: (id: string) => string;\n /** Where a service's directory sits, repo-relative — the enumeration's answer, never `services/<id>`. */\n pathOf: (id: string) => string;\n}\n\n/** How many attested calls the message spells out before \"…\" — three reads; thirty is a wall. */\nconst NAMED_CALLS = 3;\n\nexport function isolationFindings(input: IsolationInput): Finding[] {\n const { land, resolve, pathOf } = input;\n // One pass over the relationships: a service is touched when EITHER endpoint\n // resolves to it. An intra-service edge (`svc.api -> svc.db`) therefore\n // counts, which is the brief's `landscape.touched` predicate exactly, and\n // what keeps a self-model drawn as one service of container edges silent.\n // NO tag filter here, deliberately — see the banner: an `#external` endpoint\n // is still an edge the map draws on whatever it resolves to, and skipping one\n // made this check contradict `loam adopt` on a service whose own topic (a\n // kind-tagged `#external` element) was the endpoint.\n const touched = new Set<string>();\n for (const r of land.relationships) {\n for (const endpoint of [r.source, r.target]) touched.add(resolve(endpoint));\n }\n\n const findings: Finding[] = [];\n for (const model of input.attested) {\n if (!input.modelled.has(model.service) || touched.has(model.service)) continue;\n const calls = model.calls;\n if (calls.length === 0) continue;\n // `modelled.has` proves a non-external element resolves; the find is the\n // same predicate spelled on the elements, and an empty answer fails closed\n // rather than naming an element that is not there.\n const element = land.elements.find((e) => resolve(e.id) === model.service && !input.external.has(e.id));\n if (element === undefined) continue;\n const named = calls.slice(0, NAMED_CALLS).map(spellCall).join(\", \") + (calls.length > NAMED_CALLS ? \", …\" : \"\");\n // The repair form follows the calls' direction (`edgeTemplates`): the\n // outbound form alone, spelled here until 2026-09-03, sent an inbound\n // call backwards.\n const forms = edgeTemplates(element.id, calls)\n .map((t) => `\\`${t}\\``)\n .join(\" or \");\n findings.push({\n severity: \"warn\",\n code: \"landscape.service-isolated\",\n subject: model.service,\n message:\n // \"the fleet map (architecture/)\", never the landscape FILE: the input\n // is the whole PROJECT, so an edge added to `architecture/extra.likec4`\n // and never to landscape.likec4 silences this finding — measured on both\n // the seed lab and examples/docs. Naming one file told a reader the edge\n // had to land there, which SCHEMA, `loam explain` and the brief all\n // already contradicted (verification 2026-09-04).\n `landscape: ${pathOf(model.service)}/ resolves to '${element.id}' and no edge in the fleet map ` +\n `(architecture/) touches it, while ${pathOf(model.service)}/model.likec4 declares ${calls.length} ` +\n `call(s) across its boundary ` +\n `(${named}) — the service is drawn and invisible to every cross-service check. Draw each as one edge on ` +\n `${element.id}: ${forms} for a call, ` +\n `\\`publishes\\`/\\`consumes\\` for an event, naming the other party as the map already spells it`,\n });\n }\n return findings;\n}\n"]}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The fleet's use cases, graded — the CALL, with the two vocabulary reads it
3
+ * needs, lifted out of `../landscape.ts` when that module reached its line
4
+ * limit.
5
+ *
6
+ * The seam is a phase rather than a subject: everything here happens after the
7
+ * map has parsed and grades documents the map does not own — every
8
+ * `dynamic view` in `architecture/landscape.likec4` and in every
9
+ * `architecture/usecases/*.likec4`. `core/usecases/grade/usecases.ts` owns the opt-in and
10
+ * the grades; this owns which inputs they are handed, which is the part that has
11
+ * twice been got wrong and is worth stating in one place.
12
+ *
13
+ * A sub-package of `fleet/` for `./isolation.ts`'s reason, and with its rule:
14
+ * it imports NOTHING from `fleet/` itself, so everything it needs arrives in
15
+ * one record the caller fills — besides `../usecases/place.ts`, the fleet target's
16
+ * own name for where a view is, which the graders (`core/usecases/grade/`) take
17
+ * as an argument because core may not hold it.
18
+ */
19
+ import { capabilityRequirementIndex, gradableCapabilityIds } from "../../../../core/capabilities/findings.js";
20
+ import { FleetContext } from "../../../../core/fleet-context.js";
21
+ import { useCaseFindings } from "../../../../core/usecases/grade/usecases.js";
22
+ import { viewPlace } from "../usecases/place.js";
23
+ /**
24
+ * The capability ladder is APPLIED BY ITS OWN FUNCTION rather than re-spelled
25
+ * here: an absent or unreadable capabilities.yaml means silence for the whole
26
+ * family, not a fleet full of unresolved tags, so `null` travels rather than an
27
+ * empty list — which the join would read as "the fleet declares no capabilities"
28
+ * and grade every tag against. `gradableCapabilityIds`
29
+ * (`core/capabilities/findings.ts`) is the one statement of that rule, and this
30
+ * is a caller of it precisely so a fourth un-gradable vocabulary state cannot be
31
+ * fixed in core while the command layer keeps handing the join a whole key set.
32
+ *
33
+ * Both reads are already paid for under `--all`: `capabilityFleetFindings` has
34
+ * asked for the vocabulary, and every requirement document behind the `#req-`
35
+ * tag was parsed by it, so the fleet memo answers from cache. The requirement
36
+ * index is built here rather than inside the use-case package so that package
37
+ * never learns what a capability document is.
38
+ */
39
+ export async function fleetUseCaseFindings(input) {
40
+ const { docsDir, fleet } = input;
41
+ const vocabulary = await fleet.capabilities(docsDir);
42
+ const capabilityReqs = await capabilityRequirementIndex(vocabulary, (p) => fleet.readRequirements(p));
43
+ return useCaseFindings({
44
+ views: input.views,
45
+ elements: input.elements,
46
+ relationships: input.relationships,
47
+ services: input.services,
48
+ resolve: input.resolve,
49
+ capabilities: gradableCapabilityIds(vocabulary),
50
+ requirementsOf: (capability) => capabilityReqs.byCapability.get(capability),
51
+ place: viewPlace,
52
+ });
53
+ }
54
+ //# sourceMappingURL=usecases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usecases.js","sourceRoot":"","sources":["../../../../../src/commands/validate/fleet/map/usecases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAC9G,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAKjE,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAsBjD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAoB;IAC7D,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACjC,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,cAAc,GAAG,MAAM,0BAA0B,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACtG,OAAO,eAAe,CAAC;QACrB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,YAAY,EAAE,qBAAqB,CAAC,UAAU,CAAC;QAC/C,cAAc,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC;QAC3E,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * The fleet's use cases, graded — the CALL, with the two vocabulary reads it\n * needs, lifted out of `../landscape.ts` when that module reached its line\n * limit.\n *\n * The seam is a phase rather than a subject: everything here happens after the\n * map has parsed and grades documents the map does not own — every\n * `dynamic view` in `architecture/landscape.likec4` and in every\n * `architecture/usecases/*.likec4`. `core/usecases/grade/usecases.ts` owns the opt-in and\n * the grades; this owns which inputs they are handed, which is the part that has\n * twice been got wrong and is worth stating in one place.\n *\n * A sub-package of `fleet/` for `./isolation.ts`'s reason, and with its rule:\n * it imports NOTHING from `fleet/` itself, so everything it needs arrives in\n * one record the caller fills — besides `../usecases/place.ts`, the fleet target's\n * own name for where a view is, which the graders (`core/usecases/grade/`) take\n * as an argument because core may not hold it.\n */\nimport { capabilityRequirementIndex, gradableCapabilityIds } from \"../../../../core/capabilities/findings.js\";\nimport { FleetContext } from \"../../../../core/fleet-context.js\";\nimport type { DocsDir } from \"../../../../core/kernel/ids/dirs.js\";\nimport type { Elem, Rel } from \"../../../../core/c4/likec4.js\";\nimport type { ParsedView } from \"../../../../core/c4/parsed/dynamic-views.js\";\nimport type { Finding } from \"../../../../core/vocabulary/report.js\";\nimport { useCaseFindings } from \"../../../../core/usecases/grade/usecases.js\";\nimport { viewPlace } from \"../usecases/place.js\";\n\nexport interface FleetUseCases {\n docsDir: DocsDir;\n /**\n * The views come from the PROJECT load, never from a single-file fallback,\n * and that is the file-naming rule made mechanical instead of remembered:\n * only the project load gives a view the `sourcePath` a finding has to name,\n * while a single-file load calls every document `source.c4` — so a message\n * built from that load would send its reader to `architecture/source.c4`, a\n * file that has never existed. No project, no views, and nothing to get wrong.\n */\n views: readonly ParsedView[];\n /** The map's model — what a hop is resolved against. */\n elements: Elem[];\n relationships: Rel[];\n /** The enumerated fleet, and the resolver every other edge join in the target uses. */\n services: ReadonlySet<string>;\n resolve: (id: string) => string;\n fleet: FleetContext;\n}\n\n/**\n * The capability ladder is APPLIED BY ITS OWN FUNCTION rather than re-spelled\n * here: an absent or unreadable capabilities.yaml means silence for the whole\n * family, not a fleet full of unresolved tags, so `null` travels rather than an\n * empty list — which the join would read as \"the fleet declares no capabilities\"\n * and grade every tag against. `gradableCapabilityIds`\n * (`core/capabilities/findings.ts`) is the one statement of that rule, and this\n * is a caller of it precisely so a fourth un-gradable vocabulary state cannot be\n * fixed in core while the command layer keeps handing the join a whole key set.\n *\n * Both reads are already paid for under `--all`: `capabilityFleetFindings` has\n * asked for the vocabulary, and every requirement document behind the `#req-`\n * tag was parsed by it, so the fleet memo answers from cache. The requirement\n * index is built here rather than inside the use-case package so that package\n * never learns what a capability document is.\n */\nexport async function fleetUseCaseFindings(input: FleetUseCases): Promise<Finding[]> {\n const { docsDir, fleet } = input;\n const vocabulary = await fleet.capabilities(docsDir);\n const capabilityReqs = await capabilityRequirementIndex(vocabulary, (p) => fleet.readRequirements(p));\n return useCaseFindings({\n views: input.views,\n elements: input.elements,\n relationships: input.relationships,\n services: input.services,\n resolve: input.resolve,\n capabilities: gradableCapabilityIds(vocabulary),\n requirementsOf: (capability) => capabilityReqs.byCapability.get(capability),\n place: viewPlace,\n });\n}\n"]}
@@ -0,0 +1,266 @@
1
+ /**
2
+ * The architectural obligation axis, graded against the fleet it is about.
3
+ *
4
+ * `core/obligations/obligations.ts` states what the axis IS and why it has this
5
+ * shape. This module is the four questions asked of a fleet that has one, and
6
+ * the order they are asked in — the same division `checks/fleet-shape.ts` keeps
7
+ * for the authorization and capability vocabularies, which this sits beside on
8
+ * the `landscape` target for their reason: an obligation crosses services by
9
+ * construction, so no service target can answer for it.
10
+ *
11
+ * THE FOUR ARE TWO PAIRS, and each pair is one join read in both directions.
12
+ * A tag nothing declares is an ERROR (`obligation.unknown`) and a declaration
13
+ * nothing tags is a WARNING (`obligation.unapplied`) — exactly the asymmetry
14
+ * `permissions.unknown`/`permissions.unenforced` already carry, and for the
15
+ * same reason: a typo in a tag reads like a rule, while a word nobody has
16
+ * adopted yet is an honest state. Then a tagged object no requirement covers is
17
+ * a WARNING (`obligation.uncovered`) and an `adr:` naming no file is an ERROR
18
+ * (`obligation.adr-missing`): the team's work being outstanding is normal, and
19
+ * a pointer at a decision nobody can read is not.
20
+ *
21
+ * `obligation.uncovered` IS THE PREREQUISITE THE ROADMAP NAMED. `c4.uncovered`
22
+ * has always been able to say "this architecture object owes a requirement",
23
+ * but only about a NEW tagged element in a feature's `delta.likec4` — never
24
+ * about the map the fleet actually runs on. This asks the same question of the
25
+ * LIVING landscape, against the union of every service's living `arch.spec.md`
26
+ * `Covers:` lines, which is the index that did not exist before.
27
+ */
28
+ import { existsSync } from "node:fs";
29
+ import { join } from "node:path";
30
+ import {} from "../../../core/c4/likec4.js";
31
+ import { closeIds, coversDeployEdge, coversDeployNode, coversEdge, coversElement, } from "../../../core/c4/arch.js";
32
+ import { NO_DEPLOYMENT } from "../../../core/c4/parsed/deployment.js";
33
+ import { taggedDeployment } from "../../../core/deployment/objects.js";
34
+ import { elementService } from "../../../core/c4/resolve/service.js";
35
+ import { OBLIGATION_TAG_PREFIX } from "../../../core/obligations/obligations.js";
36
+ import { servicePathsAt } from "../../../core/repo/paths.js";
37
+ import {} from "../../../core/repo/entries.js";
38
+ import {} from "../../../core/vocabulary/report.js";
39
+ import { FleetContext } from "../../../core/fleet-context.js";
40
+ import { coversEntries } from "../checks/requirements.js";
41
+ /**
42
+ * The half that does not depend on the map: the file reads, and its `adr:`
43
+ * pointers resolve.
44
+ *
45
+ * Separate from the map questions because the landscape target returns early
46
+ * twice — an absent map, and one that did not parse — and a broken vocabulary
47
+ * must still be named in exactly the runs where somebody is fixing something
48
+ * else. The same placement `permissionFindings` and `capabilityFleetFindings`
49
+ * already have, one level of precision finer.
50
+ */
51
+ export function obligationVocabularyFindings(docsDir, vocabulary) {
52
+ if (!vocabulary.present)
53
+ return [];
54
+ if (vocabulary.invalid !== undefined) {
55
+ // Reported ALONE, exactly as `permissions.invalid` and `capability.invalid`
56
+ // are: every `#obl-` tag in the fleet resolves against this file, so grading
57
+ // them on top of a broken vocabulary is a cascade, not a diagnosis.
58
+ return [
59
+ {
60
+ severity: "error",
61
+ code: "obligation.invalid",
62
+ message: `landscape: architecture/obligations.yaml does not read as a vocabulary — ${vocabulary.invalid}. ` +
63
+ "Every `#obl-` tag on the fleet map resolves against this file, so none of them can be graded until it parses. " +
64
+ "The shape is `obligations: {<id>: {description, adr}}`, ids spelled with letters, digits, `_` and `-` only.",
65
+ },
66
+ ];
67
+ }
68
+ return adrFindings(docsDir, [...vocabulary.byId.values()]);
69
+ }
70
+ /** The three questions that need the map, suspended entirely when it could not be read. */
71
+ export async function obligationFindings(check) {
72
+ const { vocabulary } = check;
73
+ if (!vocabulary.present || vocabulary.invalid !== undefined)
74
+ return [];
75
+ const findings = [];
76
+ // Which objects carry which obligation. Elements and edges are collected
77
+ // together because every question below treats them alike: an obligation
78
+ // applies to a thing on the map, and whether that thing is a box or an arrow
79
+ // changes only how the message spells it and how `Covers:` matches it.
80
+ // The enumerated fleet rides in for the deployment half of the walk: an
81
+ // instance deploys a CONTAINER more often than a whole system, and resolving
82
+ // which service owns one needs the ancestor walk `serviceResolver` performs.
83
+ // It is the same set `uncoveredFindings` resolves edge endpoints with, or the
84
+ // message would name one service and the coverage check count another.
85
+ const known = new Set(check.services.map((s) => s.id));
86
+ const tagged = taggedObjects(check.land, known);
87
+ const applied = new Set(tagged.map((t) => t.obligation));
88
+ for (const id of [...applied].sort()) {
89
+ if (vocabulary.byId.has(id))
90
+ continue;
91
+ const close = closeIds(id, [...vocabulary.byId.keys()]);
92
+ findings.push({
93
+ severity: "error",
94
+ code: "obligation.unknown",
95
+ subject: id,
96
+ message: `landscape: #${OBLIGATION_TAG_PREFIX}${id} tags ${count(tagged.filter((t) => t.obligation === id).length, "object")} on the fleet map, ` +
97
+ `and architecture/obligations.yaml declares no obligation '${id}'` +
98
+ (close.length > 0 ? ` — did you mean: ${close.join(", ")}?` : "") +
99
+ ". A tag that resolves to nothing reads exactly like a rule the fleet keeps: declare it, or fix the tag.",
100
+ details: tagged.filter((t) => t.obligation === id).map((t) => t.where),
101
+ });
102
+ }
103
+ const unapplied = [...vocabulary.byId.keys()].filter((id) => !applied.has(id)).sort();
104
+ if (unapplied.length > 0) {
105
+ findings.push({
106
+ severity: "warn",
107
+ code: "obligation.unapplied",
108
+ message: `landscape: ${unapplied.length} declared obligation(s) that no \`#${OBLIGATION_TAG_PREFIX}\` tag applies anywhere on the fleet map — ` +
109
+ "either a decision that was reversed and left its word behind, or one nobody has placed yet. " +
110
+ "Tag the elements and edges it governs, or drop the declaration; a vocabulary is worth what cites it.",
111
+ details: unapplied,
112
+ });
113
+ }
114
+ // ONLY A RESOLVED APPLICATION IS ASKED ABOUT COVERAGE. A tag naming no
115
+ // declared obligation has already earned its error above, and "no requirement
116
+ // covers #obl-typo" is not a second breach — it is the same one restated in
117
+ // words that ask the reader to write a requirement for a rule that does not
118
+ // exist. The use-case axis draws this line in the same place: only a resolved
119
+ // `#cap-` claim keeps a promise.
120
+ findings.push(...(await uncoveredFindings(check, tagged.filter((t) => vocabulary.byId.has(t.obligation)))));
121
+ return findings;
122
+ }
123
+ /**
124
+ * Every `#obl-` tag on the living map, one entry per (obligation, object) pair.
125
+ *
126
+ * A bare `#obl-` slugs to the empty string and is kept as an application on
127
+ * purpose, exactly as a bare `#cap-` is kept as a claim: the prefix is the
128
+ * author's opt-in however little follows it, and dropping it as unreserved
129
+ * would leave an object that asked to be graded silently ungraded. It then
130
+ * resolves to `obligation.unknown` in every fleet that did not declare an empty
131
+ * id, which is the honest answer.
132
+ */
133
+ function taggedObjects(land, known) {
134
+ const out = [];
135
+ for (const element of land.elements) {
136
+ for (const tag of element.tags.filter((t) => t.startsWith(OBLIGATION_TAG_PREFIX))) {
137
+ out.push({
138
+ obligation: tag.slice(OBLIGATION_TAG_PREFIX.length),
139
+ element,
140
+ where: element.id,
141
+ subject: elementService(element),
142
+ });
143
+ }
144
+ }
145
+ for (const edge of land.relationships) {
146
+ for (const tag of edge.tags.filter((t) => t.startsWith(OBLIGATION_TAG_PREFIX))) {
147
+ out.push({
148
+ obligation: tag.slice(OBLIGATION_TAG_PREFIX.length),
149
+ edge,
150
+ where: `${edge.source} -> ${edge.target}`,
151
+ subject: edge.target,
152
+ });
153
+ }
154
+ }
155
+ // The topology, walked by the same rule and for the reason the rule exists: a
156
+ // tag is a claim about the object it sits on, and which MODEL that object
157
+ // lives in is not something a reader of the tag can see. Until this walk the
158
+ // same undeclared tag was an error on a container and silence on a
159
+ // datacenter — fail-open, and the case FEAT-1's ARCH-LOAM-DEPLOY-TAGGED was
160
+ // written about. A fleet that draws no topology contributes nothing here.
161
+ for (const d of taggedDeployment(land.deployment ?? NO_DEPLOYMENT, land.elements, known, OBLIGATION_TAG_PREFIX)) {
162
+ out.push({
163
+ obligation: d.obligation,
164
+ deployed: d,
165
+ where: d.where,
166
+ ...(d.service === undefined ? {} : { subject: d.service }),
167
+ });
168
+ }
169
+ return out;
170
+ }
171
+ /**
172
+ * `obligation.uncovered` — a tagged object no living arch requirement covers.
173
+ *
174
+ * The index is the union of EVERY service's living `arch.spec.md` `Covers:`
175
+ * lines, because an obligation is placed by the architect on the map and met by
176
+ * whichever team owns the thing it sits on — and a per-service index would
177
+ * report an edge as uncovered because the requirement that covers it lives in
178
+ * the service at the other end. `coversEntries` already drops REMOVED
179
+ * requirements: a retired requirement covers nothing.
180
+ *
181
+ * ONE FINDING PER TAGGED OBJECT, subject = the service that owns it, so a
182
+ * fleet-wide report reads as a worklist per team rather than as one line naming
183
+ * forty edges.
184
+ */
185
+ async function uncoveredFindings(check, tagged) {
186
+ if (tagged.length === 0)
187
+ return [];
188
+ const covers = await livingCovers(check);
189
+ const elements = check.land.elements;
190
+ const known = new Set(check.services.map((s) => s.id));
191
+ const covered = (t) => {
192
+ if (t.element !== undefined)
193
+ return covers.some((c) => coversElement(c, t.element));
194
+ if (t.edge !== undefined)
195
+ return covers.some((c) => coversEdge(c, t.edge, elements, known));
196
+ const d = t.deployed;
197
+ return d.edge === undefined
198
+ ? covers.some((c) => coversDeployNode(c, d.id))
199
+ : covers.some((c) => coversDeployEdge(c, d.edge.source, d.edge.target));
200
+ };
201
+ return tagged
202
+ .filter((t) => !covered(t))
203
+ .map((t) => ({
204
+ severity: "warn",
205
+ code: "obligation.uncovered",
206
+ ...(t.subject === undefined ? {} : { subject: t.subject }),
207
+ message: `${t.where} carries #${OBLIGATION_TAG_PREFIX}${t.obligation} and no living arch requirement covers it — ` +
208
+ `the obligation is placed and nothing says it is met. Write the requirement in ` +
209
+ // A region, a datacenter or a cluster is owned by no service, so the
210
+ // sentence stays general rather than naming a team at random. Every
211
+ // other object here has a real owner and keeps the actionable form.
212
+ `${t.subject === undefined ? "the arch.spec.md of whichever service answers for this topology" : `${t.subject}'s arch.spec.md`}` +
213
+ ` with \`Covers: ${t.where}\` and a scenario that proves it, or drop the tag if the decision no longer applies here.`,
214
+ }));
215
+ }
216
+ /**
217
+ * Every `Covers:` entry the LIVING fleet writes, across both requirement
218
+ * documents of every service.
219
+ *
220
+ * Existence is checked for both files and for the same reason
221
+ * `permissionFindings` checks it: `arch.spec.md` is optional and most of a
222
+ * legacy fleet has none, while `spec.md` is missing on a half-adopted service —
223
+ * and `FleetContext.readRequirements` throws ENOENT, which surfaces as
224
+ * `repository-unavailable` and takes the whole `--all` run down. Both axes are
225
+ * read, not only the architecture one: `Covers:` is parsed everywhere for one
226
+ * grammar's sake, and a fleet that wrote its outbox requirement in `spec.md`
227
+ * has said the thing loam is asking about.
228
+ */
229
+ async function livingCovers(check) {
230
+ const entries = [];
231
+ for (const service of check.services) {
232
+ const paths = servicePathsAt(service.dir);
233
+ for (const path of [paths.spec, paths.archSpec]) {
234
+ if (!existsSync(path))
235
+ continue;
236
+ entries.push(...coversEntries(await check.fleet.readRequirements(path)));
237
+ }
238
+ }
239
+ return entries;
240
+ }
241
+ /**
242
+ * `obligation.adr-missing` — an `adr:` path that names no file.
243
+ *
244
+ * The path is relative to the docs repo root rather than to
245
+ * `architecture/obligations.yaml`, because that is how a reader of a fleet
246
+ * document thinks about a fleet path, and because the value is a YAML field
247
+ * rather than a markdown link — `link.unresolved` grades links written in prose,
248
+ * and this one is written in a slot loam defined.
249
+ */
250
+ function adrFindings(docsDir, obligations) {
251
+ return obligations
252
+ .filter((o) => o.adr !== undefined && !existsSync(join(docsDir, o.adr)))
253
+ .map((o) => ({
254
+ severity: "error",
255
+ code: "obligation.adr-missing",
256
+ subject: o.id,
257
+ message: `landscape: obligation '${o.id}' names \`adr: ${o.adr}\` and no such file exists — ` +
258
+ "the ADR is where the decision itself is written, so a pointer at nothing leaves every tag citing a rule nobody can read. " +
259
+ "Fix the path (it is relative to the docs repo root), write the record, or drop the field.",
260
+ }));
261
+ }
262
+ /** `1 object` / `3 objects` — the plural spelled once, because three messages count things. */
263
+ function count(n, noun) {
264
+ return `${n} ${noun}${n === 1 ? "" : "s"}`;
265
+ }
266
+ //# sourceMappingURL=obligations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obligations.js","sourceRoot":"","sources":["../../../../src/commands/validate/fleet/obligations.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The architectural obligation axis, graded against the fleet it is about.\n *\n * `core/obligations/obligations.ts` states what the axis IS and why it has this\n * shape. This module is the four questions asked of a fleet that has one, and\n * the order they are asked in — the same division `checks/fleet-shape.ts` keeps\n * for the authorization and capability vocabularies, which this sits beside on\n * the `landscape` target for their reason: an obligation crosses services by\n * construction, so no service target can answer for it.\n *\n * THE FOUR ARE TWO PAIRS, and each pair is one join read in both directions.\n * A tag nothing declares is an ERROR (`obligation.unknown`) and a declaration\n * nothing tags is a WARNING (`obligation.unapplied`) — exactly the asymmetry\n * `permissions.unknown`/`permissions.unenforced` already carry, and for the\n * same reason: a typo in a tag reads like a rule, while a word nobody has\n * adopted yet is an honest state. Then a tagged object no requirement covers is\n * a WARNING (`obligation.uncovered`) and an `adr:` naming no file is an ERROR\n * (`obligation.adr-missing`): the team's work being outstanding is normal, and\n * a pointer at a decision nobody can read is not.\n *\n * `obligation.uncovered` IS THE PREREQUISITE THE ROADMAP NAMED. `c4.uncovered`\n * has always been able to say \"this architecture object owes a requirement\",\n * but only about a NEW tagged element in a feature's `delta.likec4` — never\n * about the map the fleet actually runs on. This asks the same question of the\n * LIVING landscape, against the union of every service's living `arch.spec.md`\n * `Covers:` lines, which is the index that did not exist before.\n */\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { type Elem, type LoadedDoc, type Rel } from \"../../../core/c4/likec4.js\";\nimport {\n closeIds,\n coversDeployEdge,\n coversDeployNode,\n coversEdge,\n coversElement,\n type CoversEntry,\n} from \"../../../core/c4/arch.js\";\nimport { NO_DEPLOYMENT } from \"../../../core/c4/parsed/deployment.js\";\nimport { taggedDeployment, type TaggedDeployment } from \"../../../core/deployment/objects.js\";\nimport { elementService } from \"../../../core/c4/resolve/service.js\";\nimport { OBLIGATION_TAG_PREFIX, type ObligationVocabulary } from \"../../../core/obligations/obligations.js\";\nimport { servicePathsAt } from \"../../../core/repo/paths.js\";\nimport { type ServiceEntry } from \"../../../core/repo/entries.js\";\nimport { type Finding } from \"../../../core/vocabulary/report.js\";\nimport { FleetContext } from \"../../../core/fleet-context.js\";\nimport { coversEntries } from \"../checks/requirements.js\";\nimport type { DocsDir } from \"../../../core/kernel/ids/dirs.js\";\n\nexport interface ObligationCheck {\n docsDir: DocsDir;\n vocabulary: ObligationVocabulary;\n /**\n * The living landscape, PARSED. Not nullable, and the absence is the point:\n * the landscape target returns before it reaches this call when the map is\n * missing or did not parse, so a run that could not read the map asks none of\n * the three questions below rather than answering them empty. \"Loam did not\n * look\" is never the same answer as \"there is nothing there\" — an unreadable\n * map graded as empty would report every declared obligation as applied\n * nowhere — and the suspension lives at the call site because that is where\n * the fact is known. It is also why the vocabulary half is a separate\n * function: those two verdicts must survive exactly those early returns.\n */\n land: LoadedDoc;\n services: ServiceEntry[];\n fleet: FleetContext;\n}\n\n/**\n * The half that does not depend on the map: the file reads, and its `adr:`\n * pointers resolve.\n *\n * Separate from the map questions because the landscape target returns early\n * twice — an absent map, and one that did not parse — and a broken vocabulary\n * must still be named in exactly the runs where somebody is fixing something\n * else. The same placement `permissionFindings` and `capabilityFleetFindings`\n * already have, one level of precision finer.\n */\nexport function obligationVocabularyFindings(docsDir: DocsDir, vocabulary: ObligationVocabulary): Finding[] {\n if (!vocabulary.present) return [];\n if (vocabulary.invalid !== undefined) {\n // Reported ALONE, exactly as `permissions.invalid` and `capability.invalid`\n // are: every `#obl-` tag in the fleet resolves against this file, so grading\n // them on top of a broken vocabulary is a cascade, not a diagnosis.\n return [\n {\n severity: \"error\",\n code: \"obligation.invalid\",\n message:\n `landscape: architecture/obligations.yaml does not read as a vocabulary — ${vocabulary.invalid}. ` +\n \"Every `#obl-` tag on the fleet map resolves against this file, so none of them can be graded until it parses. \" +\n \"The shape is `obligations: {<id>: {description, adr}}`, ids spelled with letters, digits, `_` and `-` only.\",\n },\n ];\n }\n\n return adrFindings(docsDir, [...vocabulary.byId.values()]);\n}\n\n/** The three questions that need the map, suspended entirely when it could not be read. */\nexport async function obligationFindings(check: ObligationCheck): Promise<Finding[]> {\n const { vocabulary } = check;\n if (!vocabulary.present || vocabulary.invalid !== undefined) return [];\n const findings: Finding[] = [];\n\n // Which objects carry which obligation. Elements and edges are collected\n // together because every question below treats them alike: an obligation\n // applies to a thing on the map, and whether that thing is a box or an arrow\n // changes only how the message spells it and how `Covers:` matches it.\n // The enumerated fleet rides in for the deployment half of the walk: an\n // instance deploys a CONTAINER more often than a whole system, and resolving\n // which service owns one needs the ancestor walk `serviceResolver` performs.\n // It is the same set `uncoveredFindings` resolves edge endpoints with, or the\n // message would name one service and the coverage check count another.\n const known = new Set(check.services.map((s) => s.id));\n const tagged = taggedObjects(check.land, known);\n const applied = new Set(tagged.map((t) => t.obligation));\n\n for (const id of [...applied].sort()) {\n if (vocabulary.byId.has(id)) continue;\n const close = closeIds(id, [...vocabulary.byId.keys()]);\n findings.push({\n severity: \"error\",\n code: \"obligation.unknown\",\n subject: id,\n message:\n `landscape: #${OBLIGATION_TAG_PREFIX}${id} tags ${count(tagged.filter((t) => t.obligation === id).length, \"object\")} on the fleet map, ` +\n `and architecture/obligations.yaml declares no obligation '${id}'` +\n (close.length > 0 ? ` — did you mean: ${close.join(\", \")}?` : \"\") +\n \". A tag that resolves to nothing reads exactly like a rule the fleet keeps: declare it, or fix the tag.\",\n details: tagged.filter((t) => t.obligation === id).map((t) => t.where),\n });\n }\n\n const unapplied = [...vocabulary.byId.keys()].filter((id) => !applied.has(id)).sort();\n if (unapplied.length > 0) {\n findings.push({\n severity: \"warn\",\n code: \"obligation.unapplied\",\n message:\n `landscape: ${unapplied.length} declared obligation(s) that no \\`#${OBLIGATION_TAG_PREFIX}\\` tag applies anywhere on the fleet map — ` +\n \"either a decision that was reversed and left its word behind, or one nobody has placed yet. \" +\n \"Tag the elements and edges it governs, or drop the declaration; a vocabulary is worth what cites it.\",\n details: unapplied,\n });\n }\n\n // ONLY A RESOLVED APPLICATION IS ASKED ABOUT COVERAGE. A tag naming no\n // declared obligation has already earned its error above, and \"no requirement\n // covers #obl-typo\" is not a second breach — it is the same one restated in\n // words that ask the reader to write a requirement for a rule that does not\n // exist. The use-case axis draws this line in the same place: only a resolved\n // `#cap-` claim keeps a promise.\n findings.push(...(await uncoveredFindings(check, tagged.filter((t) => vocabulary.byId.has(t.obligation)))));\n return findings;\n}\n\n/** One place an obligation is applied: which obligation, on what, and how a message names it. */\ninterface TaggedObject {\n obligation: string;\n /** The element, the edge, or the deployment object — exactly one is set. */\n element?: Elem;\n edge?: Rel;\n deployed?: TaggedDeployment;\n /**\n * How the finding spells this object, and how a `Covers:` line has to: an\n * element id, `source -> target`, or the `node:` forms.\n */\n where: string;\n /**\n * What the finding is filed under — the service that owns it, where one\n * does. ABSENT for a region, a datacenter or a cluster: nobody-s service\n * runs one, and naming a team that did not ask for the work is worse than\n * leaving the sentence general.\n */\n subject?: string;\n}\n\n/**\n * Every `#obl-` tag on the living map, one entry per (obligation, object) pair.\n *\n * A bare `#obl-` slugs to the empty string and is kept as an application on\n * purpose, exactly as a bare `#cap-` is kept as a claim: the prefix is the\n * author's opt-in however little follows it, and dropping it as unreserved\n * would leave an object that asked to be graded silently ungraded. It then\n * resolves to `obligation.unknown` in every fleet that did not declare an empty\n * id, which is the honest answer.\n */\nfunction taggedObjects(land: LoadedDoc, known: ReadonlySet<string>): TaggedObject[] {\n const out: TaggedObject[] = [];\n for (const element of land.elements) {\n for (const tag of element.tags.filter((t) => t.startsWith(OBLIGATION_TAG_PREFIX))) {\n out.push({\n obligation: tag.slice(OBLIGATION_TAG_PREFIX.length),\n element,\n where: element.id,\n subject: elementService(element),\n });\n }\n }\n for (const edge of land.relationships) {\n for (const tag of edge.tags.filter((t) => t.startsWith(OBLIGATION_TAG_PREFIX))) {\n out.push({\n obligation: tag.slice(OBLIGATION_TAG_PREFIX.length),\n edge,\n where: `${edge.source} -> ${edge.target}`,\n subject: edge.target,\n });\n }\n }\n // The topology, walked by the same rule and for the reason the rule exists: a\n // tag is a claim about the object it sits on, and which MODEL that object\n // lives in is not something a reader of the tag can see. Until this walk the\n // same undeclared tag was an error on a container and silence on a\n // datacenter — fail-open, and the case FEAT-1's ARCH-LOAM-DEPLOY-TAGGED was\n // written about. A fleet that draws no topology contributes nothing here.\n for (const d of taggedDeployment(land.deployment ?? NO_DEPLOYMENT, land.elements, known, OBLIGATION_TAG_PREFIX)) {\n out.push({\n obligation: d.obligation,\n deployed: d,\n where: d.where,\n ...(d.service === undefined ? {} : { subject: d.service }),\n });\n }\n return out;\n}\n\n/**\n * `obligation.uncovered` — a tagged object no living arch requirement covers.\n *\n * The index is the union of EVERY service's living `arch.spec.md` `Covers:`\n * lines, because an obligation is placed by the architect on the map and met by\n * whichever team owns the thing it sits on — and a per-service index would\n * report an edge as uncovered because the requirement that covers it lives in\n * the service at the other end. `coversEntries` already drops REMOVED\n * requirements: a retired requirement covers nothing.\n *\n * ONE FINDING PER TAGGED OBJECT, subject = the service that owns it, so a\n * fleet-wide report reads as a worklist per team rather than as one line naming\n * forty edges.\n */\nasync function uncoveredFindings(check: ObligationCheck, tagged: TaggedObject[]): Promise<Finding[]> {\n if (tagged.length === 0) return [];\n const covers = await livingCovers(check);\n const elements = check.land.elements;\n const known = new Set(check.services.map((s) => s.id));\n const covered = (t: TaggedObject): boolean => {\n if (t.element !== undefined) return covers.some((c) => coversElement(c, t.element!));\n if (t.edge !== undefined) return covers.some((c) => coversEdge(c, t.edge!, elements, known));\n const d = t.deployed!;\n return d.edge === undefined\n ? covers.some((c) => coversDeployNode(c, d.id!))\n : covers.some((c) => coversDeployEdge(c, d.edge!.source, d.edge!.target));\n };\n return tagged\n .filter((t) => !covered(t))\n .map((t) => ({\n severity: \"warn\" as const,\n code: \"obligation.uncovered\",\n ...(t.subject === undefined ? {} : { subject: t.subject }),\n message:\n `${t.where} carries #${OBLIGATION_TAG_PREFIX}${t.obligation} and no living arch requirement covers it — ` +\n `the obligation is placed and nothing says it is met. Write the requirement in ` +\n // A region, a datacenter or a cluster is owned by no service, so the\n // sentence stays general rather than naming a team at random. Every\n // other object here has a real owner and keeps the actionable form.\n `${t.subject === undefined ? \"the arch.spec.md of whichever service answers for this topology\" : `${t.subject}'s arch.spec.md`}` +\n ` with \\`Covers: ${t.where}\\` and a scenario that proves it, or drop the tag if the decision no longer applies here.`,\n }));\n}\n\n/**\n * Every `Covers:` entry the LIVING fleet writes, across both requirement\n * documents of every service.\n *\n * Existence is checked for both files and for the same reason\n * `permissionFindings` checks it: `arch.spec.md` is optional and most of a\n * legacy fleet has none, while `spec.md` is missing on a half-adopted service —\n * and `FleetContext.readRequirements` throws ENOENT, which surfaces as\n * `repository-unavailable` and takes the whole `--all` run down. Both axes are\n * read, not only the architecture one: `Covers:` is parsed everywhere for one\n * grammar's sake, and a fleet that wrote its outbox requirement in `spec.md`\n * has said the thing loam is asking about.\n */\nasync function livingCovers(check: ObligationCheck): Promise<CoversEntry[]> {\n const entries: CoversEntry[] = [];\n for (const service of check.services) {\n const paths = servicePathsAt(service.dir);\n for (const path of [paths.spec, paths.archSpec]) {\n if (!existsSync(path)) continue;\n entries.push(...coversEntries(await check.fleet.readRequirements(path)));\n }\n }\n return entries;\n}\n\n/**\n * `obligation.adr-missing` — an `adr:` path that names no file.\n *\n * The path is relative to the docs repo root rather than to\n * `architecture/obligations.yaml`, because that is how a reader of a fleet\n * document thinks about a fleet path, and because the value is a YAML field\n * rather than a markdown link — `link.unresolved` grades links written in prose,\n * and this one is written in a slot loam defined.\n */\nfunction adrFindings(docsDir: DocsDir, obligations: readonly { id: string; adr?: string }[]): Finding[] {\n return obligations\n .filter((o) => o.adr !== undefined && !existsSync(join(docsDir, o.adr)))\n .map((o) => ({\n severity: \"error\" as const,\n code: \"obligation.adr-missing\",\n subject: o.id,\n message:\n `landscape: obligation '${o.id}' names \\`adr: ${o.adr!}\\` and no such file exists — ` +\n \"the ADR is where the decision itself is written, so a pointer at nothing leaves every tag citing a rule nobody can read. \" +\n \"Fix the path (it is relative to the docs repo root), write the record, or drop the field.\",\n }));\n}\n\n/** `1 object` / `3 objects` — the plural spelled once, because three messages count things. */\nfunction count(n: number, noun: string): string {\n return `${n} ${noun}${n === 1 ? \"\" : \"s\"}`;\n}\n"]}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * The adoption vocabulary of the fleet scorecard: which contract axes a
3
+ * service PARTICIPATES in, summed to the fleet's per-axis participation
4
+ * counts, and the mechanical rule for which warnings the `--all` text report
5
+ * may fold under a per-axis "not started" banner.
6
+ *
7
+ * A leaf on purpose: it imports nothing, so `../report.ts` (the text
8
+ * renderer) and `./contracts.js` (which computes the per-service booleans)
9
+ * can both use it without closing a cycle — `adoptionOf` takes the smallest
10
+ * structural parameter it needs instead of the ContractCounts type,
11
+ * core/vocabulary/maturity.ts's EdgeSource precedent for staying a leaf.
12
+ */
13
+ /**
14
+ * The six contract axes a service adopts one at a time, in the order every
15
+ * rendering walks them. Participation is a per-service boolean with one
16
+ * mechanical rule per axis, spelled on `Scorecard.adoption` (./scorecard.js)
17
+ * where the payload key freezes them.
18
+ */
19
+ export const ADOPTION_AXES = [
20
+ "requirements",
21
+ "arch",
22
+ "openapi",
23
+ "asyncapi",
24
+ "permissions",
25
+ "capabilities",
26
+ ];
27
+ /** Sum the per-service participation booleans into the fleet's counts. */
28
+ export function adoptionOf(perService) {
29
+ const out = { requirements: 0, arch: 0, openapi: 0, asyncapi: 0, permissions: 0, capabilities: 0 };
30
+ for (const svc of perService) {
31
+ for (const axis of ADOPTION_AXES)
32
+ if (svc.participates[axis])
33
+ out[axis] += 1;
34
+ }
35
+ return out;
36
+ }
37
+ /**
38
+ * THE QUALIFICATION RULE — this table IS the rule, and it is mechanical and
39
+ * fail-closed. A finding is grouped under an axis's "not started" banner iff
40
+ * (1) its severity is `warn`, (2) its code is listed in this table's row for
41
+ * the axis, (3) this run's `adoption[axis] === 0`, and (4) the run could
42
+ * measure that zero at all — a fleet with at least one service and no
43
+ * `service.unreadable` subject (report.ts enforces this half, beside the
44
+ * banner it gates: "0 of 0" is no fleet, and an unreadable service's
45
+ * all-false participation must not manufacture the zero). Anything else —
46
+ * every error, every warn code not listed here, every warn on an axis with
47
+ * even one participating service — prints ungrouped, exactly as before. When
48
+ * in doubt a code stays OUT of the table: the cost of a wrongly-ungrouped
49
+ * warning is noise, the cost of a wrongly-grouped one is a hidden defect.
50
+ *
51
+ * A row lists exactly the warn codes whose SOLE cause is the axis not being
52
+ * started fleet-wide — codes whose remedy presupposes starting the axis at
53
+ * all, so with zero participating services the per-target repetition carries
54
+ * no information the one banner does not:
55
+ *
56
+ * - requirements: `service.no-spec` and `spec.no-requirements` fire once per
57
+ * service when nobody in the fleet has written a requirement block.
58
+ * - openapi: `service.no-openapi`'s WARN form (the error form — dangling
59
+ * authored links into the absent file — never groups, by condition 1), and
60
+ * `spine.op-link-missing`, which never reads the contract (service/spine.ts
61
+ * documents exactly that) and so fires per titled Calls-edge even with zero
62
+ * contracts fleet-wide.
63
+ * - permissions: `permissions.unenforced` — one finding whose whole content
64
+ * is "the vocabulary exists and nothing cites it yet".
65
+ * - capabilities: `capability.unrealized` — deliberately one warn PER
66
+ * declared capability (core/capabilities/findings.ts), so a freshly landed
67
+ * vocabulary warns M times before the first requirement names any of them.
68
+ * - arch and asyncapi have NO code whose sole cause is fleet-wide absence
69
+ * (an absent arch.spec.md is silent; an absent asyncapi.yaml is silent or
70
+ * an error when authored links strand on it), so their rows are empty and
71
+ * those axes surface only in the scorecard's not-started one-liner.
72
+ *
73
+ * Rows are disjoint — a code belongs to exactly one axis — which is what lets
74
+ * `groupedWarnCodes` invert the table into a Map. Not prose alone:
75
+ * test/adoption-rollup.test.ts asserts the flattened rows hold no duplicate,
76
+ * because a code filed under two axes would be grouped under whichever
77
+ * happens to sit at zero — possibly hiding it behind a fully adopted axis.
78
+ */
79
+ export const AXIS_GROUPED_WARNS = {
80
+ requirements: ["service.no-spec", "spec.no-requirements"],
81
+ arch: [],
82
+ openapi: ["service.no-openapi", "spine.op-link-missing"],
83
+ asyncapi: [],
84
+ permissions: ["permissions.unenforced"],
85
+ capabilities: ["capability.unrealized"],
86
+ };
87
+ /**
88
+ * The table inverted for this run: warn code → its axis, for exactly the axes
89
+ * this run's adoption counts put at zero. Insertion order is ADOPTION_AXES
90
+ * order then row order, so every walk over the Map renders deterministically.
91
+ */
92
+ export function groupedWarnCodes(adoption) {
93
+ const out = new Map();
94
+ for (const axis of ADOPTION_AXES) {
95
+ if (adoption[axis] !== 0)
96
+ continue;
97
+ for (const code of AXIS_GROUPED_WARNS[axis])
98
+ out.set(code, axis);
99
+ }
100
+ return out;
101
+ }
102
+ //# sourceMappingURL=adoption.js.map