@ybotok/loam 0.2.0-alpha.1 → 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 (901) hide show
  1. package/CHANGELOG.md +3448 -0
  2. package/COMPARISON.md +91 -3
  3. package/CONTRIBUTING.md +37 -0
  4. package/MIGRATING-from-OpenSpec.md +47 -23
  5. package/QUICKSTART.md +189 -12
  6. package/README.md +274 -65
  7. package/ROADMAP.md +572 -31
  8. package/SCHEMA.md +1709 -155
  9. package/WORKFLOW.md +298 -72
  10. package/dist/cli.js +26 -8
  11. package/dist/cli.js.map +1 -1
  12. package/dist/commands/adopt/adopt.js +5 -10
  13. package/dist/commands/adopt/adopt.js.map +1 -1
  14. package/dist/commands/adopt/render.js +50 -9
  15. package/dist/commands/adopt/render.js.map +1 -1
  16. package/dist/commands/archive/archive.js +16 -19
  17. package/dist/commands/archive/archive.js.map +1 -1
  18. package/dist/commands/archive/closing.js +42 -0
  19. package/dist/commands/archive/closing.js.map +1 -0
  20. package/dist/commands/archive/plan/contracts/asyncapi.js +36 -42
  21. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -1
  22. package/dist/commands/archive/plan/contracts/consumers.js +56 -0
  23. package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
  24. package/dist/commands/archive/plan/contracts/openapi.js +77 -43
  25. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -1
  26. package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
  27. package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
  28. package/dist/commands/archive/plan/document/head.js +151 -0
  29. package/dist/commands/archive/plan/document/head.js.map +1 -0
  30. package/dist/commands/archive/plan/document/links.js +284 -0
  31. package/dist/commands/archive/plan/document/links.js.map +1 -0
  32. package/dist/commands/archive/plan/document/run.js +136 -0
  33. package/dist/commands/archive/plan/document/run.js.map +1 -0
  34. package/dist/commands/archive/plan/gate.js +21 -19
  35. package/dist/commands/archive/plan/gate.js.map +1 -1
  36. package/dist/commands/archive/plan/landscape.js +167 -30
  37. package/dist/commands/archive/plan/landscape.js.map +1 -1
  38. package/dist/commands/archive/plan/model/extending.js +85 -0
  39. package/dist/commands/archive/plan/model/extending.js.map +1 -0
  40. package/dist/commands/archive/plan/refusal.js +14 -19
  41. package/dist/commands/archive/plan/refusal.js.map +1 -1
  42. package/dist/commands/archive/plan/specs.js +137 -56
  43. package/dist/commands/archive/plan/specs.js.map +1 -1
  44. package/dist/commands/archive/plan/state.js +3 -0
  45. package/dist/commands/archive/plan/state.js.map +1 -1
  46. package/dist/commands/archive/run.js +134 -30
  47. package/dist/commands/archive/run.js.map +1 -1
  48. package/dist/commands/archive/shipped.js +49 -0
  49. package/dist/commands/archive/shipped.js.map +1 -0
  50. package/dist/commands/context/context.js +85 -18
  51. package/dist/commands/context/context.js.map +1 -1
  52. package/dist/commands/context/print.js +29 -7
  53. package/dist/commands/context/print.js.map +1 -1
  54. package/dist/commands/delta/delta.js +102 -14
  55. package/dist/commands/delta/delta.js.map +1 -1
  56. package/dist/commands/delta/print.js +17 -1
  57. package/dist/commands/delta/print.js.map +1 -1
  58. package/dist/commands/dependencies.js +3 -7
  59. package/dist/commands/dependencies.js.map +1 -1
  60. package/dist/commands/diff/diff.js +20 -27
  61. package/dist/commands/diff/diff.js.map +1 -1
  62. package/dist/commands/doctor.js +60 -1
  63. package/dist/commands/doctor.js.map +1 -1
  64. package/dist/commands/explain/explain.js +89 -13
  65. package/dist/commands/explain/explain.js.map +1 -1
  66. package/dist/commands/explore.js +16 -10
  67. package/dist/commands/explore.js.map +1 -1
  68. package/dist/commands/gate/gate.js +45 -8
  69. package/dist/commands/gate/gate.js.map +1 -1
  70. package/dist/commands/gate/print.js +15 -3
  71. package/dist/commands/gate/print.js.map +1 -1
  72. package/dist/commands/gherkin/commit.js +13 -54
  73. package/dist/commands/gherkin/commit.js.map +1 -1
  74. package/dist/commands/gherkin/gherkin.js +36 -20
  75. package/dist/commands/gherkin/gherkin.js.map +1 -1
  76. package/dist/commands/gherkin/reconcile.js +10 -13
  77. package/dist/commands/gherkin/reconcile.js.map +1 -1
  78. package/dist/commands/init/first-hour.js +44 -0
  79. package/dist/commands/init/first-hour.js.map +1 -1
  80. package/dist/commands/init/init.js +18 -22
  81. package/dist/commands/init/init.js.map +1 -1
  82. package/dist/commands/list/campaign/campaign.js +4 -6
  83. package/dist/commands/list/campaign/campaign.js.map +1 -1
  84. package/dist/commands/list/json.js +5 -7
  85. package/dist/commands/list/json.js.map +1 -1
  86. package/dist/commands/list/list.js +44 -29
  87. package/dist/commands/list/list.js.map +1 -1
  88. package/dist/commands/list/print.js +52 -9
  89. package/dist/commands/list/print.js.map +1 -1
  90. package/dist/commands/list/suites/suites.js +140 -0
  91. package/dist/commands/list/suites/suites.js.map +1 -0
  92. package/dist/commands/list/views.js +37 -34
  93. package/dist/commands/list/views.js.map +1 -1
  94. package/dist/commands/mcp/dispatch.js +91 -36
  95. package/dist/commands/mcp/dispatch.js.map +1 -1
  96. package/dist/commands/mcp/mcp.js +56 -15
  97. package/dist/commands/mcp/mcp.js.map +1 -1
  98. package/dist/commands/mcp/serve.js.map +1 -1
  99. package/dist/commands/migrate-openspec/materialize/active.js +27 -22
  100. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -1
  101. package/dist/commands/migrate-openspec/materialize/stage.js +4 -3
  102. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -1
  103. package/dist/commands/migrate-openspec/materialize/target.js +2 -2
  104. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -1
  105. package/dist/commands/migrate-openspec/openspec/decisions.js +9 -14
  106. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -1
  107. package/dist/commands/migrate-openspec/openspec/error.js +7 -8
  108. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -1
  109. package/dist/commands/migrate-openspec/openspec/mapping.js +1 -9
  110. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -1
  111. package/dist/commands/migrate-openspec/openspec/paths.js +3 -6
  112. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -1
  113. package/dist/commands/new/capability-template.js +118 -0
  114. package/dist/commands/new/capability-template.js.map +1 -0
  115. package/dist/commands/new/commit.js +8 -22
  116. package/dist/commands/new/commit.js.map +1 -1
  117. package/dist/commands/new/modifies.js +206 -0
  118. package/dist/commands/new/modifies.js.map +1 -0
  119. package/dist/commands/new/new.js +59 -14
  120. package/dist/commands/new/new.js.map +1 -1
  121. package/dist/commands/new/templates.js +48 -124
  122. package/dist/commands/new/templates.js.map +1 -1
  123. package/dist/commands/open.js +3 -7
  124. package/dist/commands/open.js.map +1 -1
  125. package/dist/commands/policy/gate.js +27 -0
  126. package/dist/commands/policy/gate.js.map +1 -1
  127. package/dist/commands/rebase/plan.js +2 -2
  128. package/dist/commands/rebase/plan.js.map +1 -1
  129. package/dist/commands/rebase/rebase.js +60 -35
  130. package/dist/commands/rebase/rebase.js.map +1 -1
  131. package/dist/commands/seed/commit.js +55 -26
  132. package/dist/commands/seed/commit.js.map +1 -1
  133. package/dist/commands/seed/plan.js +158 -13
  134. package/dist/commands/seed/plan.js.map +1 -1
  135. package/dist/commands/seed/seed.js +13 -11
  136. package/dist/commands/seed/seed.js.map +1 -1
  137. package/dist/commands/show/feature.js +9 -5
  138. package/dist/commands/show/feature.js.map +1 -1
  139. package/dist/commands/show/introduced.js +157 -0
  140. package/dist/commands/show/introduced.js.map +1 -0
  141. package/dist/commands/show/marks.js +35 -6
  142. package/dist/commands/show/marks.js.map +1 -1
  143. package/dist/commands/show/service.js +41 -33
  144. package/dist/commands/show/service.js.map +1 -1
  145. package/dist/commands/show/show.js +17 -7
  146. package/dist/commands/show/show.js.map +1 -1
  147. package/dist/commands/status/fleet-next.js +90 -0
  148. package/dist/commands/status/fleet-next.js.map +1 -0
  149. package/dist/commands/status/json.js +2 -0
  150. package/dist/commands/status/json.js.map +1 -1
  151. package/dist/commands/status/print.js +89 -37
  152. package/dist/commands/status/print.js.map +1 -1
  153. package/dist/commands/status/status.js +3 -7
  154. package/dist/commands/status/status.js.map +1 -1
  155. package/dist/commands/steps/steps.js +103 -23
  156. package/dist/commands/steps/steps.js.map +1 -1
  157. package/dist/commands/subsystem/edit.js +7 -7
  158. package/dist/commands/subsystem/edit.js.map +1 -1
  159. package/dist/commands/subsystem/move.js +106 -46
  160. package/dist/commands/subsystem/move.js.map +1 -1
  161. package/dist/commands/subsystem/query.js +2 -4
  162. package/dist/commands/subsystem/query.js.map +1 -1
  163. package/dist/commands/subsystem/subsystem.js +4 -7
  164. package/dist/commands/subsystem/subsystem.js.map +1 -1
  165. package/dist/commands/subsystem/sync.js +289 -74
  166. package/dist/commands/subsystem/sync.js.map +1 -1
  167. package/dist/commands/subsystem/txn/exclude.js +132 -0
  168. package/dist/commands/subsystem/txn/exclude.js.map +1 -0
  169. package/dist/commands/subsystem/txn/links.js +128 -0
  170. package/dist/commands/subsystem/txn/links.js.map +1 -0
  171. package/dist/commands/subsystem/txn/report.js +174 -0
  172. package/dist/commands/subsystem/txn/report.js.map +1 -0
  173. package/dist/commands/subsystem/txn/txn.js +147 -45
  174. package/dist/commands/subsystem/txn/txn.js.map +1 -1
  175. package/dist/commands/subsystem/txn/views.js +200 -21
  176. package/dist/commands/subsystem/txn/views.js.map +1 -1
  177. package/dist/commands/tasks/actions.js +107 -0
  178. package/dist/commands/tasks/actions.js.map +1 -0
  179. package/dist/commands/tasks/render.js +253 -0
  180. package/dist/commands/tasks/render.js.map +1 -0
  181. package/dist/commands/tasks/tasks.js +119 -0
  182. package/dist/commands/tasks/tasks.js.map +1 -0
  183. package/dist/commands/unarchive/manifest.js +42 -26
  184. package/dist/commands/unarchive/manifest.js.map +1 -1
  185. package/dist/commands/unarchive/restore.js +83 -33
  186. package/dist/commands/unarchive/restore.js.map +1 -1
  187. package/dist/commands/unarchive/unarchive.js +22 -30
  188. package/dist/commands/unarchive/unarchive.js.map +1 -1
  189. package/dist/commands/validate/arch-coverage.js +78 -27
  190. package/dist/commands/validate/arch-coverage.js.map +1 -1
  191. package/dist/commands/validate/checks/fleet-shape.js +34 -126
  192. package/dist/commands/validate/checks/fleet-shape.js.map +1 -1
  193. package/dist/commands/validate/checks/health-deps.js +9 -6
  194. package/dist/commands/validate/checks/health-deps.js.map +1 -1
  195. package/dist/commands/validate/checks/introduced.js +102 -0
  196. package/dist/commands/validate/checks/introduced.js.map +1 -0
  197. package/dist/commands/validate/checks/requirements.js +18 -8
  198. package/dist/commands/validate/checks/requirements.js.map +1 -1
  199. package/dist/commands/validate/checks/sources.js +11 -2
  200. package/dist/commands/validate/checks/sources.js.map +1 -1
  201. package/dist/commands/validate/coverage/covers-after.js +105 -0
  202. package/dist/commands/validate/coverage/covers-after.js.map +1 -0
  203. package/dist/commands/validate/feature.js +26 -20
  204. package/dist/commands/validate/feature.js.map +1 -1
  205. package/dist/commands/validate/fleet/census.js +37 -13
  206. package/dist/commands/validate/fleet/census.js.map +1 -1
  207. package/dist/commands/validate/fleet/landscape.js +144 -126
  208. package/dist/commands/validate/fleet/landscape.js.map +1 -1
  209. package/dist/commands/validate/fleet/load.js +66 -0
  210. package/dist/commands/validate/fleet/load.js.map +1 -1
  211. package/dist/commands/validate/fleet/map/attest.js +98 -0
  212. package/dist/commands/validate/fleet/map/attest.js.map +1 -0
  213. package/dist/commands/validate/fleet/map/bindings.js +107 -0
  214. package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
  215. package/dist/commands/validate/fleet/map/consumers.js +244 -0
  216. package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
  217. package/dist/commands/validate/fleet/map/isolation.js +116 -0
  218. package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
  219. package/dist/commands/validate/fleet/map/usecases.js +54 -0
  220. package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
  221. package/dist/commands/validate/fleet/obligations.js +44 -14
  222. package/dist/commands/validate/fleet/obligations.js.map +1 -1
  223. package/dist/commands/validate/fleet/scorecard/print.js +10 -2
  224. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -1
  225. package/dist/commands/validate/fleet/scorecard/scorecard.js +17 -11
  226. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -1
  227. package/dist/commands/validate/fleet/usecases/place.js.map +1 -1
  228. package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
  229. package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
  230. package/dist/commands/validate/fleet/views/ids.js +50 -15
  231. package/dist/commands/validate/fleet/views/ids.js.map +1 -1
  232. package/dist/commands/validate/fleet/views/projects.js +278 -0
  233. package/dist/commands/validate/fleet/views/projects.js.map +1 -0
  234. package/dist/commands/validate/fleet/views/root-documents.js +83 -0
  235. package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
  236. package/dist/commands/validate/fleet/views/stale.js +40 -47
  237. package/dist/commands/validate/fleet/views/stale.js.map +1 -1
  238. package/dist/commands/validate/links/corpus.js +1 -4
  239. package/dist/commands/validate/links/corpus.js.map +1 -1
  240. package/dist/commands/validate/links/glossary.js.map +1 -1
  241. package/dist/commands/validate/render/repeats.js +63 -0
  242. package/dist/commands/validate/render/repeats.js.map +1 -0
  243. package/dist/commands/validate/render/rollups.js +115 -0
  244. package/dist/commands/validate/render/rollups.js.map +1 -0
  245. package/dist/commands/validate/render/text.js +199 -0
  246. package/dist/commands/validate/render/text.js.map +1 -0
  247. package/dist/commands/validate/report.js +36 -160
  248. package/dist/commands/validate/report.js.map +1 -1
  249. package/dist/commands/validate/scope.js +113 -0
  250. package/dist/commands/validate/scope.js.map +1 -0
  251. package/dist/commands/validate/service/api.js +21 -107
  252. package/dist/commands/validate/service/api.js.map +1 -1
  253. package/dist/commands/validate/service/contracts/generated.js +134 -0
  254. package/dist/commands/validate/service/contracts/generated.js.map +1 -0
  255. package/dist/commands/validate/service/events/events.js +36 -14
  256. package/dist/commands/validate/service/events/events.js.map +1 -1
  257. package/dist/commands/validate/service/events/message-producers.js +1 -1
  258. package/dist/commands/validate/service/events/message-producers.js.map +1 -1
  259. package/dist/commands/validate/service/evidence-pins.js +56 -10
  260. package/dist/commands/validate/service/evidence-pins.js.map +1 -1
  261. package/dist/commands/validate/service/model/diverged.js +226 -0
  262. package/dist/commands/validate/service/model/diverged.js.map +1 -0
  263. package/dist/commands/validate/service/model/grade.js +163 -0
  264. package/dist/commands/validate/service/model/grade.js.map +1 -0
  265. package/dist/commands/validate/service/service.js +121 -61
  266. package/dist/commands/validate/service/service.js.map +1 -1
  267. package/dist/commands/validate/service/specs.js +88 -28
  268. package/dist/commands/validate/service/specs.js.map +1 -1
  269. package/dist/commands/validate/service/spine.js +38 -3
  270. package/dist/commands/validate/service/spine.js.map +1 -1
  271. package/dist/commands/validate/service/usecases/tags.js +113 -0
  272. package/dist/commands/validate/service/usecases/tags.js.map +1 -0
  273. package/dist/commands/validate/service/usecases/usecases.js +209 -0
  274. package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
  275. package/dist/commands/validate/validate.js +85 -60
  276. package/dist/commands/validate/validate.js.map +1 -1
  277. package/dist/commands/verify/cross/diff.js +2 -6
  278. package/dist/commands/verify/cross/diff.js.map +1 -1
  279. package/dist/commands/verify/evidence/contract.js +1 -1
  280. package/dist/commands/verify/evidence/contract.js.map +1 -1
  281. package/dist/commands/verify/evidence/read.js +12 -3
  282. package/dist/commands/verify/evidence/read.js.map +1 -1
  283. package/dist/commands/verify/frozen.js +45 -23
  284. package/dist/commands/verify/frozen.js.map +1 -1
  285. package/dist/commands/verify/record.js +69 -17
  286. package/dist/commands/verify/record.js.map +1 -1
  287. package/dist/commands/verify/report.js +27 -44
  288. package/dist/commands/verify/report.js.map +1 -1
  289. package/dist/commands/verify/results.js +112 -30
  290. package/dist/commands/verify/results.js.map +1 -1
  291. package/dist/commands/verify/verify.js +55 -52
  292. package/dist/commands/verify/verify.js.map +1 -1
  293. package/dist/commands/vouch/pack/pack.js +2 -2
  294. package/dist/commands/vouch/pack/pack.js.map +1 -1
  295. package/dist/commands/vouch/pack/print.js +1 -6
  296. package/dist/commands/vouch/pack/print.js.map +1 -1
  297. package/dist/commands/vouch/pack/sections.js +1 -2
  298. package/dist/commands/vouch/pack/sections.js.map +1 -1
  299. package/dist/commands/vouch/run.js +26 -81
  300. package/dist/commands/vouch/run.js.map +1 -1
  301. package/dist/commands/vouch/sample/plan.js +20 -34
  302. package/dist/commands/vouch/sample/plan.js.map +1 -1
  303. package/dist/commands/vouch/vet/verify.js +39 -7
  304. package/dist/commands/vouch/vet/verify.js.map +1 -1
  305. package/dist/commands/vouch/vouch.js +10 -17
  306. package/dist/commands/vouch/vouch.js.map +1 -1
  307. package/dist/core/agent/agents-md/command-map.js +81 -106
  308. package/dist/core/agent/agents-md/command-map.js.map +1 -1
  309. package/dist/core/agent/agents-md/map/explain.js +21 -9
  310. package/dist/core/agent/agents-md/map/explain.js.map +1 -1
  311. package/dist/core/agent/agents-md/map/lenses/context.js +17 -8
  312. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -1
  313. package/dist/core/agent/agents-md/map/lenses/diff.js +33 -20
  314. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -1
  315. package/dist/core/agent/agents-md/map/lenses/gate.js +13 -5
  316. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -1
  317. package/dist/core/agent/agents-md/map/mcp.js +10 -7
  318. package/dist/core/agent/agents-md/map/mcp.js.map +1 -1
  319. package/dist/core/agent/agents-md/map/status.js +24 -8
  320. package/dist/core/agent/agents-md/map/status.js.map +1 -1
  321. package/dist/core/agent/agents-md/map/subsystem.js +80 -8
  322. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -1
  323. package/dist/core/agent/agents-md/map/usecases.js +88 -10
  324. package/dist/core/agent/agents-md/map/usecases.js.map +1 -1
  325. package/dist/core/agent/agents-md/refusals.js +49 -22
  326. package/dist/core/agent/agents-md/refusals.js.map +1 -1
  327. package/dist/core/agent/agents-md.js +39 -6
  328. package/dist/core/agent/agents-md.js.map +1 -1
  329. package/dist/core/agent/agents-stamp.js +10 -0
  330. package/dist/core/agent/agents-stamp.js.map +1 -1
  331. package/dist/core/agent/protocol.js +1 -1
  332. package/dist/core/agent/protocol.js.map +1 -1
  333. package/dist/core/agent/scaffold.js +10 -15
  334. package/dist/core/agent/scaffold.js.map +1 -1
  335. package/dist/core/agent/support/report.js +46 -5
  336. package/dist/core/agent/support/report.js.map +1 -1
  337. package/dist/core/agent/tools/dialects.js +1 -0
  338. package/dist/core/agent/tools/dialects.js.map +1 -1
  339. package/dist/core/agent/tools/registry.js +41 -76
  340. package/dist/core/agent/tools/registry.js.map +1 -1
  341. package/dist/core/agent/workflows/adopt.js +158 -11
  342. package/dist/core/agent/workflows/adopt.js.map +1 -1
  343. package/dist/core/agent/workflows/check.js +78 -39
  344. package/dist/core/agent/workflows/check.js.map +1 -1
  345. package/dist/core/agent/workflows/closing.js +88 -27
  346. package/dist/core/agent/workflows/closing.js.map +1 -1
  347. package/dist/core/agent/workflows/feature.js +128 -13
  348. package/dist/core/agent/workflows/feature.js.map +1 -1
  349. package/dist/core/agent/workflows/implement.js +96 -13
  350. package/dist/core/agent/workflows/implement.js.map +1 -1
  351. package/dist/core/agent/workflows/reference/authoring.js +106 -4
  352. package/dist/core/agent/workflows/reference/authoring.js.map +1 -1
  353. package/dist/core/agent/workflows/reference/codes.js +8 -6
  354. package/dist/core/agent/workflows/reference/codes.js.map +1 -1
  355. package/dist/core/agent/workflows/reference/done-check.js +37 -15
  356. package/dist/core/agent/workflows/reference/done-check.js.map +1 -1
  357. package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
  358. package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
  359. package/dist/core/agent/workflows/reference/reference.js +6 -3
  360. package/dist/core/agent/workflows/reference/reference.js.map +1 -1
  361. package/dist/core/agent/workflows/reference/spine.js +68 -27
  362. package/dist/core/agent/workflows/reference/spine.js.map +1 -1
  363. package/dist/core/asyncapi/baseline/plan.js +14 -81
  364. package/dist/core/asyncapi/baseline/plan.js.map +1 -1
  365. package/dist/core/asyncapi/digest.js +30 -25
  366. package/dist/core/asyncapi/digest.js.map +1 -1
  367. package/dist/core/asyncapi/merge/components.js +5 -4
  368. package/dist/core/asyncapi/merge/components.js.map +1 -1
  369. package/dist/core/asyncapi/merge/error.js +7 -2
  370. package/dist/core/asyncapi/merge/error.js.map +1 -1
  371. package/dist/core/asyncapi/merge/markers.js +32 -50
  372. package/dist/core/asyncapi/merge/markers.js.map +1 -1
  373. package/dist/core/asyncapi/merge/merge.js +33 -53
  374. package/dist/core/asyncapi/merge/merge.js.map +1 -1
  375. package/dist/core/asyncapi/merge/pin.js +12 -36
  376. package/dist/core/asyncapi/merge/pin.js.map +1 -1
  377. package/dist/core/asyncapi/model.js.map +1 -1
  378. package/dist/core/asyncapi/read.js +36 -12
  379. package/dist/core/asyncapi/read.js.map +1 -1
  380. package/dist/core/brief/brief.js +96 -36
  381. package/dist/core/brief/brief.js.map +1 -1
  382. package/dist/core/brief/checks.js +138 -3
  383. package/dist/core/brief/checks.js.map +1 -1
  384. package/dist/core/brief/landscape.js +209 -130
  385. package/dist/core/brief/landscape.js.map +1 -1
  386. package/dist/core/brief/map/extend.js +84 -0
  387. package/dist/core/brief/map/extend.js.map +1 -0
  388. package/dist/core/brief/map/owed.js +266 -0
  389. package/dist/core/brief/map/owed.js.map +1 -0
  390. package/dist/core/brief/targets.js +109 -31
  391. package/dist/core/brief/targets.js.map +1 -1
  392. package/dist/core/brief/unchecked.js +14 -3
  393. package/dist/core/brief/unchecked.js.map +1 -1
  394. package/dist/core/c4/arch.js +90 -182
  395. package/dist/core/c4/arch.js.map +1 -1
  396. package/dist/core/c4/direction/direction.js +114 -0
  397. package/dist/core/c4/direction/direction.js.map +1 -0
  398. package/dist/core/c4/likec4.js +169 -14
  399. package/dist/core/c4/likec4.js.map +1 -1
  400. package/dist/core/c4/locate/unlocated.js +150 -0
  401. package/dist/core/c4/locate/unlocated.js.map +1 -0
  402. package/dist/core/c4/parsed/deployment.js +160 -0
  403. package/dist/core/c4/parsed/deployment.js.map +1 -0
  404. package/dist/core/c4/parsed/dynamic-views.js.map +1 -1
  405. package/dist/core/c4/parsed/values.js +54 -1
  406. package/dist/core/c4/parsed/values.js.map +1 -1
  407. package/dist/core/c4/parsed/view-ids.js +39 -1
  408. package/dist/core/c4/parsed/view-ids.js.map +1 -1
  409. package/dist/core/c4/prefetch/fleet.js +134 -0
  410. package/dist/core/c4/prefetch/fleet.js.map +1 -0
  411. package/dist/core/c4/project/architecture.js +123 -7
  412. package/dist/core/c4/project/architecture.js.map +1 -1
  413. package/dist/core/c4/project/batch.js +140 -0
  414. package/dist/core/c4/project/batch.js.map +1 -0
  415. package/dist/core/c4/project/documents.js +43 -12
  416. package/dist/core/c4/project/documents.js.map +1 -1
  417. package/dist/core/c4/project/load.js +79 -43
  418. package/dist/core/c4/project/load.js.map +1 -1
  419. package/dist/core/c4/project/staged.js +277 -0
  420. package/dist/core/c4/project/staged.js.map +1 -0
  421. package/dist/core/c4/resolve/attested.js +0 -0
  422. package/dist/core/c4/resolve/attested.js.map +1 -0
  423. package/dist/core/c4/resolve/external.js +51 -0
  424. package/dist/core/c4/resolve/external.js.map +1 -0
  425. package/dist/core/c4/resolve/service.js +78 -17
  426. package/dist/core/c4/resolve/service.js.map +1 -1
  427. package/dist/core/c4/resolve/steps.js +290 -0
  428. package/dist/core/c4/resolve/steps.js.map +1 -0
  429. package/dist/core/c4/resolve/systems.js +154 -0
  430. package/dist/core/c4/resolve/systems.js.map +1 -0
  431. package/dist/core/c4/root-project/exclude.js +352 -0
  432. package/dist/core/c4/root-project/exclude.js.map +1 -0
  433. package/dist/core/c4/seed/template.js +65 -1
  434. package/dist/core/c4/seed/template.js.map +1 -1
  435. package/dist/core/c4/service-model/created/models.js +96 -0
  436. package/dist/core/c4/service-model/created/models.js.map +1 -0
  437. package/dist/core/c4/service-model/documents.js +47 -0
  438. package/dist/core/c4/service-model/documents.js.map +1 -0
  439. package/dist/core/c4/service-model/fleet/extending.js +82 -0
  440. package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
  441. package/dist/core/c4/service-model/load.js +165 -0
  442. package/dist/core/c4/service-model/load.js.map +1 -0
  443. package/dist/core/c4/service-model/renderer.js +128 -0
  444. package/dist/core/c4/service-model/renderer.js.map +1 -0
  445. package/dist/core/c4/service-model/shape.js +106 -0
  446. package/dist/core/c4/service-model/shape.js.map +1 -0
  447. package/dist/core/c4/service-model/slice.js +188 -0
  448. package/dist/core/c4/service-model/slice.js.map +1 -0
  449. package/dist/core/c4/source-mask.js +297 -10
  450. package/dist/core/c4/source-mask.js.map +1 -1
  451. package/dist/core/c4/source-scan.js +222 -141
  452. package/dist/core/c4/source-scan.js.map +1 -1
  453. package/dist/core/c4/splice/authored-source.js +79 -13
  454. package/dist/core/c4/splice/authored-source.js.map +1 -1
  455. package/dist/core/c4/splice/contract.js +20 -0
  456. package/dist/core/c4/splice/contract.js.map +1 -1
  457. package/dist/core/c4/splice/delta-blocks.js +20 -20
  458. package/dist/core/c4/splice/delta-blocks.js.map +1 -1
  459. package/dist/core/c4/splice/identity/declared.js +87 -0
  460. package/dist/core/c4/splice/identity/declared.js.map +1 -0
  461. package/dist/core/c4/splice/identity/edges.js +37 -0
  462. package/dist/core/c4/splice/identity/edges.js.map +1 -1
  463. package/dist/core/c4/splice/identity/existing.js +80 -0
  464. package/dist/core/c4/splice/identity/existing.js.map +1 -0
  465. package/dist/core/c4/splice/identity/interior.js +80 -0
  466. package/dist/core/c4/splice/identity/interior.js.map +1 -0
  467. package/dist/core/c4/splice/identity/owner.js +50 -0
  468. package/dist/core/c4/splice/identity/owner.js.map +1 -0
  469. package/dist/core/c4/splice/landscape-merge.js +182 -114
  470. package/dist/core/c4/splice/landscape-merge.js.map +1 -1
  471. package/dist/core/c4/splice/model/merge.js +151 -0
  472. package/dist/core/c4/splice/model/merge.js.map +1 -0
  473. package/dist/core/c4/splice/placement.js +160 -56
  474. package/dist/core/c4/splice/placement.js.map +1 -1
  475. package/dist/core/c4/splice/text/spot.js +131 -0
  476. package/dist/core/c4/splice/text/spot.js.map +1 -0
  477. package/dist/core/c4/workspace.js +13 -19
  478. package/dist/core/c4/workspace.js.map +1 -1
  479. package/dist/core/capabilities/capabilities.js +6 -6
  480. package/dist/core/capabilities/capabilities.js.map +1 -1
  481. package/dist/core/capabilities/delta/doc.js +7 -10
  482. package/dist/core/capabilities/delta/doc.js.map +1 -1
  483. package/dist/core/capabilities/delta/uncovered.js +2 -2
  484. package/dist/core/capabilities/delta/uncovered.js.map +1 -1
  485. package/dist/core/capabilities/findings.js +18 -22
  486. package/dist/core/capabilities/findings.js.map +1 -1
  487. package/dist/core/capabilities/realizes/findings.js +12 -19
  488. package/dist/core/capabilities/realizes/findings.js.map +1 -1
  489. package/dist/core/capabilities/realizes/join.js +0 -20
  490. package/dist/core/capabilities/realizes/join.js.map +1 -1
  491. package/dist/core/capabilities/rollup.js +6 -0
  492. package/dist/core/capabilities/rollup.js.map +1 -1
  493. package/dist/core/capabilities/tree.js +6 -28
  494. package/dist/core/capabilities/tree.js.map +1 -1
  495. package/dist/core/capabilities/usecase-join.js +3 -13
  496. package/dist/core/capabilities/usecase-join.js.map +1 -1
  497. package/dist/core/coherence/authoring/scaffold.js +11 -3
  498. package/dist/core/coherence/authoring/scaffold.js.map +1 -1
  499. package/dist/core/coherence/authoring/sentinels.js +2 -1
  500. package/dist/core/coherence/authoring/sentinels.js.map +1 -1
  501. package/dist/core/coherence/calls/called.js +52 -0
  502. package/dist/core/coherence/calls/called.js.map +1 -0
  503. package/dist/core/coherence/coherence.js +103 -22
  504. package/dist/core/coherence/coherence.js.map +1 -1
  505. package/dist/core/coherence/consumed/operations.js +70 -0
  506. package/dist/core/coherence/consumed/operations.js.map +1 -0
  507. package/dist/core/coherence/consumed/refusal.js +38 -0
  508. package/dist/core/coherence/consumed/refusal.js.map +1 -0
  509. package/dist/core/coherence/covers/health.js +85 -0
  510. package/dist/core/coherence/covers/health.js.map +1 -0
  511. package/dist/core/coherence/declared.js +60 -34
  512. package/dist/core/coherence/declared.js.map +1 -1
  513. package/dist/core/coherence/events/declared.js +44 -59
  514. package/dist/core/coherence/events/declared.js.map +1 -1
  515. package/dist/core/coherence/events/events.js +147 -16
  516. package/dist/core/coherence/events/events.js.map +1 -1
  517. package/dist/core/coherence/events/grades.js +31 -8
  518. package/dist/core/coherence/events/grades.js.map +1 -1
  519. package/dist/core/coherence/events/lookups.js +28 -87
  520. package/dist/core/coherence/events/lookups.js.map +1 -1
  521. package/dist/core/coherence/events/produced.js +100 -0
  522. package/dist/core/coherence/events/produced.js.map +1 -0
  523. package/dist/core/coherence/lookups.js +18 -78
  524. package/dist/core/coherence/lookups.js.map +1 -1
  525. package/dist/core/coherence/retired/archived.js +285 -0
  526. package/dist/core/coherence/retired/archived.js.map +1 -0
  527. package/dist/core/coherence/retired/event-pair.js +62 -0
  528. package/dist/core/coherence/retired/event-pair.js.map +1 -0
  529. package/dist/core/coherence/retired/merged.js +79 -0
  530. package/dist/core/coherence/retired/merged.js.map +1 -0
  531. package/dist/core/coherence/retired/retirement.js +49 -0
  532. package/dist/core/coherence/retired/retirement.js.map +1 -0
  533. package/dist/core/coherence/retired/revival/arrivals.js +131 -0
  534. package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
  535. package/dist/core/coherence/retired/revival/revived.js +297 -0
  536. package/dist/core/coherence/retired/revival/revived.js.map +1 -0
  537. package/dist/core/consumers/after.js +113 -0
  538. package/dist/core/consumers/after.js.map +1 -0
  539. package/dist/core/consumers/consumers.js +296 -0
  540. package/dist/core/consumers/consumers.js.map +1 -0
  541. package/dist/core/consumers/current.js +211 -0
  542. package/dist/core/consumers/current.js.map +1 -0
  543. package/dist/core/consumers/scan.js +46 -0
  544. package/dist/core/consumers/scan.js.map +1 -0
  545. package/dist/core/consumers/state.js +27 -0
  546. package/dist/core/consumers/state.js.map +1 -0
  547. package/dist/core/delta/delta.js +51 -6
  548. package/dist/core/delta/delta.js.map +1 -1
  549. package/dist/core/dependencies/fanin.js +2 -2
  550. package/dist/core/dependencies/fanin.js.map +1 -1
  551. package/dist/core/deployment/delta.js +191 -0
  552. package/dist/core/deployment/delta.js.map +1 -0
  553. package/dist/core/deployment/objects.js +145 -0
  554. package/dist/core/deployment/objects.js.map +1 -0
  555. package/dist/core/diff/base-git.js +94 -12
  556. package/dist/core/diff/base-git.js.map +1 -1
  557. package/dist/core/diff/base-state.js +49 -21
  558. package/dist/core/diff/base-state.js.map +1 -1
  559. package/dist/core/diff/joins.js +136 -0
  560. package/dist/core/diff/joins.js.map +1 -0
  561. package/dist/core/diff/scope/changed-paths.js +22 -6
  562. package/dist/core/diff/scope/changed-paths.js.map +1 -1
  563. package/dist/core/diff/scope/edges.js +82 -0
  564. package/dist/core/diff/scope/edges.js.map +1 -0
  565. package/dist/core/diff/semantic.js +100 -31
  566. package/dist/core/diff/semantic.js.map +1 -1
  567. package/dist/core/docs.js +31 -22
  568. package/dist/core/docs.js.map +1 -1
  569. package/dist/core/doctor/agents.js +34 -18
  570. package/dist/core/doctor/agents.js.map +1 -1
  571. package/dist/core/doctor/config.js +7 -3
  572. package/dist/core/doctor/config.js.map +1 -1
  573. package/dist/core/doctor/doctor.js +91 -11
  574. package/dist/core/doctor/doctor.js.map +1 -1
  575. package/dist/core/doctor/report.js.map +1 -1
  576. package/dist/core/doctor/reports/scan.js +242 -0
  577. package/dist/core/doctor/reports/scan.js.map +1 -0
  578. package/dist/core/document/apply.js +158 -11
  579. package/dist/core/document/apply.js.map +1 -1
  580. package/dist/core/document/frontmatter.js +55 -0
  581. package/dist/core/document/frontmatter.js.map +1 -1
  582. package/dist/core/document/parse.js +29 -6
  583. package/dist/core/document/parse.js.map +1 -1
  584. package/dist/core/document/scenarios.js +17 -0
  585. package/dist/core/document/scenarios.js.map +1 -1
  586. package/dist/core/document/spec.js +4 -11
  587. package/dist/core/document/spec.js.map +1 -1
  588. package/dist/core/envelope/config.js +10 -0
  589. package/dist/core/envelope/config.js.map +1 -1
  590. package/dist/core/envelope/json.js +34 -0
  591. package/dist/core/envelope/json.js.map +1 -1
  592. package/dist/core/explain/families.js +26 -21
  593. package/dist/core/explain/families.js.map +1 -1
  594. package/dist/core/explain/lookup.js +14 -1
  595. package/dist/core/explain/lookup.js.map +1 -1
  596. package/dist/core/explain/refusals.js +5 -5
  597. package/dist/core/explain/refusals.js.map +1 -1
  598. package/dist/core/explain/terms/documents.js +227 -0
  599. package/dist/core/explain/terms/documents.js.map +1 -0
  600. package/dist/core/explain/terms/done-check.js +144 -0
  601. package/dist/core/explain/terms/done-check.js.map +1 -0
  602. package/dist/core/explain/terms/entry.js +14 -0
  603. package/dist/core/explain/terms/entry.js.map +1 -0
  604. package/dist/core/explain/terms/stages.js +71 -0
  605. package/dist/core/explain/terms/stages.js.map +1 -0
  606. package/dist/core/explain/terms/tasks.js +97 -0
  607. package/dist/core/explain/terms/tasks.js.map +1 -0
  608. package/dist/core/explain/terms.js +68 -109
  609. package/dist/core/explain/terms.js.map +1 -1
  610. package/dist/core/explore/explore.js +40 -10
  611. package/dist/core/explore/explore.js.map +1 -1
  612. package/dist/core/fleet-context.js +81 -95
  613. package/dist/core/fleet-context.js.map +1 -1
  614. package/dist/core/gate/checks.js +11 -4
  615. package/dist/core/gate/checks.js.map +1 -1
  616. package/dist/core/gate/partners.js +69 -28
  617. package/dist/core/gate/partners.js.map +1 -1
  618. package/dist/core/gate/report.js.map +1 -1
  619. package/dist/core/gate/verification.js +75 -12
  620. package/dist/core/gate/verification.js.map +1 -1
  621. package/dist/core/gherkin/stale.js +13 -37
  622. package/dist/core/gherkin/stale.js.map +1 -1
  623. package/dist/core/glossary/delta.js +10 -7
  624. package/dist/core/glossary/delta.js.map +1 -1
  625. package/dist/core/glossary/tree.js +6 -19
  626. package/dist/core/glossary/tree.js.map +1 -1
  627. package/dist/core/kernel/concurrency.js +19 -0
  628. package/dist/core/kernel/concurrency.js.map +1 -1
  629. package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
  630. package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
  631. package/dist/core/kernel/path-safety.js +38 -0
  632. package/dist/core/kernel/path-safety.js.map +1 -1
  633. package/dist/core/kernel/records.js +11 -0
  634. package/dist/core/kernel/records.js.map +1 -1
  635. package/dist/core/links/backlinks.js +1 -3
  636. package/dist/core/links/backlinks.js.map +1 -1
  637. package/dist/core/links/corpus.js +51 -37
  638. package/dist/core/links/corpus.js.map +1 -1
  639. package/dist/core/links/findings.js.map +1 -1
  640. package/dist/core/links/parse.js +38 -9
  641. package/dist/core/links/parse.js.map +1 -1
  642. package/dist/core/mcp/argv.js +101 -0
  643. package/dist/core/mcp/argv.js.map +1 -1
  644. package/dist/core/mcp/author-tools.js +2 -1
  645. package/dist/core/mcp/author-tools.js.map +1 -1
  646. package/dist/core/mcp/protocol.js +2 -2
  647. package/dist/core/mcp/protocol.js.map +1 -1
  648. package/dist/core/mcp/tools.js +43 -33
  649. package/dist/core/mcp/tools.js.map +1 -1
  650. package/dist/core/openapi/baseline/gate.js +53 -12
  651. package/dist/core/openapi/baseline/gate.js.map +1 -1
  652. package/dist/core/openapi/baseline/plan.js +40 -10
  653. package/dist/core/openapi/baseline/plan.js.map +1 -1
  654. package/dist/core/openapi/baseline/record.js +0 -1
  655. package/dist/core/openapi/baseline/record.js.map +1 -1
  656. package/dist/core/openapi/contract-text.js +33 -0
  657. package/dist/core/openapi/contract-text.js.map +1 -0
  658. package/dist/core/openapi/contract-tree.js +301 -0
  659. package/dist/core/openapi/contract-tree.js.map +1 -0
  660. package/dist/core/openapi/depth.js +38 -24
  661. package/dist/core/openapi/depth.js.map +1 -1
  662. package/dist/core/openapi/digest.js +52 -2
  663. package/dist/core/openapi/digest.js.map +1 -1
  664. package/dist/core/openapi/doc.js +12 -4
  665. package/dist/core/openapi/doc.js.map +1 -1
  666. package/dist/core/openapi/merge/components.js +25 -60
  667. package/dist/core/openapi/merge/components.js.map +1 -1
  668. package/dist/core/openapi/merge/error.js +3 -13
  669. package/dist/core/openapi/merge/error.js.map +1 -1
  670. package/dist/core/openapi/merge/markers.js +26 -30
  671. package/dist/core/openapi/merge/markers.js.map +1 -1
  672. package/dist/core/openapi/merge/merge.js +28 -52
  673. package/dist/core/openapi/merge/merge.js.map +1 -1
  674. package/dist/core/openapi/merge/pin.js +17 -35
  675. package/dist/core/openapi/merge/pin.js.map +1 -1
  676. package/dist/core/openspec/decide/verdict.js.map +1 -1
  677. package/dist/core/openspec/inventory.js +4 -5
  678. package/dist/core/openspec/inventory.js.map +1 -1
  679. package/dist/core/openspec/model/mapping.js +30 -28
  680. package/dist/core/openspec/model/mapping.js.map +1 -1
  681. package/dist/core/openspec/model/model.js +12 -7
  682. package/dist/core/openspec/model/model.js.map +1 -1
  683. package/dist/core/openspec/scan/changes.js +10 -4
  684. package/dist/core/openspec/scan/changes.js.map +1 -1
  685. package/dist/core/openspec/scan/config.js +7 -16
  686. package/dist/core/openspec/scan/config.js.map +1 -1
  687. package/dist/core/openspec/scan/shape.js +63 -19
  688. package/dist/core/openspec/scan/shape.js.map +1 -1
  689. package/dist/core/openspec/scan/walk.js +21 -38
  690. package/dist/core/openspec/scan/walk.js.map +1 -1
  691. package/dist/core/pack/living.js +43 -4
  692. package/dist/core/pack/living.js.map +1 -1
  693. package/dist/core/pack/pack.js +50 -6
  694. package/dist/core/pack/pack.js.map +1 -1
  695. package/dist/core/projection/arch-slice.js +2 -2
  696. package/dist/core/projection/arch-slice.js.map +1 -1
  697. package/dist/core/projection/introduced.js +14 -0
  698. package/dist/core/projection/introduced.js.map +1 -0
  699. package/dist/core/provenance/findings.js +48 -12
  700. package/dist/core/provenance/findings.js.map +1 -1
  701. package/dist/core/provenance/git.js +33 -57
  702. package/dist/core/provenance/git.js.map +1 -1
  703. package/dist/core/provenance/gitq/moves.js +71 -114
  704. package/dist/core/provenance/gitq/moves.js.map +1 -1
  705. package/dist/core/provenance/gitq/vouched-ancestor.js +2 -2
  706. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -1
  707. package/dist/core/provenance/sources.js +23 -6
  708. package/dist/core/provenance/sources.js.map +1 -1
  709. package/dist/core/provenance/stamp.js +5 -17
  710. package/dist/core/provenance/stamp.js.map +1 -1
  711. package/dist/core/repo/authored/paths.js +18 -0
  712. package/dist/core/repo/authored/paths.js.map +1 -1
  713. package/dist/core/repo/entries.js.map +1 -1
  714. package/dist/core/repo/paths.js +92 -6
  715. package/dist/core/repo/paths.js.map +1 -1
  716. package/dist/core/repo/repo.js +74 -14
  717. package/dist/core/repo/repo.js.map +1 -1
  718. package/dist/core/repo/tree/find.js +12 -3
  719. package/dist/core/repo/tree/find.js.map +1 -1
  720. package/dist/core/repo/tree/fs.js +27 -1
  721. package/dist/core/repo/tree/fs.js.map +1 -1
  722. package/dist/core/repo/tree/render/body.js +258 -0
  723. package/dist/core/repo/tree/render/body.js.map +1 -0
  724. package/dist/core/repo/tree/render/projects.js +182 -0
  725. package/dist/core/repo/tree/render/projects.js.map +1 -0
  726. package/dist/core/repo/tree/render/service/header.js +125 -0
  727. package/dist/core/repo/tree/render/service/header.js.map +1 -0
  728. package/dist/core/repo/tree/render/service/peers.js +28 -0
  729. package/dist/core/repo/tree/render/service/peers.js.map +1 -0
  730. package/dist/core/repo/tree/render/service/view-id.js +67 -0
  731. package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
  732. package/dist/core/repo/tree/render/service/views.js +78 -0
  733. package/dist/core/repo/tree/render/service/views.js.map +1 -0
  734. package/dist/core/repo/tree/render/stale.js +42 -0
  735. package/dist/core/repo/tree/render/stale.js.map +1 -0
  736. package/dist/core/repo/tree/render/text.js +84 -0
  737. package/dist/core/repo/tree/render/text.js.map +1 -0
  738. package/dist/core/repo/tree/render/views.js +293 -0
  739. package/dist/core/repo/tree/render/views.js.map +1 -0
  740. package/dist/core/repo/tree/walk.js +53 -32
  741. package/dist/core/repo/tree/walk.js.map +1 -1
  742. package/dist/core/results.js +47 -12
  743. package/dist/core/results.js.map +1 -1
  744. package/dist/core/scaffold/landscape.js +121 -13
  745. package/dist/core/scaffold/landscape.js.map +1 -1
  746. package/dist/core/scaffold/legacy.js +271 -0
  747. package/dist/core/scaffold/legacy.js.map +1 -0
  748. package/dist/core/staging/commit.js +26 -15
  749. package/dist/core/staging/commit.js.map +1 -1
  750. package/dist/core/staging/lock.js +74 -12
  751. package/dist/core/staging/lock.js.map +1 -1
  752. package/dist/core/staging/recovery/intent.js +2 -5
  753. package/dist/core/staging/recovery/intent.js.map +1 -1
  754. package/dist/core/staging/recovery/recover.js +84 -6
  755. package/dist/core/staging/recovery/recover.js.map +1 -1
  756. package/dist/core/staging/snapshot/manifest.js +188 -0
  757. package/dist/core/staging/snapshot/manifest.js.map +1 -0
  758. package/dist/core/staging/{snapshot.js → snapshot/snapshot.js} +39 -45
  759. package/dist/core/staging/snapshot/snapshot.js.map +1 -0
  760. package/dist/core/staging/txn/forward.js +24 -14
  761. package/dist/core/staging/txn/forward.js.map +1 -1
  762. package/dist/core/staging/writes.js.map +1 -1
  763. package/dist/core/status/actions/execution.js +11 -0
  764. package/dist/core/status/actions/execution.js.map +1 -1
  765. package/dist/core/status/contracts.js +39 -15
  766. package/dist/core/status/contracts.js.map +1 -1
  767. package/dist/core/status/feature/artifacts.js +33 -8
  768. package/dist/core/status/feature/artifacts.js.map +1 -1
  769. package/dist/core/status/feature/feature.js +24 -17
  770. package/dist/core/status/feature/feature.js.map +1 -1
  771. package/dist/core/status/feature/next.js +20 -7
  772. package/dist/core/status/feature/next.js.map +1 -1
  773. package/dist/core/status/feature/words.js +96 -0
  774. package/dist/core/status/feature/words.js.map +1 -0
  775. package/dist/core/status/fleet/fleet.js +43 -14
  776. package/dist/core/status/fleet/fleet.js.map +1 -1
  777. package/dist/core/status/fleet/next.js +153 -58
  778. package/dist/core/status/fleet/next.js.map +1 -1
  779. package/dist/core/status/report.js.map +1 -1
  780. package/dist/core/status/scan.js.map +1 -1
  781. package/dist/core/status/verification.js +30 -15
  782. package/dist/core/status/verification.js.map +1 -1
  783. package/dist/core/tasks/packet.js +199 -0
  784. package/dist/core/tasks/packet.js.map +1 -0
  785. package/dist/core/tasks/record.js +43 -0
  786. package/dist/core/tasks/record.js.map +1 -0
  787. package/dist/core/tasks/sources.js +181 -0
  788. package/dist/core/tasks/sources.js.map +1 -0
  789. package/dist/core/tasks/stamps.js +76 -0
  790. package/dist/core/tasks/stamps.js.map +1 -0
  791. package/dist/core/tasks/unit.js +0 -0
  792. package/dist/core/tasks/unit.js.map +1 -0
  793. package/dist/core/usecases/capability.js +11 -14
  794. package/dist/core/usecases/capability.js.map +1 -1
  795. package/dist/core/usecases/delta/claims.js +31 -7
  796. package/dist/core/usecases/delta/claims.js.map +1 -1
  797. package/dist/core/usecases/delta/flows.js +5 -7
  798. package/dist/core/usecases/delta/flows.js.map +1 -1
  799. package/dist/core/usecases/delta/modified.js +315 -0
  800. package/dist/core/usecases/delta/modified.js.map +1 -0
  801. package/dist/core/usecases/delta/overlay.js +32 -191
  802. package/dist/core/usecases/delta/overlay.js.map +1 -1
  803. package/dist/core/usecases/fleet.js +195 -36
  804. package/dist/core/usecases/fleet.js.map +1 -1
  805. package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/capability-tag.js +8 -9
  806. package/dist/core/usecases/grade/capability-tag.js.map +1 -0
  807. package/dist/core/usecases/grade/feature.js +88 -0
  808. package/dist/core/usecases/grade/feature.js.map +1 -0
  809. package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/requirement-tag.js +3 -4
  810. package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
  811. package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/steps.js +102 -33
  812. package/dist/core/usecases/grade/steps.js.map +1 -0
  813. package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/usecases.js +23 -10
  814. package/dist/core/usecases/grade/usecases.js.map +1 -0
  815. package/dist/core/usecases/operations.js +26 -14
  816. package/dist/core/usecases/operations.js.map +1 -1
  817. package/dist/core/usecases/place.js.map +1 -1
  818. package/dist/core/usecases/service/exclude.js +119 -0
  819. package/dist/core/usecases/service/exclude.js.map +1 -0
  820. package/dist/core/usecases/service/flows.js +164 -0
  821. package/dist/core/usecases/service/flows.js.map +1 -0
  822. package/dist/core/usecases/suites/participants.js +83 -0
  823. package/dist/core/usecases/suites/participants.js.map +1 -0
  824. package/dist/core/usecases/suites/suites.js +45 -0
  825. package/dist/core/usecases/suites/suites.js.map +1 -0
  826. package/dist/core/verify/answers.js +12 -5
  827. package/dist/core/verify/answers.js.map +1 -1
  828. package/dist/core/verify/build.js +102 -82
  829. package/dist/core/verify/build.js.map +1 -1
  830. package/dist/core/verify/checklist.js +70 -12
  831. package/dist/core/verify/checklist.js.map +1 -1
  832. package/dist/core/verify/location.js +67 -0
  833. package/dist/core/verify/location.js.map +1 -0
  834. package/dist/core/verify/pins/lint.js +3 -2
  835. package/dist/core/verify/pins/lint.js.map +1 -1
  836. package/dist/core/verify/pins/pin.js +1 -1
  837. package/dist/core/verify/pins/pin.js.map +1 -1
  838. package/dist/core/verify/read/file.js +224 -0
  839. package/dist/core/verify/read/file.js.map +1 -0
  840. package/dist/core/verify/{file.js → read/shape.js} +16 -104
  841. package/dist/core/verify/read/shape.js.map +1 -0
  842. package/dist/core/verify/read/union.js +105 -0
  843. package/dist/core/verify/read/union.js.map +1 -0
  844. package/dist/core/verify/record.js +35 -12
  845. package/dist/core/verify/record.js.map +1 -1
  846. package/dist/core/verify/store/commit.js +40 -30
  847. package/dist/core/verify/store/commit.js.map +1 -1
  848. package/dist/core/verify/store/render.js +8 -4
  849. package/dist/core/verify/store/render.js.map +1 -1
  850. package/dist/core/vocabulary/issue.js +4 -0
  851. package/dist/core/vocabulary/issue.js.map +1 -1
  852. package/dist/core/vocabulary/maturity.js +75 -4
  853. package/dist/core/vocabulary/maturity.js.map +1 -1
  854. package/dist/core/vocabulary/report.js +16 -1
  855. package/dist/core/vocabulary/report.js.map +1 -1
  856. package/examples/README.md +54 -11
  857. package/examples/docs/architecture/landscape.likec4 +62 -6
  858. package/examples/docs/architecture/services.likec4 +70 -0
  859. package/examples/docs/architecture/subsystems.likec4 +7 -0
  860. package/examples/docs/architecture/usecases/order-notification.likec4 +16 -7
  861. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +11 -8
  862. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +6 -6
  863. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +4 -1
  864. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +13 -10
  865. package/examples/docs/likec4.config.json +0 -1
  866. package/examples/docs/services/checkout-web/model.likec4 +39 -56
  867. package/examples/docs/services/order-service/arch.spec.md +13 -6
  868. package/examples/docs/services/order-service/asyncapi.yaml +3 -2
  869. package/examples/docs/services/order-service/model.likec4 +58 -70
  870. package/examples/docs/services/payment-service/arch.spec.md +7 -4
  871. package/examples/docs/services/payment-service/model.likec4 +38 -37
  872. package/examples/docs/services/platform/identity-service/arch.spec.md +7 -4
  873. package/examples/docs/services/platform/identity-service/model.likec4 +35 -37
  874. package/examples/docs/services/platform/notification-service/asyncapi.yaml +2 -1
  875. package/examples/docs/services/platform/notification-service/health.yaml +8 -3
  876. package/examples/docs/services/platform/notification-service/model.likec4 +43 -64
  877. package/package.json +1 -1
  878. package/dist/commands/validate/checks/vocabulary.js +0 -31
  879. package/dist/commands/validate/checks/vocabulary.js.map +0 -1
  880. package/dist/commands/validate/fleet/usecases/capability-tag.js.map +0 -1
  881. package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +0 -1
  882. package/dist/commands/validate/fleet/usecases/steps.js.map +0 -1
  883. package/dist/commands/validate/fleet/usecases/usecases.js.map +0 -1
  884. package/dist/core/agent/agents-md/artifacts.js +0 -220
  885. package/dist/core/agent/agents-md/artifacts.js.map +0 -1
  886. package/dist/core/agent/agents-md/cycle.js +0 -165
  887. package/dist/core/agent/agents-md/cycle.js.map +0 -1
  888. package/dist/core/agent/agents-md/shipped/archive-gate.js +0 -98
  889. package/dist/core/agent/agents-md/shipped/archive-gate.js.map +0 -1
  890. package/dist/core/agent/agents-md/spine.js +0 -40
  891. package/dist/core/agent/agents-md/spine.js.map +0 -1
  892. package/dist/core/coherence/events/merged.js +0 -40
  893. package/dist/core/coherence/events/merged.js.map +0 -1
  894. package/dist/core/diff/current-state.js +0 -96
  895. package/dist/core/diff/current-state.js.map +0 -1
  896. package/dist/core/diff/victims.js +0 -247
  897. package/dist/core/diff/victims.js.map +0 -1
  898. package/dist/core/repo/tree/views.js +0 -172
  899. package/dist/core/repo/tree/views.js.map +0 -1
  900. package/dist/core/staging/snapshot.js.map +0 -1
  901. package/dist/core/verify/file.js.map +0 -1
@@ -1,35 +1,21 @@
1
- // Per-service C4. Written by an agent from the `loam adopt` brief, then curated.
1
+ // notification-service's own C4 — what is INSIDE the element the fleet map binds
2
+ // to services/platform/notification-service/. Written by an agent from the
3
+ // `loam adopt` brief, then curated.
2
4
  //
3
- // Every .likec4 file is parsed ALONE, so the kinds this document uses have to be
4
- // declared in this document: a `specification` block here is not a duplicate of
5
- // the landscape's, it is what makes this file readable without it.
6
- specification {
7
- element softwareSystem
8
- element container
9
- element database
10
- // Declared because the consumption edges below point at CHANNELS rather than
11
- // at the broker. Three edges into one `kafka` box would say only "talks to
12
- // kafka"; three edges into three topics say which contracts this service is
13
- // standing on, and they line up one-for-one with the channels in
14
- // asyncapi.yaml.
15
- element topic {
16
- style {
17
- shape queue
18
- }
19
- }
20
- }
21
-
5
+ // An EXTENDING model: no `specification` block, no partner copies. The topics
6
+ // this service consumes — `kafka.orderEvents`, `kafka.paymentEvents`,
7
+ // `kafka.crmEvents` — are the MAP's, declared there once with the `topic` kind
8
+ // that carries `#external` and `#platform`; this file points at them. So is
9
+ // `notificationProvider`, the third-party gateway: a system this service reaches
10
+ // belongs in architecture/landscape.likec4, and declaring a copy of it here
11
+ // would be `c4.element-unowned`. `extend` takes the fully-qualified id because
12
+ // the element is nested in the `marketplace` group.
13
+ //
14
+ // SCHEMA.md, "Two shapes of a service model", has the standalone shape — a model
15
+ // that declares its own `specification` and is therefore parsed alone — and the
16
+ // ordered recipe for migrating one to this shape.
22
17
  model {
23
- notificationService = softwareSystem 'notification-service' {
24
- description 'Turns fleet events into customer email and SMS'
25
- // The binding, not the title, is what ties this element to
26
- // services/notification-service/. With only a title, renaming the box in a
27
- // diagram silently detaches every join that runs through it — health.yaml's
28
- // dependencies, `Covers:` entries, the landscape's service checks.
29
- metadata {
30
- service 'notification-service'
31
- }
32
-
18
+ extend marketplace.notificationService {
33
19
  consumer = container 'consumer' {
34
20
  description 'Kafka consumer group; one handler per message name'
35
21
  technology 'Go'
@@ -39,11 +25,10 @@ model {
39
25
  technology 'Go'
40
26
  }
41
27
  // Both stores are nested INSIDE the service and neither is drawn beside it
42
- // in the landscape: a store with one consumer drawn as a fleet-level peer
43
- // reads as a system other services may depend on, which is what
44
- // `landscape.datastore-private` pushes back on. Neither appears in
45
- // health.yaml's dependencies either — they share this service's lifecycle
46
- // rather than being something it reaches across a boundary.
28
+ // in the landscape — the example's choice, and one loam does not grade
29
+ // either way. Neither appears in health.yaml's dependencies either: they
30
+ // share this service's lifecycle rather than being something it reaches
31
+ // across a boundary, and that is the fact the nesting is drawn from.
47
32
  deliveryLog = database 'delivery-log' {
48
33
  description 'One row per (message id, channel) — the idempotency key that makes redelivery a no-op — carrying the orderId and customer each send was addressed to, so a receipt can find its order and a capture that arrives first has somewhere to wait'
49
34
  technology 'PostgreSQL'
@@ -67,30 +52,12 @@ model {
67
52
  sender -> deliveryLog 'Records delivered / failed'
68
53
  }
69
54
 
70
- // Everything the service touches belongs in its own model, cross-boundary
71
- // dependencies included — the landscape carries only the boundary crossing.
72
- // health.yaml names `kafka` as a critical dependency and that id has to resolve
73
- // HERE, by element id, `metadata { service }` binding or title
74
- // (`health.dependency-unmodelled` otherwise); and a model with elements and no
75
- // edges beside a health.yaml that declares dependencies is `c4.no-relationships`
76
- // — a service that reaches nothing is almost never true.
77
- kafka = softwareSystem 'kafka' {
78
- description 'Event backbone (platform)'
79
- orderEvents = topic 'order.events'
80
- paymentEvents = topic 'payment.events'
81
- crmEvents = topic 'crm.events'
82
- }
83
-
84
- // The second thing this service reaches across its own boundary, and the one
85
- // the runbook spends an incident section on: while the provider is down or
86
- // throttling, nothing is delivered and there is no fallback path. It belongs
87
- // here for the same reason payment-service's model draws `stripe` — a model
88
- // that stopped at the broker would show a worker whose only failure mode is
89
- // lag, which is the half of the picture the on-call graphs already give you.
90
- provider = softwareSystem 'notification-provider' {
91
- description 'Third-party email and SMS gateway — quota-limited, and outside this fleet'
92
- }
93
-
55
+ // The three channels this service takes messages off, pointing at the map's
56
+ // topics. health.yaml names `kafka` as a critical dependency and that id has to
57
+ // resolve through this model (`health.dependency-unmodelled` otherwise): it
58
+ // does, because a partner brings its ANCESTORS with it — the edges name the
59
+ // topics and the broker answers for them.
60
+ //
94
61
  // No `metadata { consumes }` on these edges, and adding it would change
95
62
  // nothing: loam reads the event spine off `architecture/landscape.likec4`
96
63
  // alone, never off a service model. What resolves a consumed name against
@@ -104,15 +71,27 @@ model {
104
71
  // Drawn topic → consumer, the direction the landscape uses and the one the
105
72
  // event spine requires there: `consumes` binds the edge's TARGET, so the same
106
73
  // edge drawn the other way round binds to nothing at all.
107
- kafka.orderEvents -> notificationService.consumer 'OrderPlaced triggers the confirmation'
108
- kafka.paymentEvents -> notificationService.consumer 'PaymentCaptured triggers the receipt'
109
- kafka.crmEvents -> notificationService.consumer 'CustomerUpdated refreshes contact details'
74
+ kafka.orderEvents -> marketplace.notificationService.consumer 'OrderPlaced triggers the confirmation'
75
+ kafka.paymentEvents -> marketplace.notificationService.consumer 'PaymentCaptured triggers the receipt'
76
+ kafka.crmEvents -> marketplace.notificationService.consumer 'CustomerUpdated refreshes contact details'
110
77
 
111
- notificationService.sender -> provider 'Sends email and SMS, and backs off on 429'
78
+ // The second thing this service reaches across its own boundary, and the one
79
+ // the runbook spends an incident section on: while the provider is down or
80
+ // throttling, nothing is delivered and there is no fallback path. Its element
81
+ // is the map's, and the map also carries the SERVICE-level twin of this edge
82
+ // (`marketplace.notificationService -> notificationProvider`), because every
83
+ // fleet check reads the map alone. The cross-boundary call is written twice on
84
+ // purpose — container-level here, service-level there — and that remainder is
85
+ // recorded in ROADMAP.md rather than hidden.
86
+ marketplace.notificationService.sender -> notificationProvider 'Sends email and SMS, and backs off on 429'
112
87
  }
113
88
 
89
+ // Views belong to LikeC4's renderer; no loam check reads anything below. This
90
+ // file is part of the root project, so `npx likec4 start` at the docs root draws
91
+ // this view beside the fleet map — there is no per-service likec4.config.json,
92
+ // and loam never writes one beside an extending model.
114
93
  views {
115
- view notification_service of notificationService {
94
+ view notification_service of marketplace.notificationService {
116
95
  include *
117
96
  }
118
97
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ybotok/loam",
3
- "version": "0.2.0-alpha.1",
3
+ "version": "0.2.0-alpha.13",
4
4
  "description": "Architecture-first semantic integrity and change governance for evolving software systems: connect C4, requirements, contracts, and verification evidence.",
5
5
  "author": "spentsov",
6
6
  "repository": {
@@ -1,31 +0,0 @@
1
- /**
2
- * The handful of facts every validate check speaks, and none of them owns.
3
- *
4
- * A leaf module rather than a paragraph beside its first caller, because the
5
- * checks are spread across packages and each of these is read from more than
6
- * one of them: the dispatcher's rollup and the service target's sources check
7
- * both name one finding code, and several targets render parser diagnostics
8
- * the same way. ACTOR_KINDS and EXTERNAL_TAG lived here too, until they
9
- * reached a third copy (`core/gate/partners.ts`, `core/verify/checklist.ts`);
10
- * their shared spelling is now `core/vocabulary/maturity.ts`, beside the
11
- * landscape evidence that asks the same questions.
12
- */
13
- import {} from "../../../core/c4/likec4.js";
14
- /** The one code the rollup line counts; spelled once so the two cannot drift. */
15
- export const UNVERIFIABLE = "sources.unverifiable-from-here";
16
- /**
17
- * One parser diagnostic as a finding's evidence line: `L12:` when the parser
18
- * knew a line, because that lets a reader open the file at the fault instead of
19
- * searching for it.
20
- *
21
- * Three other modules hand-roll the same ternary (`commands/show.ts`,
22
- * `commands/delta.ts`, `core/c4/splice/landscape-merge.ts`). All four belong
23
- * beside `LikeC4Error` in `core/c4/likec4.ts`. That used to be blocked by the
24
- * file limit — nine lines of headroom — and is not any more: moving the resolver
25
- * out to `core/c4/resolve/service.ts` left the loader around 100 lines under.
26
- * The consolidation is now unblocked and simply owed.
27
- */
28
- export function errorText(e) {
29
- return typeof e.line === "number" ? `L${e.line}: ${e.message}` : e.message;
30
- }
31
- //# sourceMappingURL=vocabulary.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vocabulary.js","sourceRoot":"","sources":["../../../../src/commands/validate/checks/vocabulary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAoB,MAAM,4BAA4B,CAAC;AAE9D,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GAAG,gCAAgC,CAAC;AAE7D;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS,CAAC,CAAc;IACtC,OAAO,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAC7E,CAAC","sourcesContent":["/**\n * The handful of facts every validate check speaks, and none of them owns.\n *\n * A leaf module rather than a paragraph beside its first caller, because the\n * checks are spread across packages and each of these is read from more than\n * one of them: the dispatcher's rollup and the service target's sources check\n * both name one finding code, and several targets render parser diagnostics\n * the same way. ACTOR_KINDS and EXTERNAL_TAG lived here too, until they\n * reached a third copy (`core/gate/partners.ts`, `core/verify/checklist.ts`);\n * their shared spelling is now `core/vocabulary/maturity.ts`, beside the\n * landscape evidence that asks the same questions.\n */\nimport { type LikeC4Error } from \"../../../core/c4/likec4.js\";\n\n/** The one code the rollup line counts; spelled once so the two cannot drift. */\nexport const UNVERIFIABLE = \"sources.unverifiable-from-here\";\n\n/**\n * One parser diagnostic as a finding's evidence line: `L12:` when the parser\n * knew a line, because that lets a reader open the file at the fault instead of\n * searching for it.\n *\n * Three other modules hand-roll the same ternary (`commands/show.ts`,\n * `commands/delta.ts`, `core/c4/splice/landscape-merge.ts`). All four belong\n * beside `LikeC4Error` in `core/c4/likec4.ts`. That used to be blocked by the\n * file limit — nine lines of headroom — and is not any more: moving the resolver\n * out to `core/c4/resolve/service.ts` left the loader around 100 lines under.\n * The consolidation is now unblocked and simply owed.\n */\nexport function errorText(e: LikeC4Error): string {\n return typeof e.line === \"number\" ? `L${e.line}: ${e.message}` : e.message;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"capability-tag.js","sourceRoot":"","sources":["../../../../../src/commands/validate/fleet/usecases/capability-tag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EACL,cAAc,EACd,OAAO,GAER,MAAM,+CAA+C,CAAC;AAGvD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,qGAAqG;AACrG,SAAS,QAAQ,CAAC,EAAU;IAC1B,OAAO,GAAG,EAAE,MAAM,cAAc,GAAG,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC;AACpD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,WAAW,CAAC,IAAgB,EAAE,KAAiD;IACtF,MAAM,IAAI,GACR,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;QACpB,CAAC,CAAC,iBAAiB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QAC1D,CAAC,CAAC,kFAAkF,CAAC;IACzF,OAAO,CACL,GAAG,SAAS,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,GAAG,kCAAkC;QAC5E,+CAA+C,KAAK,CAAC,IAAI,MAAM,IAAI,GAAG;QACtE,mIAAmI,CACpI,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,IAAgB,EAAE,KAAiD;IACtF,OAAO,CACL,GAAG,SAAS,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,GAAG,SAAS,KAAK,CAAC,GAAG,CAAC,MAAM,oCAAoC;QACvG,IAAI,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,mEAAmE;QAC3G,0GAA0G;QAC1G,2GAA2G;QAC3G,qBAAqB,CACtB,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAgB,EAAE,MAAkC;IACxF,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;YAAE,SAAS;QACxC,QAAQ,CAAC,IAAI,CAAC;YACZ,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,+BAA+B;YACrC,wEAAwE;YACxE,0EAA0E;YAC1E,aAAa;YACb,OAAO,EAAE,IAAI,CAAC,EAAE;YAChB,OAAO,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC;SACrF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["/**\n * `usecase.capability-unresolved` — the `#cap-` tag that names no declared\n * capability, or more than one.\n *\n * The join itself lives in `core/capabilities/usecase-join.ts` and none of it is\n * repeated here: this module owns the grade and the sentence, nothing else. That\n * split is why the tag can answer \"many\" at all — the slug is not injective, so\n * `payments/refunds` and `payments-refunds` both flatten to\n * `payments-refunds` — and why the close candidates a message offers are real\n * declared ids rather than loam's flattened spelling of them.\n *\n * ERROR, the same grade `capability.unknown` carries on a `Capability:` line and\n * for its reason: an invented capability reads exactly like a real one. Here it\n * reads that way at flow altitude — the tag is what files a whole business\n * sequence under an owner, so a claim that resolves to nothing produces a use\n * case nobody can find and a capability nobody can see is realized.\n *\n * SUPPRESSED ENTIRELY when the vocabulary is absent or unreadable: the caller\n * resolves no claims at all in that case, so this answers with nothing. The\n * claims are RESOLVED BY THE CALLER rather than here because the `#req-` grade\n * beside this one is scoped by the very same verdicts, and two resolutions of\n * one view's tags are two chances to disagree about which capability a flow is\n * about. The ladder that produces the suppressing `null` is\n * `gradableCapabilityIds` in `core/capabilities/findings.ts` — one function, called by every site that needs the graded id list, this module's\n * caller in `../landscape.ts` included. The FILE is this axis's opt-in, so a\n * fleet with no `architecture/capabilities.yaml` produces no capability finding\n * at all, and an unreadable one is `capability.invalid` alone rather than one\n * unresolved tag per use case in the fleet, which is a cascade and not a\n * diagnosis. That rule is not re-decided here: a second reading of\n * `CapabilityVocabulary` anywhere in this package is the copy that goes stale\n * the day a fourth un-gradable state is added, so call the function.\n */\nimport {\n CAP_TAG_PREFIX,\n tagSlug,\n type CapabilityClaim,\n} from \"../../../../core/capabilities/usecase-join.js\";\nimport type { ParsedView } from \"../../../../core/c4/parsed/dynamic-views.js\";\nimport type { Finding } from \"../../../../core/vocabulary/report.js\";\nimport { viewPlace } from \"./place.js\";\n\n/** A capability id as an author must write it in a tag: `identity/tokens (#cap-identity-tokens)`. */\nfunction idAndTag(id: string): string {\n return `${id} (#${CAP_TAG_PREFIX}${tagSlug(id)})`;\n}\n\n/**\n * A tag nothing declares, with the close names spelled as TAGS as well as ids.\n *\n * Both spellings, because either alone sends the author somewhere wrong: the id\n * is what `capabilities.yaml` holds and the tag is what the view must carry, and\n * an author handed only `identity/tokens` writes `#cap-identity/tokens`, which\n * LikeC4 refuses to parse. The flattening rule is stated in the same breath so\n * the reader can derive the next one without being told again.\n */\nfunction noneMessage(view: ParsedView, claim: Extract<CapabilityClaim, { kind: \"none\" }>): string {\n const hint =\n claim.close.length > 0\n ? `Did you mean: ${claim.close.map(idAndTag).join(\", \")}?`\n : \"Declare it there (`capabilities: {<id>: {description, owner}}`), or fix the tag.\";\n return (\n `${viewPlace(view)} is tagged #${claim.tag}, and no capability declared in ` +\n `architecture/capabilities.yaml flattens to '${claim.slug}'. ${hint} ` +\n \"A tag spells the id with every character outside `[A-Za-z0-9_-]` flattened to `-`, because that is all a LikeC4 tag name accepts.\"\n );\n}\n\n/**\n * A tag two or more declared ids answer to. Every colliding id is named — a\n * message that stopped at the first would be reporting the ambiguity while\n * hiding half of what makes it one.\n */\nfunction manyMessage(view: ParsedView, claim: Extract<CapabilityClaim, { kind: \"many\" }>): string {\n return (\n `${viewPlace(view)} is tagged #${claim.tag}, and ${claim.ids.length} declared capabilities flatten to ` +\n `'${claim.slug}' (${claim.ids.join(\", \")}) — nothing in the tag can say which one this use case realizes. ` +\n \"Rename one of them in architecture/capabilities.yaml: a guessed capability files every hop of the flow, \" +\n \"and every rollup built over it, under an owner who never claimed it — and the wrong answer looks exactly \" +\n \"like the right one.\"\n );\n}\n\n/**\n * One finding per `#cap-` tag that does not resolve — never one per view.\n *\n * A view may legitimately carry two capability tags (a checkout flow that also\n * issues the identity token realizes both), and `resolveCapabilityTags` answers\n * each on its own terms for that reason. Collapsing them here would either\n * swallow a broken tag beside a working one or lose the capability the view\n * genuinely does realize; one tag, one verdict, one finding keeps both facts.\n */\nexport function capabilityTagFindings(view: ParsedView, claims: readonly CapabilityClaim[]): Finding[] {\n const findings: Finding[] = [];\n for (const claim of claims) {\n if (claim.kind === \"resolved\") continue;\n findings.push({\n severity: \"error\",\n code: \"usecase.capability-unresolved\",\n // The VIEW, not the tag: a subject is what a reader goes and opens, and\n // `subjectsWith` counts one broken use case once however many of its tags\n // are wrong.\n subject: view.id,\n message: claim.kind === \"none\" ? noneMessage(view, claim) : manyMessage(view, claim),\n });\n }\n return findings;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"requirement-tag.js","sourceRoot":"","sources":["../../../../../src/commands/validate/fleet/usecases/requirement-tag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EACL,cAAc,EACd,OAAO,EACP,sBAAsB,GAGvB,MAAM,+CAA+C,CAAC;AAGvD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,0FAA0F;AAC1F,SAAS,QAAQ,CAAC,EAAU;IAC1B,OAAO,GAAG,EAAE,MAAM,cAAc,GAAG,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,SAAS,MAAM,CAAC,KAAsD;IACpE,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,UAAU;YACb,OAAO,KAAK,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC;gBACpC,CAAC,CAAC,oGAAoG;oBAClG,4FAA4F;oBAC5F,qEAAqE;gBACzE,CAAC,CAAC,qBAAqB,KAAK,CAAC,YAAY,CAAC,MAAM,kBAAkB,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;oBAChG,oGAAoG;oBACpG,iGAAiG;oBACjG,mGAAmG,CAAC;QAC5G,KAAK,cAAc;YACjB,OAAO,CACL,eAAe,KAAK,CAAC,UAAU,yCAAyC,KAAK,CAAC,UAAU,YAAY;gBACpG,kGAAkG;gBAClG,4DAA4D,CAC7D,CAAC;QACJ,KAAK,OAAO;YACV,OAAO,CACL,gBAAgB,KAAK,CAAC,UAAU,qDAAqD;gBACrF,qFAAqF,CACtF,CAAC;QACJ,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;gBAC3B,CAAC,CAAC,gBAAgB,KAAK,CAAC,UAAU,mDAAmD,KAAK,CAAC,IAAI,KAAK;oBAChG,iBAAiB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;gBAC5D,CAAC,CAAC,gBAAgB,KAAK,CAAC,UAAU,mDAAmD,KAAK,CAAC,IAAI,MAAM;oBACjG,qDAAqD,CAAC;QAC9D;YACE,OAAO,CACL,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,qBAAqB,KAAK,CAAC,UAAU,iBAAiB,KAAK,CAAC,IAAI,IAAI;gBACvF,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,gEAAgE;gBACxF,mGAAmG;gBACnG,8DAA8D,CAC/D,CAAC;IACN,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAgB,EAChB,MAAkC,EAClC,cAAuE;IAEvE,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvF,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,cAAc,CAAC,EAAE,CAAC;QAC7E,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;YAAE,SAAS;QACxC,QAAQ,CAAC,IAAI,CAAC;YACZ,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,gCAAgC;YACtC,yEAAyE;YACzE,sEAAsE;YACtE,OAAO,EAAE,IAAI,CAAC,EAAE;YAChB,OAAO,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,GAAG,8BAA8B,MAAM,CAAC,KAAK,CAAC,EAAE;SACjG,CAAC,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["/**\n * `usecase.requirement-unresolved` — the `#req-` tag that names no requirement\n * of the capability the view is about.\n *\n * The join lives in `core/capabilities/usecase-join.ts` and none of it is\n * repeated here: this module owns the grade and the sentences. Six arms, six\n * fixes, and they are deliberately the same vocabulary\n * `capability.realizes-unknown` uses for the OTHER carrier of this claim — an\n * author who has learned one set of messages has learned both.\n *\n * ERROR, for `usecase.capability-unresolved`'s reason one join deeper: the tag\n * is the architect's claim that a flow satisfies a named business promise, and a\n * claim that resolves to nothing reads exactly like one that does — in the view,\n * in review, and to anyone asking which flow keeps that promise.\n *\n * AN UNRESOLVED CLAIM SUPPRESSES NOTHING. `capability.requirement-unrealized`\n * counts only RESOLVED claims, so a typo'd `#req-` tag leaves the requirement\n * reported as realized by nobody — which is the truth, and is exactly what a\n * broken claim should not be able to hide. The two findings arriving together is\n * the intended reading: one says the tag is wrong, the other says the promise is\n * still unkept.\n */\nimport {\n REQ_TAG_PREFIX,\n tagSlug,\n resolveRequirementTags,\n type CapabilityClaim,\n type RequirementClaim,\n} from \"../../../../core/capabilities/usecase-join.js\";\nimport type { ParsedView } from \"../../../../core/c4/parsed/dynamic-views.js\";\nimport type { Finding } from \"../../../../core/vocabulary/report.js\";\nimport { viewPlace } from \"./place.js\";\n\n/** A `Requirement-ID` as an author must write it in a tag: `CHK.ONCE (#req-CHK-ONCE)`. */\nfunction idAndTag(id: string): string {\n return `${id} (#${REQ_TAG_PREFIX}${tagSlug(id)})`;\n}\n\n/**\n * The fix for one unresolved claim. The `unscoped` arm splits in two on the\n * count, because none and several are opposite mistakes: one author forgot to\n * say which capability, the other said two and left the id homeless.\n */\nfunction advice(claim: Exclude<RequirementClaim, { kind: \"resolved\" }>): string {\n switch (claim.kind) {\n case \"unscoped\":\n return claim.capabilities.length === 0\n ? \"the view carries no `#cap-` tag that resolves to a declared capability, and a `Requirement-ID` is \" +\n \"unique only inside its own document — so there is nothing for this id to be looked up in. \" +\n \"Add the `#cap-<slug>` tag naming the capability this flow is about.\"\n : `the view resolves ${claim.capabilities.length} capabilities (${claim.capabilities.join(\", \")}), ` +\n \"so nothing says which document the id belongs to. A flow realizing promises from two capabilities \" +\n \"needs one `#req-` tag per capability to be unambiguous, which the tag grammar cannot express — \" +\n \"split the flow, or drop the `#req-` tag and let `Realizes:` on the service requirements carry it.\";\n case \"undocumented\":\n return (\n `capability '${claim.capability}' is declared but has no capabilities/${claim.capability}/spec.md, ` +\n \"so it carries no requirements to satisfy. Write the document — a name alone can be claimed with \" +\n \"`#cap-`, but only a document has promises a flow can keep.\"\n );\n case \"empty\":\n return (\n `capabilities/${claim.capability}/spec.md exists and declares no requirements yet — ` +\n \"add the `## Requirements` section, each requirement carrying its `Requirement-ID:`.\"\n );\n case \"none\":\n return claim.close.length > 0\n ? `capabilities/${claim.capability}/spec.md declares no requirement flattening to '${claim.slug}'. ` +\n `Did you mean: ${claim.close.map(idAndTag).join(\", \")}?`\n : `capabilities/${claim.capability}/spec.md declares no requirement flattening to '${claim.slug}' — ` +\n \"check the `Requirement-ID:` lines in that document.\";\n default:\n return (\n `${claim.ids.length} requirements of '${claim.capability}' flatten to '${claim.slug}' ` +\n `(${claim.ids.join(\", \")}) — nothing in the tag can say which promise this flow keeps. ` +\n \"Rename one of them: a guessed requirement reports the wrong promise as kept and the right one as \" +\n \"unimplemented, and both answers look exactly like the truth.\"\n );\n }\n}\n\n/**\n * One finding per `#req-` tag that does not resolve — never one per view.\n *\n * Several `#req-` tags on one view are legal and normal: a checkout flow that\n * charges once AND honours the price keeps two promises, and there is no honest\n * way to make its author pick one. So a broken tag beside a working one must\n * neither swallow the break nor lose the promise the view genuinely does keep.\n *\n * `claims` is the view's OWN capability verdicts, already resolved by the\n * caller — passed rather than recomputed so the scope this grade uses and the\n * scope `capabilityTagFindings` graded are the same list, and an unresolved\n * `#cap-` tag cannot silently scope a requirement lookup.\n */\nexport function requirementTagFindings(\n view: ParsedView,\n claims: readonly CapabilityClaim[],\n requirementsOf: (capability: string) => ReadonlySet<string> | undefined,\n): Finding[] {\n const scope = claims.flatMap((claim) => (claim.kind === \"resolved\" ? [claim.id] : []));\n const findings: Finding[] = [];\n for (const claim of resolveRequirementTags(view.tags, scope, requirementsOf)) {\n if (claim.kind === \"resolved\") continue;\n findings.push({\n severity: \"error\",\n code: \"usecase.requirement-unresolved\",\n // The VIEW, not the tag — a subject is what a reader goes and opens, and\n // one broken use case counts once however many of its tags are wrong.\n subject: view.id,\n message: `${viewPlace(view)} is tagged #${claim.tag}, and it does not resolve: ${advice(claim)}`,\n });\n }\n return findings;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"steps.js","sourceRoot":"","sources":["../../../../../src/commands/validate/fleet/usecases/steps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,aAAa,EAAwC,MAAM,6BAA6B,CAAC;AAGlG,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAEtE,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA+BvC,uFAAuF;AACvF,SAAS,OAAO,CAAC,GAAe;IAC9B,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,eAAe,CAAC,GAAe,EAAE,WAAqB;IAC7D,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU;QAC/B,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE;QACxF,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC;IACvF,OAAO;QACL,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE;QACpB,OAAO,EACL,GAAG,OAAO,CAAC,GAAG,CAAC,mCAAmC,WAAW,CAAC,IAAI,OAAO,WAAW,CAAC,EAAE,mBAAmB;YAC1G,oGAAoG;YACpG,yGAAyG;YACzG,4BAA4B,KAAK,CAAC,IAAI,mBAAmB,KAAK,CAAC,QAAQ,oCAAoC;YAC3G,4DAA4D,WAAW,CAAC,EAAE,OAAO,WAAW,CAAC,IAAI,WAAW;KAC/G,CAAC;AACJ,CAAC;AAED,4GAA4G;AAC5G,SAAS,aAAa,CAAC,GAAQ;IAC7B,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,EAAE,EAAE,CAAC;IAC5D,OAAO,GAAG,GAAG,CAAC,MAAM,OAAO,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC;AACvE,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,gBAAgB,CAAC,GAAe,EAAE,WAAsB;IAC/D,OAAO;QACL,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,wBAAwB;QAC9B,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE;QACpB,OAAO,EACL,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,WAAW,CAAC,IAAI,CAAC,MAAM,uBAAuB,WAAW,CAAC,IAAI,MAAM;YACxF,GAAG,WAAW,CAAC,EAAE,kBAAkB,WAAW,CAAC,GAAG,CAAC,MAAM,4CAA4C;YACrG,uGAAuG;YACvG,0GAA0G;YAC1G,6DAA6D;QAC/D,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,SAAS,gBAAgB,CAAC,WAAuB,EAAE,OAAoB;IACrE,IAAI,WAAW,CAAC,EAAE,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3G,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACnE,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACjD,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1D,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,OAAO,CAAC,EAAU,EAAE,QAAgB;IAC3C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,OAAO,OAAO,KAAK,SAAS,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,GAAe,EAAE,WAAuB,EAAE,QAAgB;IACjF,MAAM,OAAO,GACX,WAAW,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,gBAAgB,CAAC;IAClG,OAAO;QACL,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE;QACpB,OAAO,EACL,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,WAAW,CAAC,IAAI,OAAO,WAAW,CAAC,EAAE,iBAAiB,OAAO,eAAe;YAChG,qFAAqF;YACrF,GAAG,QAAQ,wEAAwE;YACnF,0GAA0G;YAC1G,uCAAuC;KAC1C,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAe,EAAE,OAAoB;IAChE,MAAM,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3D,QAAQ,WAAW,CAAC,OAAO,EAAE,CAAC;QAC5B,KAAK,UAAU;YACb,OAAO,CAAC,eAAe,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;QAC7C,KAAK,WAAW;YACd,OAAO,CAAC,gBAAgB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;QAC9C,KAAK,YAAY,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACxD,OAAO,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["/**\n * The three grades one hop of a use case can earn: `usecase.step-unbacked`,\n * `usecase.step-contested` and `usecase.step-unlinked`.\n *\n * The attribution itself is `core/c4/arch.ts`'s `attributeStep` — which declared\n * relationship backs a hop, oriented on `isBackward` and decided by the\n * DISTINCT-op count — and none of that reasoning is repeated here. This module\n * owns three things: which verdict earns which code, the three guards that keep\n * the warn honest, and the sentences.\n *\n * WHY `step-unbacked` IS THE CHECK THAT EARNS THE FEATURE. A hop between two\n * elements that both exist, with no relationship between them anywhere in the\n * model, is ZERO LikeC4 errors: a `dynamic view` is allowed to show a call the\n * model never declared, so the diagram renders, the project parses, and every\n * other check in loam stays green. The flow reads as fine in every tool the\n * fleet has. If loam does not convict it, nothing does — which is why it is an\n * error rather than an advisory.\n *\n * ONE BREACH, ONE FINDING, and here that is structural rather than remembered.\n * `contested` and `attributed` are disjoint verdicts, so deriving\n * `step-unlinked` from the `attributed` arm — never from the candidate\n * relationships — is what makes a contested step report once. A grader that\n * walked `rels` looking for a missing `op` would convict the same hop twice:\n * once for the disagreement, and once for whichever candidate happened to carry\n * no operation at all.\n */\nimport { attributeStep, type StepAttribution, type StepScope } from \"../../../../core/c4/arch.js\";\nimport type { Elem, Rel } from \"../../../../core/c4/likec4.js\";\nimport type { ParsedStep, ParsedView } from \"../../../../core/c4/parsed/dynamic-views.js\";\nimport { ACTOR_KINDS } from \"../../../../core/vocabulary/maturity.js\";\nimport type { Finding } from \"../../../../core/vocabulary/report.js\";\nimport { stepPlace } from \"../../../../core/usecases/place.js\";\nimport { viewPlace } from \"./place.js\";\n\n/** One hop being graded and the view it belongs to — never passed apart. */\nexport interface GradedStep {\n view: ParsedView;\n step: ParsedStep;\n}\n\n/**\n * What a hop is graded against, built ONCE per run.\n *\n * `services` and `model.known` are the same set by construction (`./usecases.ts`\n * builds both from one value), which is what stops \"which service is this\n * element\" being answered one way by the attribution and another by the provider\n * guard below. `resolve` is injected for the same reason `fleetShapeFindings`\n * takes it: the fleet target already holds the shared element→service resolver,\n * and a second one built here could not disagree today but would be a second\n * place to change.\n */\nexport interface StepGrading {\n model: StepScope;\n /** The `services/<id>/` directories that exist. */\n services: ReadonlySet<string>;\n /** The shared element→service resolver every other edge join uses. */\n resolve: (id: string) => string;\n}\n\ntype Unbacked = Extract<StepAttribution, { verdict: \"unbacked\" }>;\ntype Contested = Extract<StepAttribution, { verdict: \"contested\" }>;\ntype Attributed = Extract<StepAttribution, { verdict: \"attributed\" }>;\n\n/** `…checkout.likec4 — dynamic view 'uc_checkout' step 2 'authorizes the payment'`. */\nfunction placeOf(hop: GradedStep): string {\n return `${viewPlace(hop.view)} ${stepPlace(hop.step)}`;\n}\n\n/**\n * A hop nothing in the model backs.\n *\n * Two fixes, because there are genuinely two mistakes that land here and the\n * author is the only one who can say which they made: the edge really is\n * missing, or the hop is a reply written the long way round. The second is\n * offered as the OTHER spelling of what they already typed — suggesting the\n * spelling they used would be a hint that restates the defect — and the sentence\n * says which pair that spelling looks the hop up under, because `<-` attributes\n * a reply to the CALL it answers rather than to the direction the message\n * travels (`callPair` in core/c4/arch.ts holds the measurement).\n */\nfunction unbackedFinding(hop: GradedStep, attribution: Unbacked): Finding {\n const other = hop.step.isBackward\n ? { spelling: `${hop.step.source} -> ${hop.step.target}`, when: \"is not a return step\" }\n : { spelling: `${hop.step.target} <- ${hop.step.source}`, when: \"is a return step\" };\n return {\n severity: \"error\",\n code: \"usecase.step-unbacked\",\n subject: hop.view.id,\n message:\n `${placeOf(hop)}: nothing in the model declares ${attribution.from} -> ${attribution.to}, so this hop is ` +\n \"backed by no relationship — and LikeC4 reports no error for it, so the view still renders and the \" +\n \"project still parses. Draw the edge in `model { }` (with `metadata { op '<operationId>' }` where it is \" +\n `a call), or, if this hop ${other.when}, write it as \\`${other.spelling}\\` — a reply is attributed to the ` +\n `call it answers, so that spelling looks the hop up under ${attribution.to} -> ${attribution.from} instead.`,\n };\n}\n\n/** `web -> orders.api \"Calls createOrder\" (op: createOrder)`, or `(no op)` where the edge declares none. */\nfunction candidateLine(rel: Rel): string {\n const op = rel.op === undefined ? \"no op\" : `op: ${rel.op}`;\n return `${rel.source} -> ${rel.target} \"${rel.title ?? \"\"}\" (${op})`;\n}\n\n/**\n * A hop whose candidates disagree about the operation.\n *\n * WARN, not error, because the model is complete — every candidate is a\n * relationship somebody drew on purpose — and the honest answer is sometimes\n * \"two paths, one flow\". What loam refuses to do is pick: a guessed operation is\n * indistinguishable from a right one in every rollup built over the use case,\n * and it stays wrong invisibly.\n *\n * `details` carries every candidate rather than the distinct ops, because the\n * repair is made on a RELATIONSHIP: the author has to find the edge that names\n * the wrong operation, and a list of operation names does not say which edge\n * that is. An absent `metadata { op }` prints as `no op` and is a candidate like\n * any other — it is exactly as much of a disagreement as a second name.\n */\nfunction contestedFinding(hop: GradedStep, attribution: Contested): Finding {\n return {\n severity: \"warn\",\n code: \"usecase.step-contested\",\n subject: hop.view.id,\n message:\n `${placeOf(hop)}: ${attribution.rels.length} relationships back ${attribution.from} -> ` +\n `${attribution.to} and they name ${attribution.ops.length} different operations, so nothing can say ` +\n \"which one this hop exercises. loam names the candidates instead of picking one — a guessed operation \" +\n \"reads exactly like a right one in every rollup built over this flow. Give the candidates one operation, \" +\n \"or draw the hop between the elements that name exactly one.\",\n details: attribution.rels.map(candidateLine),\n };\n}\n\n/**\n * The service this hop calls, when the hop is a `step-unlinked` candidate at\n * all — `null` when any of the three guards refuses. ALL THREE are mechanical,\n * and each closes a whole class of warnings that would otherwise be simply\n * wrong. The count is stated because a reader auditing this function is meant to\n * find three bullets and three `return null`s below and conclude that none of\n * them is surplus: the one a miscount invites deleting is the last, and deleting\n * it puts the warning back on the first hop of almost every flow.\n *\n * - A `publishes` or `consumes` on ANY candidate means the hop does reach a\n * declared API — an AsyncAPI one. The event spine already grades it\n * (`spine.message-undefined` and its family), and asking for an `op` as well\n * would be loam demanding an HTTP operationId for a Kafka message. Read\n * across every candidate rather than the first, because on the service tier\n * the candidates are one call drawn as containers.\n * - The target must resolve to a real `services/<id>/`. Without it every hop\n * into an `#external` system, an actor, a database, a cache or a queue warns\n * — none of which owns an `openapi.yaml`, so none of them CAN carry the\n * operationId the message would be asking for. Through the shared resolver,\n * so \"the provider\" here and \"the provider\" in the spine check cannot\n * disagree about which element stands for which directory.\n * - The CALLER must not be an actor. A person is not a caller: `customer ->\n * checkoutWeb 'opens the basket'` is somebody using the app, and the app owes\n * no operationId for a click. The guard above does not cover this, because it\n * reads the TARGET — and the target here is one of ours, so without this the\n * warning fired on the FIRST HOP OF ALMOST EVERY FLOW, which is where a\n * sequence diagram puts its actor. Measured on the published example fleet\n * before it was added. This is the same exemption `fleet/census.ts`,\n * `arch-coverage.ts`, `core/gate/partners.ts` and `core/verify/checklist.ts`\n * each already apply, through the same `ACTOR_KINDS` — a person was never a\n * participant in any of loam's other censuses either.\n *\n * The op test reads the ATTRIBUTION rather than the relationships: an\n * `attributed` verdict with no `op` means every candidate agreed the hop names\n * no operation, which is the state this warn is about. Candidates that disagree\n * never reach here at all — that is the suppression, and it is why it cannot be\n * forgotten.\n */\nfunction unlinkedProvider(attribution: Attributed, grading: StepGrading): string | null {\n if (attribution.op !== undefined) return null;\n if (attribution.rels.some((rel) => rel.publishes !== undefined || rel.consumes !== undefined)) return null;\n if (isActor(attribution.from, grading.model.elements)) return null;\n const provider = grading.resolve(attribution.to);\n return grading.services.has(provider) ? provider : null;\n}\n\n/**\n * Is this endpoint a person rather than a system?\n *\n * Exact id, not the ancestor walk the service resolver does: an actor is a\n * top-level element in every landscape loam has seen, and a nested one would be\n * a person inside a system, which is not a shape the model has. An endpoint that\n * names no element cannot occur — a step naming one is a LikeC4 reference error,\n * so the document never reaches a check.\n */\nfunction isActor(id: string, elements: Elem[]): boolean {\n const element = elements.find((candidate) => candidate.id === id);\n return element !== undefined && ACTOR_KINDS.has(element.kind.toLowerCase());\n}\n\n/**\n * A hop backed by the model and joined to no contract.\n *\n * The mirror of `spine.op-link-missing` at flow altitude: the use case reaches\n * the fleet map and stops there, so nothing can say which operation of the\n * provider's contract the step exercises — and the whole point of grading a use\n * case is that the flow joins through to the API it drives.\n */\nfunction unlinkedFinding(hop: GradedStep, attribution: Attributed, provider: string): Finding {\n const backing =\n attribution.rels.length === 1 ? \"one relationship\" : `${attribution.rels.length} relationships`;\n return {\n severity: \"warn\",\n code: \"usecase.step-unlinked\",\n subject: hop.view.id,\n message:\n `${placeOf(hop)}: ${attribution.from} -> ${attribution.to} is backed by ${backing} carrying no ` +\n \"`metadata { op }` and no `publishes`/`consumes`, so this hop names no operation of \" +\n `${provider}'s contract — the use case reaches the fleet map and stops there. Add ` +\n \"`metadata { op '<operationId>' }` to the edge in `model { }`, or `metadata { publishes '<message>' }` / \" +\n \"`consumes` where the hop is an event.\",\n };\n}\n\n/**\n * The findings one hop earns — at most one, whatever is wrong with it.\n *\n * A `switch` over the closed verdict union with every arm returning, so a fourth\n * verdict added upstream is a compile error here rather than a hop that silently\n * stops being graded.\n */\nexport function stepFindings(hop: GradedStep, grading: StepGrading): Finding[] {\n const attribution = attributeStep(hop.step, grading.model);\n switch (attribution.verdict) {\n case \"unbacked\":\n return [unbackedFinding(hop, attribution)];\n case \"contested\":\n return [contestedFinding(hop, attribution)];\n case \"attributed\": {\n const provider = unlinkedProvider(attribution, grading);\n return provider === null ? [] : [unlinkedFinding(hop, attribution, provider)];\n }\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"usecases.js","sourceRoot":"","sources":["../../../../../src/commands/validate/fleet/usecases/usecases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAI/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAoB,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AA8C9D;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,WAAW,CAAC,KAA4B;IAC/C,OAAO,KAAK;SACT,MAAM,CAAC,SAAS,CAAC;SACjB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACpF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,MAAM,OAAO,GAAgB;QAC3B,mEAAmE;QACnE,0EAA0E;QAC1E,8DAA8D;QAC9D,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE;QAC9F,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC;IACF,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5C,4EAA4E;QAC5E,6EAA6E;QAC7E,sEAAsE;QACtE,gDAAgD;QAChD,EAAE;QACF,wEAAwE;QACxE,2EAA2E;QAC3E,wEAAwE;QACxE,0EAA0E;QAC1E,oEAAoE;QACpE,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;YACpE,QAAQ,CAAC,IAAI,CAAC,GAAG,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;YACtD,QAAQ,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;QAC/E,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["/**\n * The use-case axis of `validate --all`: the `dynamic view`s a fleet declares,\n * graded as business flows against the model they are drawn over.\n *\n * ONLY VIEWS CARRYING A RESERVED TAG ARE GRADED, and that opt-in is what lets\n * this ship into a fleet that already has diagrams. An untagged `dynamic view`\n * is somebody's hand-drawn sequence — drawn to explain something to a person,\n * not to be joined to a model — and grading it would turn every existing docs\n * repo red on upgrade over documents nobody promised anything about. A `#cap-`\n * or `#req-` tag is the author saying \"this is a use case; hold it to the\n * model\", and nothing else says it: a view with no tags and a view whose tags\n * are all somebody's own vocabulary are the same thing here.\n *\n * THE TAG OPTS A VIEW IN WHETHER OR NOT IT RESOLVES. A `#cap-` slug that names\n * no declared capability is a broken claim about the vocabulary, not a withdrawn\n * one, so its steps are still graded — and the step grades read\n * `architecture/capabilities.yaml` nowhere at all. Coupling them would mean a\n * fleet that has not adopted the capability axis could never have a use case\n * checked, which inverts the adoption order the whole axis is built on: draw the\n * flow first, name the capability when the vocabulary exists.\n *\n * Everything here is LINEAR IN STEPS over documents `validate --all` has already\n * parsed, and nothing in it reads a file or throws — a fleet with no tagged view\n * produces exactly nothing. Linear in steps is not free per step: `attributeStep`\n * scans `relationships` once for the exact tier and again for the resolved one,\n * and `isActor` scans `elements`, so the real shape is O(steps × relationships)\n * plus O(steps × elements). That is why `StepGrading` is built once below rather\n * than per hop — the per-hop cost is a scan, so anything rebuilt per hop is paid\n * against every hop in the fleet.\n */\nimport { compareIds } from \"../../../../core/repo/entries.js\";\nimport { resolveCapabilityTags } from \"../../../../core/capabilities/usecase-join.js\";\nimport { isUseCase } from \"../../../../core/usecases/fleet.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 { capabilityTagFindings } from \"./capability-tag.js\";\nimport { requirementTagFindings } from \"./requirement-tag.js\";\nimport { stepFindings, type StepGrading } from \"./steps.js\";\nimport { viewFile } from \"../../../../core/usecases/place.js\";\n\n/** What the use-case grades run over: the views, the model they are drawn on, and the fleet. */\nexport interface UseCaseScope {\n /**\n * Every `dynamic view` the `architecture/` PROJECT declares, each carrying the\n * file it was written in.\n *\n * The caller must pass views that came from `loadProject` and no others. Only\n * that loader gives a view a `sourcePath` relative to `architecture/`; the\n * single-file loaders name every document after themselves (`source.c4`), and\n * a finding built from one of those would name a file that has never existed\n * — see `./place.ts`, which is where the path is spelled.\n */\n views: readonly ParsedView[];\n elements: Elem[];\n relationships: Rel[];\n /** The `services/<id>/` directories that exist. */\n services: ReadonlySet<string>;\n /** The shared element→service resolver — the same one every other edge join uses. */\n resolve: (id: string) => string;\n /**\n * The declared capability ids, or `null` when `architecture/capabilities.yaml`\n * is absent or does not read as a vocabulary.\n *\n * `null` and `[]` are deliberately different answers, and the join at\n * `core/capabilities/usecase-join.ts` says why it cannot tell them apart\n * itself: an empty list means \"the fleet declares no capabilities\", which is a\n * real verdict every tag then fails against, while `null` means \"there is no\n * vocabulary to grade against\" and suspends the tag grade entirely. The\n * caller applies the ladder because the caller is the one that read the file.\n */\n capabilities: readonly string[] | null;\n /**\n * The requirement ids one capability's document declares, or `undefined` for a\n * capability with no document — the scope a `#req-` tag is resolved in.\n *\n * A function rather than the map itself, so this package never learns what a\n * capability document is: the fleet target reads them once\n * (`capabilityRequirementIndex`) and hands the lookup over. `undefined` and an\n * empty set are different answers here, exactly as they are one join over —\n * no document at all, against a document declaring no promises yet.\n */\n requirementsOf: (capability: string) => ReadonlySet<string> | undefined;\n}\n\n/**\n * The views that opted in, in a stable order.\n *\n * The opt-in itself is `isUseCase` in `core/usecases/fleet.ts` and is not\n * restated here. It used to be — the same `startsWith` pair, spelled a second\n * time — and the two spellings drifted: this one took either reserved prefix\n * while the reader-side one took `#cap-` alone, so `validate` graded a\n * `#req-`-only flow that `loam diff`, `delta`, `status`, the packs and `list\n * capabilities` could not see. What is left here is the ORDER, which is this\n * package's own concern.\n *\n * Sorted by (file, view id) rather than reported in LikeC4's own record order:\n * nothing in loam has measured that the parse preserves declaration order, so a\n * report whose row order depends on that would reorder under a dependency bump\n * — the diff-stability rule `core/capabilities/rollup.ts` states for its rows,\n * applied to findings.\n */\nfunction gradedViews(views: readonly ParsedView[]): ParsedView[] {\n return views\n .filter(isUseCase)\n .sort((a, b) => compareIds(viewFile(a), viewFile(b)) || compareIds(a.id, b.id));\n}\n\n/**\n * Every use-case finding a fleet's declared views earn.\n *\n * The grading record is built once and shared across every step of every view:\n * `attributeStep` caches its element→service resolver on the identity of the\n * elements array and the fleet set, so handing it one `StepScope` for the whole\n * run is what keeps the fleet's use cases from rebuilding that id map per hop.\n */\nexport function useCaseFindings(scope: UseCaseScope): Finding[] {\n const grading: StepGrading = {\n // `known` and `services` come from ONE value, so the fleet set the\n // attribution resolves against and the fleet set the provider guard tests\n // cannot drift apart into two answers about the same element.\n model: { elements: scope.elements, relationships: scope.relationships, known: scope.services },\n services: scope.services,\n resolve: scope.resolve,\n };\n const findings: Finding[] = [];\n for (const view of gradedViews(scope.views)) {\n // ONE resolution of this view's capability tags, shared by both grades. The\n // `#req-` tag is scoped by exactly the capabilities the `#cap-` tags resolve\n // to, so resolving twice would be two chances to disagree about which\n // document a `Requirement-ID` is unique inside.\n //\n // THE LADDER IS THE `null`, NOT AN EMPTY LIST, and the distinction is a\n // wrong answer away: a suspended vocabulary handed on as `[]` reads to the\n // requirement grade as \"this view resolves no capability\", which is its\n // `unscoped` ERROR — so every `#req-` tag in a fleet that has not adopted\n // the capability axis would be convicted for the axis not existing.\n if (scope.capabilities !== null) {\n const claims = resolveCapabilityTags(view.tags, scope.capabilities);\n findings.push(...capabilityTagFindings(view, claims));\n findings.push(...requirementTagFindings(view, claims, scope.requirementsOf));\n }\n for (const step of view.steps) findings.push(...stepFindings({ view, step }, grading));\n }\n return findings;\n}\n"]}
@@ -1,220 +0,0 @@
1
- /**
2
- * The document's opening arc: what the docs repo HOLDS — the layout, how its
3
- * documents link to each other, the glossary, architectural obligations, and
4
- * the `loam.json` wiring every repository commits.
5
- *
6
- * The three sections that used to close this file — the architecture spec
7
- * axis, the generated Gherkin suite, and the frontmatter/vouch chain — are now
8
- * the `loam-authoring` reference page (../workflows/reference/authoring.ts),
9
- * printed by `loam instructions loam-authoring` rather than written into
10
- * AGENTS.md. They are grammars consulted while writing ONE document, and the
11
- * file they were in is auto-loaded on every session by hosts that truncate it
12
- * silently; ./command-map.ts's header carries the measurement that decided it.
13
- * What is left here is what an agent must know before it can form a question
14
- * at all.
15
- *
16
- * One section of the AGENTS.md template. ../agents-md.ts assembles the
17
- * document by PLAIN CONCATENATION — no join separator — so every section
18
- * starts at the first character of its opening line and ends with the newline
19
- * that closes its last one. Keep that shape when editing, or two sections glue
20
- * onto one line in every docs repo loam scaffolds from now on.
21
- */
22
- export const ARTIFACTS = `# Working in this docs repo
23
-
24
- This is a **loam** docs repo: the shared source of truth for a governed software
25
- system — its architecture, requirements, contracts and evidence. Everything here
26
- is plain files. \`loam\` reads and writes them; delete \`loam\` and the docs remain.
27
-
28
- **The bar this artifact set aims at is reproducibility**: a reader should be able
29
- to answer, from these files alone — what each governed boundary exposes, what it
30
- reaches, what shapes it exchanges, how it is run, and what pages whom —
31
- without opening the code. \`loam validate\` grades form and joins, never depth:
32
- green means the files agree with each other, and the bar is what "done" is
33
- measured against — a thin baseline that validates is thin, not done.
34
-
35
- ## Layout
36
-
37
- \`\`\`
38
- architecture/landscape.likec4 the living C4 model of the whole system
39
- architecture/permissions.yaml optional system-wide authorization vocabulary
40
- architecture/obligations.yaml optional ARCHITECTURAL obligations (#obl-<name> on the map)
41
- architecture/adrs/NNNN-*.md optional SYSTEM-level decisions (MADR) — only their links are graded
42
- glossary/<term>.md optional domain vocabulary — one file per term, nesting allowed
43
- services/<svc>/
44
- model.likec4 this governed boundary's C4
45
- spec.md its living requirements (current state)
46
- arch.spec.md its living ARCHITECTURE requirements (outbox, retries, alerts)
47
- openapi.yaml its API contract
48
- asyncapi.yaml its AsyncAPI 3 event contract
49
- adrs/ runbook.md health.yaml why it is like this, how to run it
50
- features/<FEAT>/ a change in flight
51
- intent.md why, in business terms
52
- delta.likec4 the architecture change, tagged #<FEAT>
53
- specs/<svc>/spec.md the requirement change for one governed boundary
54
- specs/<svc>/arch.spec.md the architectural requirement change, same delta grammar
55
- specs/<svc>/openapi.yaml the endpoints this feature adds
56
- specs/<svc>/asyncapi.yaml the event-contract delta (optional; a complete AsyncAPI 3 document)
57
- verification.yaml what was checked once the code was built
58
- features/archive/<FEAT>/ shipped changes — the evolution history
59
- \`\`\`
60
-
61
- ## Linking between documents
62
-
63
- Documents here link to each other with **standard markdown links**, and the
64
- target is a relative path to the file:
65
-
66
- \`\`\`markdown
67
- [0001 — transactional outbox](../../architecture/adrs/0001-transactional-outbox.md)
68
- \`\`\`
69
-
70
- Two reasons, and the second is the one that decides it. A markdown link renders
71
- as a link in pull-request review, which is where these documents are actually
72
- read, while \`[[0001 transactional outbox]]\` renders there as the literal
73
- brackets somebody typed. And its target is a real relative path, so "does this
74
- link resolve" is a filesystem question with a yes-or-no answer — where resolving
75
- a wikilink means reimplementing Obsidian's shortest-unique-path search across the
76
- whole repo, which is guessing, and loam refuses and names rather than guessing.
77
-
78
- You lose nothing by it. Obsidian reads a repo written this way with no
79
- integration at all — graph view, backlinks and search all work on markdown links
80
- — and its per-vault \`Use [[Wikilinks]]\` setting turns OFF, after which its own
81
- autocomplete and rename-tracking produce markdown links too. The authoring
82
- comfort is a toggle in somebody's editor, not a decision this repo carries.
83
-
84
- **\`loam validate\` resolves these links** (\`link.unresolved\`, error): a relative
85
- target that names nothing is a broken join, reported once per document with
86
- every bad link and its line. A link here is a **join**, not decoration — a
87
- requirement that names a term wants that term's document linked, and an ADR that
88
- supersedes another wants to say which, the same kind of relationship
89
- \`Operations:\` and \`Covers:\` already state.
90
-
91
- Three things are deliberately NOT graded, so write them freely: a target outside
92
- this repository (\`../../some-service/README.md\` — that tree may not be checked
93
- out beside these documents), a link to a heading (\`#section\`), and any link
94
- inside a fenced code block or an inline code span, which is how a document shows
95
- the convention without being convicted for it.
96
-
97
- CASE **is** graded, and deliberately: \`[Order](Order.md)\` beside a file called
98
- \`order.md\` resolves on Windows and macOS and 404s on GitHub and every Linux
99
- runner, so the message names the stored spelling on all of them alike.
100
-
101
- ## The glossary — the system's domain words
102
-
103
- \`glossary/<term>.md\`, one file per term, nesting allowed
104
- (\`glossary/payments/authorization.md\` is the term \`payments/authorization\`). There is
105
- no \`glossary.yaml\`: a definition is prose, and the DIRECTORY is the list. The
106
- directory's existence is the opt-in — a system without one hears nothing.
107
-
108
- **A term is checkable because a link is a join.** Cite it from the document that
109
- uses the word — a requirement, a capability document, a feature's intent — with an
110
- ordinary relative link:
111
-
112
- \`\`\`markdown
113
- An [Order](../../glossary/order.md) is what a customer has confirmed.
114
- \`\`\`
115
-
116
- A citation that does not resolve is \`link.unresolved\` like any other; a term nothing
117
- outside \`glossary/\` cites is \`glossary.unlinked\` (warn). Terms citing each other is
118
- normal and does NOT count as adoption — a glossary is a network of definitions, and
119
- two terms defining each other say nothing about whether the system uses either word.
120
- \`loam list glossary\` prints every term with the documents that cite it.
121
-
122
- **A feature may bring a new word with it**: write it at
123
- \`features/<FEAT>/glossary/<term>.md\` and \`loam archive\` copies it into \`glossary/\`,
124
- \`loam unarchive\` takes it back out. This route is CREATE-ONLY — a term the living
125
- glossary already defines is \`glossary.term-exists\`, which \`--approve\` does not
126
- override, because the merge is a whole-file copy and would replace an authored
127
- definition wholesale. To CHANGE a definition, edit \`glossary/<term>.md\` directly in
128
- the same pull request, where git produces an ordinary conflict.
129
-
130
- Cite the new word at its FUTURE living path (\`../../../../glossary/order.md\` from a
131
- \`specs/<svc>/\` delta) — that link resolves while the feature is in flight, and the
132
- merge re-expresses it from wherever the text lands, so it keeps resolving afterwards.
133
-
134
- Write the definition for a reader who knows the business and not this system: what the
135
- word means, and what it is NOT (an order is not a cart). Never which service owns it —
136
- that is the system map's question and it changes.
137
-
138
-
139
- ## Architectural obligations — what the architect hands the team
140
-
141
- An architect has always had one checked channel here: an edge carrying
142
- \`metadata { op 'authorizePayment' }\` obliges the provider to define that operationId,
143
- or \`spine.op-undefined\` fails the gate. Obligations are the same handoff for the rules
144
- that VARY — an outbox on this publisher and not that one, a circuit breaker on two
145
- edges out of five — and they are three separate things on purpose:
146
-
147
- - an **ADR** in \`architecture/adrs/\` says WHAT was decided, as thin or as thick as the
148
- decision needs;
149
- - a **\`#obl-<name>\` tag** on an element or an edge in \`architecture/landscape.likec4\`
150
- says WHERE it applies, so one ADR governs three edges and not the fourth without the
151
- document forking;
152
- - **\`architecture/obligations.yaml\`** declares the names, so a mistyped tag is an error
153
- rather than a word nobody notices.
154
-
155
- \`\`\`yaml
156
- obligations:
157
- outbox:
158
- description: Publishers write the event and the state change in one transaction.
159
- adr: architecture/adrs/0001-transactional-outbox.md # relative to the docs repo root
160
- \`\`\`
161
-
162
- **Your side of it is \`Covers:\`**. A tagged object with no living requirement covering it
163
- is \`obligation.uncovered\` (warn), and the finding names the service, the object and the
164
- exact line to write — \`Covers: <element>\` or \`Covers: <source> -> <target>\` in that
165
- service's \`arch.spec.md\`, with a scenario that proves it. An id is its own tag suffix,
166
- so it may hold letters, digits, \`_\` and \`-\` only.
167
-
168
- ## \`loam.json\` — the wiring, in every repo
169
-
170
- A governed system is **N + 1 repositories**: this docs repo, and one per governed
171
- implementation boundary. Paths and commands call that boundary a \`service\`; it
172
- may be a modular monolith, a network service, a CLI or a worker. Every repo
173
- commits its own \`loam.json\`, so an agent, human or CI runner can find the rest
174
- of the system. There is no global config; without a \`loam.json\`, commands refuse
175
- with \`no-config\` rather than guessing.
176
-
177
- \`\`\`json
178
- { "docsDir": "../docs-repo", "service": "payment-service", "gherkinDir": "features" }
179
- \`\`\`
180
-
181
- - \`docsDir\` — where the docs repo is, **stored exactly as it was passed** and
182
- resolved against the directory holding the \`loam.json\`. So \`../docs-repo\`
183
- keeps working on every machine that checks the repos out side by side, which
184
- is the point of committing the file. An absolute path is a warning
185
- (\`doctor.docs-absolute\`): it resolves only on the machine that ran \`loam init\`.
186
- The docs repo's own \`loam.json\` says \`"docsDir": "."\`.
187
- - \`service\` — the canonical id of the governed boundary THIS repo contains, i.e. the
188
- \`services/<id>/\` directory it is allowed to speak for. \`loam vouch\`,
189
- \`loam gherkin\` and \`loam verify --service\` when writing with \`--record\`,
190
- \`--results\` or \`--contract-results\` bind to it; without it they refuse
191
- (\`repository-unavailable\`) rather than write another boundary's documents
192
- from a repo that is not that boundary's. A read-only verify checklist needs no
193
- binding and works from the docs repo.
194
- - \`gherkinDir\` — optional, default \`features\`: the directory \`loam gherkin\`
195
- writes its own \`loam/\` subtree into.
196
- - \`agentTools\` — optional: the agent tools \`loam init\` has written command and
197
- skill files for here, accumulated across runs. Written by \`init\`, read by
198
- \`loam doctor\`; nothing else depends on it, and a config without it loads.
199
-
200
- **Step 0 of everything below, once per repo:**
201
-
202
- \`\`\`sh
203
- loam init --docs ../docs-repo --service payment-service # in EACH service repo
204
- loam doctor # before you trust any of it
205
- \`\`\`
206
-
207
- \`loam init --docs <dir>\` **joins** an existing docs repo; creating a new one
208
- takes \`--create\`, so a mistyped path cannot quietly scaffold a second source of
209
- truth beside the real one. \`loam doctor\` is the read-only preflight: it reads
210
- loam.json defensively, resolves \`docsDir\`, probes access, checks \`services/\` and
211
- the system map, and reports the service binding — run it first when anything
212
- behaves as though the system were empty.
213
-
214
- **Living vs delta.** \`services/<svc>/spec.md\` is the complete current state.
215
- \`features/<FEAT>/specs/<svc>/spec.md\` is a diff against it, reviewed as a diff, with
216
- requirements grouped under \`## ADDED\`, \`## MODIFIED\` or \`## REMOVED Requirements\`.
217
- \`loam archive\` folds the delta into the living state.
218
-
219
- `;
220
- //# sourceMappingURL=artifacts.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../../../src/core/agent/agents-md/artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqMxB,CAAC","sourcesContent":["/**\n * The document's opening arc: what the docs repo HOLDS — the layout, how its\n * documents link to each other, the glossary, architectural obligations, and\n * the `loam.json` wiring every repository commits.\n *\n * The three sections that used to close this file — the architecture spec\n * axis, the generated Gherkin suite, and the frontmatter/vouch chain — are now\n * the `loam-authoring` reference page (../workflows/reference/authoring.ts),\n * printed by `loam instructions loam-authoring` rather than written into\n * AGENTS.md. They are grammars consulted while writing ONE document, and the\n * file they were in is auto-loaded on every session by hosts that truncate it\n * silently; ./command-map.ts's header carries the measurement that decided it.\n * What is left here is what an agent must know before it can form a question\n * at all.\n *\n * One section of the AGENTS.md template. ../agents-md.ts assembles the\n * document by PLAIN CONCATENATION — no join separator — so every section\n * starts at the first character of its opening line and ends with the newline\n * that closes its last one. Keep that shape when editing, or two sections glue\n * onto one line in every docs repo loam scaffolds from now on.\n */\nexport const ARTIFACTS = `# Working in this docs repo\n\nThis is a **loam** docs repo: the shared source of truth for a governed software\nsystem — its architecture, requirements, contracts and evidence. Everything here\nis plain files. \\`loam\\` reads and writes them; delete \\`loam\\` and the docs remain.\n\n**The bar this artifact set aims at is reproducibility**: a reader should be able\nto answer, from these files alone — what each governed boundary exposes, what it\nreaches, what shapes it exchanges, how it is run, and what pages whom —\nwithout opening the code. \\`loam validate\\` grades form and joins, never depth:\ngreen means the files agree with each other, and the bar is what \"done\" is\nmeasured against — a thin baseline that validates is thin, not done.\n\n## Layout\n\n\\`\\`\\`\narchitecture/landscape.likec4 the living C4 model of the whole system\narchitecture/permissions.yaml optional system-wide authorization vocabulary\narchitecture/obligations.yaml optional ARCHITECTURAL obligations (#obl-<name> on the map)\narchitecture/adrs/NNNN-*.md optional SYSTEM-level decisions (MADR) — only their links are graded\nglossary/<term>.md optional domain vocabulary — one file per term, nesting allowed\nservices/<svc>/\n model.likec4 this governed boundary's C4\n spec.md its living requirements (current state)\n arch.spec.md its living ARCHITECTURE requirements (outbox, retries, alerts)\n openapi.yaml its API contract\n asyncapi.yaml its AsyncAPI 3 event contract\n adrs/ runbook.md health.yaml why it is like this, how to run it\nfeatures/<FEAT>/ a change in flight\n intent.md why, in business terms\n delta.likec4 the architecture change, tagged #<FEAT>\n specs/<svc>/spec.md the requirement change for one governed boundary\n specs/<svc>/arch.spec.md the architectural requirement change, same delta grammar\n specs/<svc>/openapi.yaml the endpoints this feature adds\n specs/<svc>/asyncapi.yaml the event-contract delta (optional; a complete AsyncAPI 3 document)\n verification.yaml what was checked once the code was built\nfeatures/archive/<FEAT>/ shipped changes — the evolution history\n\\`\\`\\`\n\n## Linking between documents\n\nDocuments here link to each other with **standard markdown links**, and the\ntarget is a relative path to the file:\n\n\\`\\`\\`markdown\n[0001 — transactional outbox](../../architecture/adrs/0001-transactional-outbox.md)\n\\`\\`\\`\n\nTwo reasons, and the second is the one that decides it. A markdown link renders\nas a link in pull-request review, which is where these documents are actually\nread, while \\`[[0001 transactional outbox]]\\` renders there as the literal\nbrackets somebody typed. And its target is a real relative path, so \"does this\nlink resolve\" is a filesystem question with a yes-or-no answer — where resolving\na wikilink means reimplementing Obsidian's shortest-unique-path search across the\nwhole repo, which is guessing, and loam refuses and names rather than guessing.\n\nYou lose nothing by it. Obsidian reads a repo written this way with no\nintegration at all — graph view, backlinks and search all work on markdown links\n— and its per-vault \\`Use [[Wikilinks]]\\` setting turns OFF, after which its own\nautocomplete and rename-tracking produce markdown links too. The authoring\ncomfort is a toggle in somebody's editor, not a decision this repo carries.\n\n**\\`loam validate\\` resolves these links** (\\`link.unresolved\\`, error): a relative\ntarget that names nothing is a broken join, reported once per document with\nevery bad link and its line. A link here is a **join**, not decoration — a\nrequirement that names a term wants that term's document linked, and an ADR that\nsupersedes another wants to say which, the same kind of relationship\n\\`Operations:\\` and \\`Covers:\\` already state.\n\nThree things are deliberately NOT graded, so write them freely: a target outside\nthis repository (\\`../../some-service/README.md\\` — that tree may not be checked\nout beside these documents), a link to a heading (\\`#section\\`), and any link\ninside a fenced code block or an inline code span, which is how a document shows\nthe convention without being convicted for it.\n\nCASE **is** graded, and deliberately: \\`[Order](Order.md)\\` beside a file called\n\\`order.md\\` resolves on Windows and macOS and 404s on GitHub and every Linux\nrunner, so the message names the stored spelling on all of them alike.\n\n## The glossary — the system's domain words\n\n\\`glossary/<term>.md\\`, one file per term, nesting allowed\n(\\`glossary/payments/authorization.md\\` is the term \\`payments/authorization\\`). There is\nno \\`glossary.yaml\\`: a definition is prose, and the DIRECTORY is the list. The\ndirectory's existence is the opt-in — a system without one hears nothing.\n\n**A term is checkable because a link is a join.** Cite it from the document that\nuses the word — a requirement, a capability document, a feature's intent — with an\nordinary relative link:\n\n\\`\\`\\`markdown\nAn [Order](../../glossary/order.md) is what a customer has confirmed.\n\\`\\`\\`\n\nA citation that does not resolve is \\`link.unresolved\\` like any other; a term nothing\noutside \\`glossary/\\` cites is \\`glossary.unlinked\\` (warn). Terms citing each other is\nnormal and does NOT count as adoption — a glossary is a network of definitions, and\ntwo terms defining each other say nothing about whether the system uses either word.\n\\`loam list glossary\\` prints every term with the documents that cite it.\n\n**A feature may bring a new word with it**: write it at\n\\`features/<FEAT>/glossary/<term>.md\\` and \\`loam archive\\` copies it into \\`glossary/\\`,\n\\`loam unarchive\\` takes it back out. This route is CREATE-ONLY — a term the living\nglossary already defines is \\`glossary.term-exists\\`, which \\`--approve\\` does not\noverride, because the merge is a whole-file copy and would replace an authored\ndefinition wholesale. To CHANGE a definition, edit \\`glossary/<term>.md\\` directly in\nthe same pull request, where git produces an ordinary conflict.\n\nCite the new word at its FUTURE living path (\\`../../../../glossary/order.md\\` from a\n\\`specs/<svc>/\\` delta) — that link resolves while the feature is in flight, and the\nmerge re-expresses it from wherever the text lands, so it keeps resolving afterwards.\n\nWrite the definition for a reader who knows the business and not this system: what the\nword means, and what it is NOT (an order is not a cart). Never which service owns it —\nthat is the system map's question and it changes.\n\n\n## Architectural obligations — what the architect hands the team\n\nAn architect has always had one checked channel here: an edge carrying\n\\`metadata { op 'authorizePayment' }\\` obliges the provider to define that operationId,\nor \\`spine.op-undefined\\` fails the gate. Obligations are the same handoff for the rules\nthat VARY — an outbox on this publisher and not that one, a circuit breaker on two\nedges out of five — and they are three separate things on purpose:\n\n- an **ADR** in \\`architecture/adrs/\\` says WHAT was decided, as thin or as thick as the\n decision needs;\n- a **\\`#obl-<name>\\` tag** on an element or an edge in \\`architecture/landscape.likec4\\`\n says WHERE it applies, so one ADR governs three edges and not the fourth without the\n document forking;\n- **\\`architecture/obligations.yaml\\`** declares the names, so a mistyped tag is an error\n rather than a word nobody notices.\n\n\\`\\`\\`yaml\nobligations:\n outbox:\n description: Publishers write the event and the state change in one transaction.\n adr: architecture/adrs/0001-transactional-outbox.md # relative to the docs repo root\n\\`\\`\\`\n\n**Your side of it is \\`Covers:\\`**. A tagged object with no living requirement covering it\nis \\`obligation.uncovered\\` (warn), and the finding names the service, the object and the\nexact line to write — \\`Covers: <element>\\` or \\`Covers: <source> -> <target>\\` in that\nservice's \\`arch.spec.md\\`, with a scenario that proves it. An id is its own tag suffix,\nso it may hold letters, digits, \\`_\\` and \\`-\\` only.\n\n## \\`loam.json\\` — the wiring, in every repo\n\nA governed system is **N + 1 repositories**: this docs repo, and one per governed\nimplementation boundary. Paths and commands call that boundary a \\`service\\`; it\nmay be a modular monolith, a network service, a CLI or a worker. Every repo\ncommits its own \\`loam.json\\`, so an agent, human or CI runner can find the rest\nof the system. There is no global config; without a \\`loam.json\\`, commands refuse\nwith \\`no-config\\` rather than guessing.\n\n\\`\\`\\`json\n{ \"docsDir\": \"../docs-repo\", \"service\": \"payment-service\", \"gherkinDir\": \"features\" }\n\\`\\`\\`\n\n- \\`docsDir\\` — where the docs repo is, **stored exactly as it was passed** and\n resolved against the directory holding the \\`loam.json\\`. So \\`../docs-repo\\`\n keeps working on every machine that checks the repos out side by side, which\n is the point of committing the file. An absolute path is a warning\n (\\`doctor.docs-absolute\\`): it resolves only on the machine that ran \\`loam init\\`.\n The docs repo's own \\`loam.json\\` says \\`\"docsDir\": \".\"\\`.\n- \\`service\\` — the canonical id of the governed boundary THIS repo contains, i.e. the\n \\`services/<id>/\\` directory it is allowed to speak for. \\`loam vouch\\`,\n \\`loam gherkin\\` and \\`loam verify --service\\` when writing with \\`--record\\`,\n \\`--results\\` or \\`--contract-results\\` bind to it; without it they refuse\n (\\`repository-unavailable\\`) rather than write another boundary's documents\n from a repo that is not that boundary's. A read-only verify checklist needs no\n binding and works from the docs repo.\n- \\`gherkinDir\\` — optional, default \\`features\\`: the directory \\`loam gherkin\\`\n writes its own \\`loam/\\` subtree into.\n- \\`agentTools\\` — optional: the agent tools \\`loam init\\` has written command and\n skill files for here, accumulated across runs. Written by \\`init\\`, read by\n \\`loam doctor\\`; nothing else depends on it, and a config without it loads.\n\n**Step 0 of everything below, once per repo:**\n\n\\`\\`\\`sh\nloam init --docs ../docs-repo --service payment-service # in EACH service repo\nloam doctor # before you trust any of it\n\\`\\`\\`\n\n\\`loam init --docs <dir>\\` **joins** an existing docs repo; creating a new one\ntakes \\`--create\\`, so a mistyped path cannot quietly scaffold a second source of\ntruth beside the real one. \\`loam doctor\\` is the read-only preflight: it reads\nloam.json defensively, resolves \\`docsDir\\`, probes access, checks \\`services/\\` and\nthe system map, and reports the service binding — run it first when anything\nbehaves as though the system were empty.\n\n**Living vs delta.** \\`services/<svc>/spec.md\\` is the complete current state.\n\\`features/<FEAT>/specs/<svc>/spec.md\\` is a diff against it, reviewed as a diff, with\nrequirements grouped under \\`## ADDED\\`, \\`## MODIFIED\\` or \\`## REMOVED Requirements\\`.\n\\`loam archive\\` folds the delta into the living state.\n\n`;\n"]}