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

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 (1036) hide show
  1. package/CHANGELOG.md +2635 -86
  2. package/COMPARISON.md +80 -63
  3. package/CONTRIBUTING.md +84 -0
  4. package/MIGRATING-from-OpenSpec.md +213 -54
  5. package/QUICKSTART.md +125 -0
  6. package/README.md +450 -150
  7. package/ROADMAP.md +599 -0
  8. package/SCHEMA.md +2355 -256
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +701 -0
  11. package/dist/cli.js +113 -19
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +209 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +268 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +77 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/plan/contracts/asyncapi.js +178 -0
  20. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/openapi.js +159 -0
  22. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  23. package/dist/commands/archive/plan/gate.js +323 -0
  24. package/dist/commands/archive/plan/gate.js.map +1 -0
  25. package/dist/commands/archive/plan/landscape.js +180 -0
  26. package/dist/commands/archive/plan/landscape.js.map +1 -0
  27. package/dist/commands/archive/plan/refusal.js +111 -0
  28. package/dist/commands/archive/plan/refusal.js.map +1 -0
  29. package/dist/commands/archive/plan/specs.js +237 -0
  30. package/dist/commands/archive/plan/specs.js.map +1 -0
  31. package/dist/commands/archive/plan/state.js +27 -0
  32. package/dist/commands/archive/plan/state.js.map +1 -0
  33. package/dist/commands/archive/run.js +252 -0
  34. package/dist/commands/archive/run.js.map +1 -0
  35. package/dist/commands/context/context.js +99 -0
  36. package/dist/commands/context/context.js.map +1 -0
  37. package/dist/commands/context/print.js +283 -0
  38. package/dist/commands/context/print.js.map +1 -0
  39. package/dist/commands/delta/delta.js +279 -0
  40. package/dist/commands/delta/delta.js.map +1 -0
  41. package/dist/commands/delta/print.js +205 -0
  42. package/dist/commands/delta/print.js.map +1 -0
  43. package/dist/commands/dependencies.js +9 -7
  44. package/dist/commands/dependencies.js.map +1 -1
  45. package/dist/commands/diff/diff.js +93 -0
  46. package/dist/commands/diff/diff.js.map +1 -0
  47. package/dist/commands/diff/print.js +38 -0
  48. package/dist/commands/diff/print.js.map +1 -0
  49. package/dist/commands/doctor.js +5 -4
  50. package/dist/commands/doctor.js.map +1 -1
  51. package/dist/commands/explain/explain.js +151 -0
  52. package/dist/commands/explain/explain.js.map +1 -0
  53. package/dist/commands/explore.js +29 -24
  54. package/dist/commands/explore.js.map +1 -1
  55. package/dist/commands/gate/gate.js +115 -0
  56. package/dist/commands/gate/gate.js.map +1 -0
  57. package/dist/commands/gate/print.js +54 -0
  58. package/dist/commands/gate/print.js.map +1 -0
  59. package/dist/commands/gherkin/commit.js +146 -0
  60. package/dist/commands/gherkin/commit.js.map +1 -0
  61. package/dist/commands/gherkin/gherkin.js +246 -0
  62. package/dist/commands/gherkin/gherkin.js.map +1 -0
  63. package/dist/commands/gherkin/reconcile.js +149 -0
  64. package/dist/commands/gherkin/reconcile.js.map +1 -0
  65. package/dist/commands/gherkin/render.js +77 -0
  66. package/dist/commands/gherkin/render.js.map +1 -0
  67. package/dist/commands/init/example.js +204 -0
  68. package/dist/commands/init/example.js.map +1 -0
  69. package/dist/commands/init/first-hour.js +28 -0
  70. package/dist/commands/init/first-hour.js.map +1 -0
  71. package/dist/commands/{init.js → init/init.js} +146 -71
  72. package/dist/commands/init/init.js.map +1 -0
  73. package/dist/commands/init/mcp.js +131 -0
  74. package/dist/commands/init/mcp.js.map +1 -0
  75. package/dist/commands/init/options.js +78 -0
  76. package/dist/commands/init/options.js.map +1 -0
  77. package/dist/commands/instructions.js +72 -14
  78. package/dist/commands/instructions.js.map +1 -1
  79. package/dist/commands/list/campaign/campaign.js +65 -0
  80. package/dist/commands/list/campaign/campaign.js.map +1 -0
  81. package/dist/commands/list/campaign/owners.js +65 -0
  82. package/dist/commands/list/campaign/owners.js.map +1 -0
  83. package/dist/commands/list/json.js +157 -0
  84. package/dist/commands/list/json.js.map +1 -0
  85. package/dist/commands/list/list.js +343 -0
  86. package/dist/commands/list/list.js.map +1 -0
  87. package/dist/commands/list/print.js +301 -0
  88. package/dist/commands/list/print.js.map +1 -0
  89. package/dist/commands/list/review.js +120 -0
  90. package/dist/commands/list/review.js.map +1 -0
  91. package/dist/commands/list/views.js +105 -0
  92. package/dist/commands/list/views.js.map +1 -0
  93. package/dist/commands/mcp/dispatch.js +183 -0
  94. package/dist/commands/mcp/dispatch.js.map +1 -0
  95. package/dist/commands/mcp/mcp.js +34 -0
  96. package/dist/commands/mcp/mcp.js.map +1 -0
  97. package/dist/commands/mcp/serve.js +55 -0
  98. package/dist/commands/mcp/serve.js.map +1 -0
  99. package/dist/commands/migrate-openspec/materialize/active.js +170 -0
  100. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  101. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  102. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  103. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  104. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  105. package/dist/commands/migrate-openspec/materialize/stage.js +142 -0
  106. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  107. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  108. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  109. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  110. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  111. package/dist/commands/migrate-openspec/openspec/decisions.js +91 -0
  112. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  113. package/dist/commands/migrate-openspec/openspec/error.js +19 -0
  114. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  115. package/dist/commands/migrate-openspec/openspec/mapping.js +170 -0
  116. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  117. package/dist/commands/migrate-openspec/openspec/paths.js +43 -0
  118. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  119. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  120. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  121. package/dist/commands/migrate-openspec/print.js +89 -0
  122. package/dist/commands/migrate-openspec/print.js.map +1 -0
  123. package/dist/commands/new/commit.js +76 -0
  124. package/dist/commands/new/commit.js.map +1 -0
  125. package/dist/commands/new/new.js +283 -0
  126. package/dist/commands/new/new.js.map +1 -0
  127. package/dist/commands/new/templates.js +355 -0
  128. package/dist/commands/new/templates.js.map +1 -0
  129. package/dist/commands/open.js +203 -0
  130. package/dist/commands/open.js.map +1 -0
  131. package/dist/commands/policy/format.js +152 -0
  132. package/dist/commands/policy/format.js.map +1 -0
  133. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +11 -11
  134. package/dist/commands/policy/gate.js.map +1 -0
  135. package/dist/commands/rebase/edit.js +106 -0
  136. package/dist/commands/rebase/edit.js.map +1 -0
  137. package/dist/commands/rebase/living.js +185 -0
  138. package/dist/commands/rebase/living.js.map +1 -0
  139. package/dist/commands/rebase/plan.js +245 -0
  140. package/dist/commands/rebase/plan.js.map +1 -0
  141. package/dist/commands/rebase/rebase.js +275 -0
  142. package/dist/commands/rebase/rebase.js.map +1 -0
  143. package/dist/commands/seed/commit.js +192 -0
  144. package/dist/commands/seed/commit.js.map +1 -0
  145. package/dist/commands/seed/plan.js +133 -0
  146. package/dist/commands/seed/plan.js.map +1 -0
  147. package/dist/commands/seed/seed.js +172 -0
  148. package/dist/commands/seed/seed.js.map +1 -0
  149. package/dist/commands/show/feature.js +178 -0
  150. package/dist/commands/show/feature.js.map +1 -0
  151. package/dist/commands/show/marks.js +24 -0
  152. package/dist/commands/show/marks.js.map +1 -0
  153. package/dist/commands/{show.js → show/service.js} +63 -152
  154. package/dist/commands/show/service.js.map +1 -0
  155. package/dist/commands/show/show.js +77 -0
  156. package/dist/commands/show/show.js.map +1 -0
  157. package/dist/commands/status/json.js +45 -0
  158. package/dist/commands/status/json.js.map +1 -0
  159. package/dist/commands/status/print.js +157 -0
  160. package/dist/commands/status/print.js.map +1 -0
  161. package/dist/commands/status/status.js +119 -0
  162. package/dist/commands/status/status.js.map +1 -0
  163. package/dist/commands/steps/steps.js +189 -0
  164. package/dist/commands/steps/steps.js.map +1 -0
  165. package/dist/commands/subsystem/edit.js +192 -0
  166. package/dist/commands/subsystem/edit.js.map +1 -0
  167. package/dist/commands/subsystem/move.js +265 -0
  168. package/dist/commands/subsystem/move.js.map +1 -0
  169. package/dist/commands/subsystem/query.js +115 -0
  170. package/dist/commands/subsystem/query.js.map +1 -0
  171. package/dist/commands/subsystem/subsystem.js +101 -0
  172. package/dist/commands/subsystem/subsystem.js.map +1 -0
  173. package/dist/commands/subsystem/sync.js +103 -0
  174. package/dist/commands/subsystem/sync.js.map +1 -0
  175. package/dist/commands/subsystem/txn/txn.js +94 -0
  176. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  177. package/dist/commands/subsystem/txn/views.js +70 -0
  178. package/dist/commands/subsystem/txn/views.js.map +1 -0
  179. package/dist/commands/unarchive/manifest.js +160 -0
  180. package/dist/commands/unarchive/manifest.js.map +1 -0
  181. package/dist/commands/{unarchive.js → unarchive/restore.js} +47 -160
  182. package/dist/commands/unarchive/restore.js.map +1 -0
  183. package/dist/commands/unarchive/unarchive.js +67 -0
  184. package/dist/commands/unarchive/unarchive.js.map +1 -0
  185. package/dist/commands/validate/arch-coverage.js +204 -0
  186. package/dist/commands/validate/arch-coverage.js.map +1 -0
  187. package/dist/commands/validate/checks/fleet-shape.js +296 -0
  188. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  189. package/dist/commands/validate/checks/health-deps.js +55 -0
  190. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  191. package/dist/commands/validate/checks/requirements.js +254 -0
  192. package/dist/commands/validate/checks/requirements.js.map +1 -0
  193. package/dist/commands/validate/checks/sources.js +76 -0
  194. package/dist/commands/validate/checks/sources.js.map +1 -0
  195. package/dist/commands/validate/checks/vocabulary.js +31 -0
  196. package/dist/commands/validate/checks/vocabulary.js.map +1 -0
  197. package/dist/commands/validate/feature.js +216 -0
  198. package/dist/commands/validate/feature.js.map +1 -0
  199. package/dist/commands/validate/fleet/census.js +69 -0
  200. package/dist/commands/validate/fleet/census.js.map +1 -0
  201. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  202. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  203. package/dist/commands/validate/fleet/landscape.js +353 -0
  204. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  205. package/dist/commands/validate/fleet/load.js +52 -0
  206. package/dist/commands/validate/fleet/load.js.map +1 -0
  207. package/dist/commands/validate/fleet/obligations.js +270 -0
  208. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  209. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  210. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  211. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  212. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  213. package/dist/commands/validate/fleet/scorecard/print.js +63 -0
  214. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  215. package/dist/commands/validate/fleet/scorecard/scorecard.js +156 -0
  216. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  217. package/dist/commands/validate/fleet/usecases/capability-tag.js +94 -0
  218. package/dist/commands/validate/fleet/usecases/capability-tag.js.map +1 -0
  219. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  220. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  221. package/dist/commands/validate/fleet/usecases/requirement-tag.js +95 -0
  222. package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +1 -0
  223. package/dist/commands/validate/fleet/usecases/steps.js +197 -0
  224. package/dist/commands/validate/fleet/usecases/steps.js.map +1 -0
  225. package/dist/commands/validate/fleet/usecases/usecases.js +99 -0
  226. package/dist/commands/validate/fleet/usecases/usecases.js.map +1 -0
  227. package/dist/commands/validate/fleet/views/ids.js +40 -0
  228. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  229. package/dist/commands/validate/fleet/views/stale.js +59 -0
  230. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  231. package/dist/commands/validate/links/corpus.js +92 -0
  232. package/dist/commands/validate/links/corpus.js.map +1 -0
  233. package/dist/commands/validate/links/glossary.js +75 -0
  234. package/dist/commands/validate/links/glossary.js.map +1 -0
  235. package/dist/commands/validate/report.js +269 -0
  236. package/dist/commands/validate/report.js.map +1 -0
  237. package/dist/commands/validate/service/api.js +338 -0
  238. package/dist/commands/validate/service/api.js.map +1 -0
  239. package/dist/commands/validate/service/events/events.js +219 -0
  240. package/dist/commands/validate/service/events/events.js.map +1 -0
  241. package/dist/commands/validate/service/events/message-producers.js +77 -0
  242. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  243. package/dist/commands/validate/service/evidence-pins.js +131 -0
  244. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  245. package/dist/commands/validate/service/service.js +251 -0
  246. package/dist/commands/validate/service/service.js.map +1 -0
  247. package/dist/commands/validate/service/specs.js +251 -0
  248. package/dist/commands/validate/service/specs.js.map +1 -0
  249. package/dist/commands/validate/service/spine.js +113 -0
  250. package/dist/commands/validate/service/spine.js.map +1 -0
  251. package/dist/commands/validate/validate.js +338 -0
  252. package/dist/commands/validate/validate.js.map +1 -0
  253. package/dist/commands/verify/cross/diff.js +182 -0
  254. package/dist/commands/verify/cross/diff.js.map +1 -0
  255. package/dist/commands/verify/evidence/contract.js +32 -0
  256. package/dist/commands/verify/evidence/contract.js.map +1 -0
  257. package/dist/commands/verify/evidence/pins.js +52 -0
  258. package/dist/commands/verify/evidence/pins.js.map +1 -0
  259. package/dist/commands/verify/evidence/read.js +72 -0
  260. package/dist/commands/verify/evidence/read.js.map +1 -0
  261. package/dist/commands/verify/frozen.js +241 -0
  262. package/dist/commands/verify/frozen.js.map +1 -0
  263. package/dist/commands/verify/record.js +226 -0
  264. package/dist/commands/verify/record.js.map +1 -0
  265. package/dist/commands/verify/report.js +223 -0
  266. package/dist/commands/verify/report.js.map +1 -0
  267. package/dist/commands/verify/results.js +246 -0
  268. package/dist/commands/verify/results.js.map +1 -0
  269. package/dist/commands/verify/verify.js +217 -0
  270. package/dist/commands/verify/verify.js.map +1 -0
  271. package/dist/commands/vouch/contract.js +11 -0
  272. package/dist/commands/vouch/contract.js.map +1 -0
  273. package/dist/commands/vouch/pack/contract.js +2 -0
  274. package/dist/commands/vouch/pack/contract.js.map +1 -0
  275. package/dist/commands/vouch/pack/pack.js +266 -0
  276. package/dist/commands/vouch/pack/pack.js.map +1 -0
  277. package/dist/commands/vouch/pack/print.js +271 -0
  278. package/dist/commands/vouch/pack/print.js.map +1 -0
  279. package/dist/commands/vouch/pack/sections.js +142 -0
  280. package/dist/commands/vouch/pack/sections.js.map +1 -0
  281. package/dist/commands/vouch/prompt/confirm.js +46 -0
  282. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  283. package/dist/commands/vouch/report.js +101 -0
  284. package/dist/commands/vouch/report.js.map +1 -0
  285. package/dist/commands/vouch/run.js +285 -0
  286. package/dist/commands/vouch/run.js.map +1 -0
  287. package/dist/commands/vouch/sample/plan.js +125 -0
  288. package/dist/commands/vouch/sample/plan.js.map +1 -0
  289. package/dist/commands/vouch/sample/print.js +109 -0
  290. package/dist/commands/vouch/sample/print.js.map +1 -0
  291. package/dist/commands/vouch/vet/verify.js +123 -0
  292. package/dist/commands/vouch/vet/verify.js.map +1 -0
  293. package/dist/commands/vouch/vouch.js +176 -0
  294. package/dist/commands/vouch/vouch.js.map +1 -0
  295. package/dist/core/agent/agents-md/artifacts.js +220 -0
  296. package/dist/core/agent/agents-md/artifacts.js.map +1 -0
  297. package/dist/core/agent/agents-md/command-map.js +324 -0
  298. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  299. package/dist/core/agent/agents-md/cycle.js +165 -0
  300. package/dist/core/agent/agents-md/cycle.js.map +1 -0
  301. package/dist/core/agent/agents-md/map/explain.js +34 -0
  302. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  303. package/dist/core/agent/agents-md/map/lenses/context.js +41 -0
  304. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  305. package/dist/core/agent/agents-md/map/lenses/diff.js +46 -0
  306. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  307. package/dist/core/agent/agents-md/map/lenses/gate.js +57 -0
  308. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  309. package/dist/core/agent/agents-md/map/mcp.js +41 -0
  310. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  311. package/dist/core/agent/agents-md/map/status.js +62 -0
  312. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  313. package/dist/core/agent/agents-md/map/subsystem.js +32 -0
  314. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  315. package/dist/core/agent/agents-md/map/usecases.js +60 -0
  316. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  317. package/dist/core/agent/agents-md/refusals.js +246 -0
  318. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  319. package/dist/core/agent/agents-md/shipped/archive-gate.js +98 -0
  320. package/dist/core/agent/agents-md/shipped/archive-gate.js.map +1 -0
  321. package/dist/core/agent/agents-md/spine.js +40 -0
  322. package/dist/core/agent/agents-md/spine.js.map +1 -0
  323. package/dist/core/agent/agents-md.js +170 -0
  324. package/dist/core/agent/agents-md.js.map +1 -0
  325. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +50 -0
  326. package/dist/core/agent/agents-stamp.js.map +1 -0
  327. package/dist/core/agent/contract.js +2 -0
  328. package/dist/core/agent/contract.js.map +1 -0
  329. package/dist/core/agent/protocol.js +193 -0
  330. package/dist/core/agent/protocol.js.map +1 -0
  331. package/dist/core/agent/scaffold.js +259 -0
  332. package/dist/core/agent/scaffold.js.map +1 -0
  333. package/dist/core/agent/support/report.js +103 -0
  334. package/dist/core/agent/support/report.js.map +1 -0
  335. package/dist/core/agent/tools/dialects.js +150 -0
  336. package/dist/core/agent/tools/dialects.js.map +1 -0
  337. package/dist/core/agent/tools/registry.js +228 -0
  338. package/dist/core/agent/tools/registry.js.map +1 -0
  339. package/dist/core/agent/workflows/adopt.js +133 -0
  340. package/dist/core/agent/workflows/adopt.js.map +1 -0
  341. package/dist/core/agent/workflows/check.js +337 -0
  342. package/dist/core/agent/workflows/check.js.map +1 -0
  343. package/dist/core/agent/workflows/closing.js +262 -0
  344. package/dist/core/agent/workflows/closing.js.map +1 -0
  345. package/dist/core/agent/workflows/feature.js +105 -0
  346. package/dist/core/agent/workflows/feature.js.map +1 -0
  347. package/dist/core/agent/workflows/implement.js +105 -0
  348. package/dist/core/agent/workflows/implement.js.map +1 -0
  349. package/dist/core/agent/workflows/reference/authoring.js +209 -0
  350. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  351. package/dist/core/agent/workflows/reference/codes.js +65 -0
  352. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  353. package/dist/core/agent/workflows/reference/done-check.js +188 -0
  354. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  355. package/dist/core/agent/workflows/reference/reference.js +16 -0
  356. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  357. package/dist/core/agent/workflows/reference/spine.js +297 -0
  358. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  359. package/dist/core/asyncapi/baseline/plan.js +110 -0
  360. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  361. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  362. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  363. package/dist/core/asyncapi/depth.js +164 -0
  364. package/dist/core/asyncapi/depth.js.map +1 -0
  365. package/dist/core/asyncapi/digest.js +141 -0
  366. package/dist/core/asyncapi/digest.js.map +1 -0
  367. package/dist/core/asyncapi/merge/components.js +91 -0
  368. package/dist/core/asyncapi/merge/components.js.map +1 -0
  369. package/dist/core/asyncapi/merge/error.js +33 -0
  370. package/dist/core/asyncapi/merge/error.js.map +1 -0
  371. package/dist/core/asyncapi/merge/markers.js +308 -0
  372. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  373. package/dist/core/asyncapi/merge/merge.js +215 -0
  374. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  375. package/dist/core/asyncapi/merge/pin.js +107 -0
  376. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  377. package/dist/core/asyncapi/model.js +11 -0
  378. package/dist/core/asyncapi/model.js.map +1 -0
  379. package/dist/core/asyncapi/producers.js +50 -0
  380. package/dist/core/asyncapi/producers.js.map +1 -0
  381. package/dist/core/{asyncapi.js → asyncapi/read.js} +95 -109
  382. package/dist/core/asyncapi/read.js.map +1 -0
  383. package/dist/core/brief/brief.js +225 -0
  384. package/dist/core/brief/brief.js.map +1 -0
  385. package/dist/core/brief/checks.js +250 -0
  386. package/dist/core/brief/checks.js.map +1 -0
  387. package/dist/core/brief/landscape.js +194 -0
  388. package/dist/core/brief/landscape.js.map +1 -0
  389. package/dist/core/brief/targets.js +226 -0
  390. package/dist/core/brief/targets.js.map +1 -0
  391. package/dist/core/brief/unchecked.js +48 -0
  392. package/dist/core/brief/unchecked.js.map +1 -0
  393. package/dist/core/c4/arch.js +174 -0
  394. package/dist/core/c4/arch.js.map +1 -0
  395. package/dist/core/c4/likec4.js +90 -0
  396. package/dist/core/c4/likec4.js.map +1 -0
  397. package/dist/core/c4/parsed/deployment.js +158 -0
  398. package/dist/core/c4/parsed/deployment.js.map +1 -0
  399. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  400. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  401. package/dist/core/c4/parsed/specification.js +78 -0
  402. package/dist/core/c4/parsed/specification.js.map +1 -0
  403. package/dist/core/c4/parsed/values.js +57 -0
  404. package/dist/core/c4/parsed/values.js.map +1 -0
  405. package/dist/core/c4/parsed/view-ids.js +75 -0
  406. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  407. package/dist/core/c4/project/architecture.js +45 -0
  408. package/dist/core/c4/project/architecture.js.map +1 -0
  409. package/dist/core/c4/project/documents.js +58 -0
  410. package/dist/core/c4/project/documents.js.map +1 -0
  411. package/dist/core/c4/project/load.js +187 -0
  412. package/dist/core/c4/project/load.js.map +1 -0
  413. package/dist/core/c4/project/staged.js +220 -0
  414. package/dist/core/c4/project/staged.js.map +1 -0
  415. package/dist/core/c4/resolve/service.js +159 -0
  416. package/dist/core/c4/resolve/service.js.map +1 -0
  417. package/dist/core/c4/resolve/steps.js +144 -0
  418. package/dist/core/c4/resolve/steps.js.map +1 -0
  419. package/dist/core/c4/seed/fleet-file.js +201 -0
  420. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  421. package/dist/core/c4/seed/items.js +91 -0
  422. package/dist/core/c4/seed/items.js.map +1 -0
  423. package/dist/core/c4/seed/stamp.js +48 -0
  424. package/dist/core/c4/seed/stamp.js.map +1 -0
  425. package/dist/core/c4/seed/template.js +109 -0
  426. package/dist/core/c4/seed/template.js.map +1 -0
  427. package/dist/core/c4/source-mask.js +82 -0
  428. package/dist/core/c4/source-mask.js.map +1 -0
  429. package/dist/core/c4/source-scan.js +227 -0
  430. package/dist/core/c4/source-scan.js.map +1 -0
  431. package/dist/core/c4/splice/authored-source.js +101 -0
  432. package/dist/core/c4/splice/authored-source.js.map +1 -0
  433. package/dist/core/c4/splice/contract.js +10 -0
  434. package/dist/core/c4/splice/contract.js.map +1 -0
  435. package/dist/core/c4/splice/delta-blocks.js +139 -0
  436. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  437. package/dist/core/c4/splice/identity/edges.js +36 -0
  438. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  439. package/dist/core/c4/splice/landscape-merge.js +269 -0
  440. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  441. package/dist/core/c4/splice/placement.js +194 -0
  442. package/dist/core/c4/splice/placement.js.map +1 -0
  443. package/dist/core/c4/workspace.js +174 -0
  444. package/dist/core/c4/workspace.js.map +1 -0
  445. package/dist/core/capabilities/authoring/notes.js +141 -0
  446. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  447. package/dist/core/capabilities/capabilities.js +124 -0
  448. package/dist/core/capabilities/capabilities.js.map +1 -0
  449. package/dist/core/capabilities/delta/doc.js +50 -0
  450. package/dist/core/capabilities/delta/doc.js.map +1 -0
  451. package/dist/core/capabilities/delta/overlay.js +129 -0
  452. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  453. package/dist/core/capabilities/delta/summary.js +57 -0
  454. package/dist/core/capabilities/delta/summary.js.map +1 -0
  455. package/dist/core/capabilities/delta/tree.js +43 -0
  456. package/dist/core/capabilities/delta/tree.js.map +1 -0
  457. package/dist/core/capabilities/delta/uncovered.js +222 -0
  458. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  459. package/dist/core/capabilities/findings.js +342 -0
  460. package/dist/core/capabilities/findings.js.map +1 -0
  461. package/dist/core/capabilities/realizes/findings.js +181 -0
  462. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  463. package/dist/core/capabilities/realizes/join.js +143 -0
  464. package/dist/core/capabilities/realizes/join.js.map +1 -0
  465. package/dist/core/capabilities/rollup.js +199 -0
  466. package/dist/core/capabilities/rollup.js.map +1 -0
  467. package/dist/core/capabilities/tree.js +126 -0
  468. package/dist/core/capabilities/tree.js.map +1 -0
  469. package/dist/core/capabilities/usecase-join.js +277 -0
  470. package/dist/core/capabilities/usecase-join.js.map +1 -0
  471. package/dist/core/coherence/authoring/scaffold.js +177 -0
  472. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  473. package/dist/core/coherence/authoring/sentinels.js +74 -0
  474. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  475. package/dist/core/coherence/coherence.js +287 -0
  476. package/dist/core/coherence/coherence.js.map +1 -0
  477. package/dist/core/coherence/declared.js +269 -0
  478. package/dist/core/coherence/declared.js.map +1 -0
  479. package/dist/core/coherence/events/declared.js +206 -0
  480. package/dist/core/coherence/events/declared.js.map +1 -0
  481. package/dist/core/coherence/events/events.js +204 -0
  482. package/dist/core/coherence/events/events.js.map +1 -0
  483. package/dist/core/coherence/events/grades.js +166 -0
  484. package/dist/core/coherence/events/grades.js.map +1 -0
  485. package/dist/core/coherence/events/lookups.js +122 -0
  486. package/dist/core/coherence/events/lookups.js.map +1 -0
  487. package/dist/core/coherence/events/merged.js +40 -0
  488. package/dist/core/coherence/events/merged.js.map +1 -0
  489. package/dist/core/coherence/living.js +198 -0
  490. package/dist/core/coherence/living.js.map +1 -0
  491. package/dist/core/coherence/lookups.js +155 -0
  492. package/dist/core/coherence/lookups.js.map +1 -0
  493. package/dist/core/coherence/pending.js +39 -0
  494. package/dist/core/coherence/pending.js.map +1 -0
  495. package/dist/core/conflict-markers.js +60 -0
  496. package/dist/core/conflict-markers.js.map +1 -0
  497. package/dist/core/delta/claims.js +73 -0
  498. package/dist/core/delta/claims.js.map +1 -0
  499. package/dist/core/delta/delta.js +296 -0
  500. package/dist/core/delta/delta.js.map +1 -0
  501. package/dist/core/delta/document.js +177 -0
  502. package/dist/core/delta/document.js.map +1 -0
  503. package/dist/core/delta/scope.js +48 -0
  504. package/dist/core/delta/scope.js.map +1 -0
  505. package/dist/core/delta/select.js +237 -0
  506. package/dist/core/delta/select.js.map +1 -0
  507. package/dist/core/dependencies/dependencies.js +141 -0
  508. package/dist/core/dependencies/dependencies.js.map +1 -0
  509. package/dist/core/dependencies/facts.js +165 -0
  510. package/dist/core/dependencies/facts.js.map +1 -0
  511. package/dist/core/dependencies/fanin.js +88 -0
  512. package/dist/core/dependencies/fanin.js.map +1 -0
  513. package/dist/core/dependencies/graph.js +106 -0
  514. package/dist/core/dependencies/graph.js.map +1 -0
  515. package/dist/core/deployment/delta.js +188 -0
  516. package/dist/core/deployment/delta.js.map +1 -0
  517. package/dist/core/deployment/objects.js +145 -0
  518. package/dist/core/deployment/objects.js.map +1 -0
  519. package/dist/core/diff/base-git.js +148 -0
  520. package/dist/core/diff/base-git.js.map +1 -0
  521. package/dist/core/diff/base-state.js +209 -0
  522. package/dist/core/diff/base-state.js.map +1 -0
  523. package/dist/core/diff/current-state.js +96 -0
  524. package/dist/core/diff/current-state.js.map +1 -0
  525. package/dist/core/diff/scope/changed-paths.js +188 -0
  526. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  527. package/dist/core/diff/semantic.js +243 -0
  528. package/dist/core/diff/semantic.js.map +1 -0
  529. package/dist/core/diff/victims.js +247 -0
  530. package/dist/core/diff/victims.js.map +1 -0
  531. package/dist/core/docs.js +7 -64
  532. package/dist/core/docs.js.map +1 -1
  533. package/dist/core/doctor/agents.js +222 -0
  534. package/dist/core/doctor/agents.js.map +1 -0
  535. package/dist/core/doctor/config.js +135 -0
  536. package/dist/core/doctor/config.js.map +1 -0
  537. package/dist/core/doctor/doctor.js +275 -0
  538. package/dist/core/doctor/doctor.js.map +1 -0
  539. package/dist/core/doctor/report.js +13 -0
  540. package/dist/core/doctor/report.js.map +1 -0
  541. package/dist/core/doctor/residue.js +110 -0
  542. package/dist/core/doctor/residue.js.map +1 -0
  543. package/dist/core/document/apply.js +77 -0
  544. package/dist/core/document/apply.js.map +1 -0
  545. package/dist/core/{frontmatter.js → document/frontmatter.js} +48 -2
  546. package/dist/core/document/frontmatter.js.map +1 -0
  547. package/dist/core/document/grammar/directives.js +143 -0
  548. package/dist/core/document/grammar/directives.js.map +1 -0
  549. package/dist/core/document/parse.js +263 -0
  550. package/dist/core/document/parse.js.map +1 -0
  551. package/dist/core/document/scenarios.js +221 -0
  552. package/dist/core/document/scenarios.js.map +1 -0
  553. package/dist/core/document/spec.js +241 -0
  554. package/dist/core/document/spec.js.map +1 -0
  555. package/dist/core/{config.js → envelope/config.js} +79 -18
  556. package/dist/core/envelope/config.js.map +1 -0
  557. package/dist/core/envelope/json.js +175 -0
  558. package/dist/core/envelope/json.js.map +1 -0
  559. package/dist/core/{version.js → envelope/version.js} +3 -3
  560. package/dist/core/envelope/version.js.map +1 -0
  561. package/dist/core/explain/families.js +175 -0
  562. package/dist/core/explain/families.js.map +1 -0
  563. package/dist/core/explain/fix-tables.js +178 -0
  564. package/dist/core/explain/fix-tables.js.map +1 -0
  565. package/dist/core/explain/lookup.js +181 -0
  566. package/dist/core/explain/lookup.js.map +1 -0
  567. package/dist/core/explain/refusals.js +49 -0
  568. package/dist/core/explain/refusals.js.map +1 -0
  569. package/dist/core/explain/terms.js +144 -0
  570. package/dist/core/explain/terms.js.map +1 -0
  571. package/dist/core/explore/describe.js +105 -0
  572. package/dist/core/explore/describe.js.map +1 -0
  573. package/dist/core/{explore.js → explore/explore.js} +50 -101
  574. package/dist/core/explore/explore.js.map +1 -0
  575. package/dist/core/fleet-context.js +120 -78
  576. package/dist/core/fleet-context.js.map +1 -1
  577. package/dist/core/gate/checks.js +201 -0
  578. package/dist/core/gate/checks.js.map +1 -0
  579. package/dist/core/gate/partners.js +205 -0
  580. package/dist/core/gate/partners.js.map +1 -0
  581. package/dist/core/gate/report.js +47 -0
  582. package/dist/core/gate/report.js.map +1 -0
  583. package/dist/core/gate/verification.js +113 -0
  584. package/dist/core/gate/verification.js.map +1 -0
  585. package/dist/core/gherkin/digest.js +60 -0
  586. package/dist/core/gherkin/digest.js.map +1 -0
  587. package/dist/core/gherkin/emit.js +177 -0
  588. package/dist/core/gherkin/emit.js.map +1 -0
  589. package/dist/core/gherkin/read.js +76 -0
  590. package/dist/core/gherkin/read.js.map +1 -0
  591. package/dist/core/gherkin/stale.js +234 -0
  592. package/dist/core/gherkin/stale.js.map +1 -0
  593. package/dist/core/gherkin/stamp.js +77 -0
  594. package/dist/core/gherkin/stamp.js.map +1 -0
  595. package/dist/core/gherkin/steps/catalogue.js +154 -0
  596. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  597. package/dist/core/gherkin/steps/inventory.js +98 -0
  598. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  599. package/dist/core/gherkin/steps/phrase.js +72 -0
  600. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  601. package/dist/core/glossary/delta.js +106 -0
  602. package/dist/core/glossary/delta.js.map +1 -0
  603. package/dist/core/glossary/tree.js +86 -0
  604. package/dist/core/glossary/tree.js.map +1 -0
  605. package/dist/core/kernel/concurrency.js.map +1 -0
  606. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  607. package/dist/core/kernel/document-bytes.js.map +1 -0
  608. package/dist/core/kernel/fences.js +42 -0
  609. package/dist/core/kernel/fences.js.map +1 -0
  610. package/dist/core/kernel/ids/capability.js +72 -0
  611. package/dist/core/kernel/ids/capability.js.map +1 -0
  612. package/dist/core/kernel/ids/dirs.js +33 -0
  613. package/dist/core/kernel/ids/dirs.js.map +1 -0
  614. package/dist/core/kernel/ids/feature.js +75 -0
  615. package/dist/core/kernel/ids/feature.js.map +1 -0
  616. package/dist/core/kernel/ids/service.js +156 -0
  617. package/dist/core/kernel/ids/service.js.map +1 -0
  618. package/dist/core/kernel/ids/subsystem.js +63 -0
  619. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  620. package/dist/core/{path-safety.js → kernel/path-safety.js} +18 -4
  621. package/dist/core/kernel/path-safety.js.map +1 -0
  622. package/dist/core/kernel/records.js.map +1 -0
  623. package/dist/core/links/backlinks.js +68 -0
  624. package/dist/core/links/backlinks.js.map +1 -0
  625. package/dist/core/links/case.js +74 -0
  626. package/dist/core/links/case.js.map +1 -0
  627. package/dist/core/links/corpus.js +104 -0
  628. package/dist/core/links/corpus.js.map +1 -0
  629. package/dist/core/links/findings.js +110 -0
  630. package/dist/core/links/findings.js.map +1 -0
  631. package/dist/core/links/parse.js +236 -0
  632. package/dist/core/links/parse.js.map +1 -0
  633. package/dist/core/mcp/argv.js +111 -0
  634. package/dist/core/mcp/argv.js.map +1 -0
  635. package/dist/core/mcp/author-tools.js +72 -0
  636. package/dist/core/mcp/author-tools.js.map +1 -0
  637. package/dist/core/mcp/framing.js +46 -0
  638. package/dist/core/mcp/framing.js.map +1 -0
  639. package/dist/core/mcp/protocol.js +280 -0
  640. package/dist/core/mcp/protocol.js.map +1 -0
  641. package/dist/core/mcp/tools.js +314 -0
  642. package/dist/core/mcp/tools.js.map +1 -0
  643. package/dist/core/obligations/obligations.js +106 -0
  644. package/dist/core/obligations/obligations.js.map +1 -0
  645. package/dist/core/openapi/baseline/gate.js +166 -0
  646. package/dist/core/openapi/baseline/gate.js.map +1 -0
  647. package/dist/core/openapi/baseline/plan.js +112 -0
  648. package/dist/core/openapi/baseline/plan.js.map +1 -0
  649. package/dist/core/openapi/baseline/record.js +175 -0
  650. package/dist/core/openapi/baseline/record.js.map +1 -0
  651. package/dist/core/openapi/depth.js +122 -0
  652. package/dist/core/openapi/depth.js.map +1 -0
  653. package/dist/core/openapi/digest.js +189 -0
  654. package/dist/core/openapi/digest.js.map +1 -0
  655. package/dist/core/{openapi.js → openapi/doc.js} +44 -106
  656. package/dist/core/openapi/doc.js.map +1 -0
  657. package/dist/core/openapi/merge/components.js +234 -0
  658. package/dist/core/openapi/merge/components.js.map +1 -0
  659. package/dist/core/openapi/merge/error.js +26 -0
  660. package/dist/core/openapi/merge/error.js.map +1 -0
  661. package/dist/core/openapi/merge/markers.js +208 -0
  662. package/dist/core/openapi/merge/markers.js.map +1 -0
  663. package/dist/core/openapi/merge/merge.js +256 -0
  664. package/dist/core/openapi/merge/merge.js.map +1 -0
  665. package/dist/core/openapi/merge/pin.js +128 -0
  666. package/dist/core/openapi/merge/pin.js.map +1 -0
  667. package/dist/core/openspec/decide/capabilities.js +244 -0
  668. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  669. package/dist/core/openspec/decide/dispositions.js +63 -0
  670. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  671. package/dist/core/openspec/decide/renames.js +179 -0
  672. package/dist/core/openspec/decide/renames.js.map +1 -0
  673. package/dist/core/openspec/decide/verdict.js +84 -0
  674. package/dist/core/openspec/decide/verdict.js.map +1 -0
  675. package/dist/core/openspec/inventory.js +221 -0
  676. package/dist/core/openspec/inventory.js.map +1 -0
  677. package/dist/core/openspec/model/mapping.js +76 -0
  678. package/dist/core/openspec/model/mapping.js.map +1 -0
  679. package/dist/core/openspec/model/model.js +65 -0
  680. package/dist/core/openspec/model/model.js.map +1 -0
  681. package/dist/core/openspec/scan/changes.js +235 -0
  682. package/dist/core/openspec/scan/changes.js.map +1 -0
  683. package/dist/core/openspec/scan/config.js +200 -0
  684. package/dist/core/openspec/scan/config.js.map +1 -0
  685. package/dist/core/openspec/scan/shape.js +260 -0
  686. package/dist/core/openspec/scan/shape.js.map +1 -0
  687. package/dist/core/openspec/scan/walk.js +133 -0
  688. package/dist/core/openspec/scan/walk.js.map +1 -0
  689. package/dist/core/openspec/scan/workspace.js +71 -0
  690. package/dist/core/openspec/scan/workspace.js.map +1 -0
  691. package/dist/core/owners/codeowners.js +141 -0
  692. package/dist/core/owners/codeowners.js.map +1 -0
  693. package/dist/core/pack/features.js +120 -0
  694. package/dist/core/pack/features.js.map +1 -0
  695. package/dist/core/pack/joins.js +112 -0
  696. package/dist/core/pack/joins.js.map +1 -0
  697. package/dist/core/pack/living.js +137 -0
  698. package/dist/core/pack/living.js.map +1 -0
  699. package/dist/core/pack/pack.js +76 -0
  700. package/dist/core/pack/pack.js.map +1 -0
  701. package/dist/core/permissions/permissions.js +87 -0
  702. package/dist/core/permissions/permissions.js.map +1 -0
  703. package/dist/core/projection/api.js +84 -0
  704. package/dist/core/projection/api.js.map +1 -0
  705. package/dist/core/projection/arch-slice.js +63 -0
  706. package/dist/core/projection/arch-slice.js.map +1 -0
  707. package/dist/core/projection/events.js +34 -0
  708. package/dist/core/projection/events.js.map +1 -0
  709. package/dist/core/provenance/findings.js +208 -0
  710. package/dist/core/provenance/findings.js.map +1 -0
  711. package/dist/core/provenance/git.js +225 -0
  712. package/dist/core/provenance/git.js.map +1 -0
  713. package/dist/core/provenance/gitq/moves.js +182 -0
  714. package/dist/core/provenance/gitq/moves.js.map +1 -0
  715. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  716. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  717. package/dist/core/provenance/sample/scope.js +238 -0
  718. package/dist/core/provenance/sample/scope.js.map +1 -0
  719. package/dist/core/provenance/sample/sections.js +61 -0
  720. package/dist/core/provenance/sample/sections.js.map +1 -0
  721. package/dist/core/provenance/sources.js +263 -0
  722. package/dist/core/provenance/sources.js.map +1 -0
  723. package/dist/core/provenance/stamp.js +232 -0
  724. package/dist/core/provenance/stamp.js.map +1 -0
  725. package/dist/core/provenance/walk.js +157 -0
  726. package/dist/core/provenance/walk.js.map +1 -0
  727. package/dist/core/repo/authored/paths.js +210 -0
  728. package/dist/core/repo/authored/paths.js.map +1 -0
  729. package/dist/core/repo/entries.js +126 -0
  730. package/dist/core/repo/entries.js.map +1 -0
  731. package/dist/core/repo/paths.js +277 -0
  732. package/dist/core/repo/paths.js.map +1 -0
  733. package/dist/core/repo/repo.js +248 -0
  734. package/dist/core/repo/repo.js.map +1 -0
  735. package/dist/core/repo/service-target.js +153 -0
  736. package/dist/core/repo/service-target.js.map +1 -0
  737. package/dist/core/repo/state.js +58 -0
  738. package/dist/core/repo/state.js.map +1 -0
  739. package/dist/core/repo/tree/find.js +52 -0
  740. package/dist/core/repo/tree/find.js.map +1 -0
  741. package/dist/core/repo/tree/fs.js +64 -0
  742. package/dist/core/repo/tree/fs.js.map +1 -0
  743. package/dist/core/repo/tree/marker.js +61 -0
  744. package/dist/core/repo/tree/marker.js.map +1 -0
  745. package/dist/core/repo/tree/views.js +172 -0
  746. package/dist/core/repo/tree/views.js.map +1 -0
  747. package/dist/core/repo/tree/walk.js +234 -0
  748. package/dist/core/repo/tree/walk.js.map +1 -0
  749. package/dist/core/results.js +99 -2
  750. package/dist/core/results.js.map +1 -1
  751. package/dist/core/scaffold/landscape.js +131 -0
  752. package/dist/core/scaffold/landscape.js.map +1 -0
  753. package/dist/core/scaffold/readme.js +84 -0
  754. package/dist/core/scaffold/readme.js.map +1 -0
  755. package/dist/core/staging/commit.js +241 -0
  756. package/dist/core/staging/commit.js.map +1 -0
  757. package/dist/core/staging/interrupted.js +96 -0
  758. package/dist/core/staging/interrupted.js.map +1 -0
  759. package/dist/core/staging/lock.js +206 -0
  760. package/dist/core/staging/lock.js.map +1 -0
  761. package/dist/core/staging/recovery/finding.js +35 -0
  762. package/dist/core/staging/recovery/finding.js.map +1 -0
  763. package/dist/core/staging/recovery/intent.js +98 -0
  764. package/dist/core/staging/recovery/intent.js.map +1 -0
  765. package/dist/core/staging/recovery/recover.js +126 -0
  766. package/dist/core/staging/recovery/recover.js.map +1 -0
  767. package/dist/core/staging/recovery/residue.js +62 -0
  768. package/dist/core/staging/recovery/residue.js.map +1 -0
  769. package/dist/core/staging/snapshot.js +202 -0
  770. package/dist/core/staging/snapshot.js.map +1 -0
  771. package/dist/core/staging/txn/forward.js +171 -0
  772. package/dist/core/staging/txn/forward.js.map +1 -0
  773. package/dist/core/staging/txn/journal.js +139 -0
  774. package/dist/core/staging/txn/journal.js.map +1 -0
  775. package/dist/core/staging/txn/transaction.js +75 -0
  776. package/dist/core/staging/txn/transaction.js.map +1 -0
  777. package/dist/core/staging/writes.js +113 -0
  778. package/dist/core/staging/writes.js.map +1 -0
  779. package/dist/core/status/actions/execution.js +49 -0
  780. package/dist/core/status/actions/execution.js.map +1 -0
  781. package/dist/core/status/contracts.js +102 -0
  782. package/dist/core/status/contracts.js.map +1 -0
  783. package/dist/core/status/feature/artifacts.js +196 -0
  784. package/dist/core/status/feature/artifacts.js.map +1 -0
  785. package/dist/core/status/feature/feature.js +207 -0
  786. package/dist/core/status/feature/feature.js.map +1 -0
  787. package/dist/core/status/feature/next.js +150 -0
  788. package/dist/core/status/feature/next.js.map +1 -0
  789. package/dist/core/status/feature/state.js +21 -0
  790. package/dist/core/status/feature/state.js.map +1 -0
  791. package/dist/core/status/fleet/fleet.js +197 -0
  792. package/dist/core/status/fleet/fleet.js.map +1 -0
  793. package/dist/core/status/fleet/next.js +207 -0
  794. package/dist/core/status/fleet/next.js.map +1 -0
  795. package/dist/core/status/interrupted.js +97 -0
  796. package/dist/core/status/interrupted.js.map +1 -0
  797. package/dist/core/status/report.js +31 -0
  798. package/dist/core/status/report.js.map +1 -0
  799. package/dist/core/status/scan.js +41 -0
  800. package/dist/core/status/scan.js.map +1 -0
  801. package/dist/core/status/verification.js +201 -0
  802. package/dist/core/status/verification.js.map +1 -0
  803. package/dist/core/usecases/capability.js +169 -0
  804. package/dist/core/usecases/capability.js.map +1 -0
  805. package/dist/core/usecases/delta/claims.js +116 -0
  806. package/dist/core/usecases/delta/claims.js.map +1 -0
  807. package/dist/core/usecases/delta/flows.js +103 -0
  808. package/dist/core/usecases/delta/flows.js.map +1 -0
  809. package/dist/core/usecases/delta/overlay.js +72 -0
  810. package/dist/core/usecases/delta/overlay.js.map +1 -0
  811. package/dist/core/usecases/fleet.js +137 -0
  812. package/dist/core/usecases/fleet.js.map +1 -0
  813. package/dist/core/usecases/operations.js +111 -0
  814. package/dist/core/usecases/operations.js.map +1 -0
  815. package/dist/core/usecases/place.js +44 -0
  816. package/dist/core/usecases/place.js.map +1 -0
  817. package/dist/core/usecases/touch.js +101 -0
  818. package/dist/core/usecases/touch.js.map +1 -0
  819. package/dist/core/verify/answers.js +173 -0
  820. package/dist/core/verify/answers.js.map +1 -0
  821. package/dist/core/verify/build.js +150 -0
  822. package/dist/core/verify/build.js.map +1 -0
  823. package/dist/core/verify/checklist.js +201 -0
  824. package/dist/core/verify/checklist.js.map +1 -0
  825. package/dist/core/verify/claims/identity.js +61 -0
  826. package/dist/core/verify/claims/identity.js.map +1 -0
  827. package/dist/core/verify/cross/diff.js +97 -0
  828. package/dist/core/verify/cross/diff.js.map +1 -0
  829. package/dist/core/verify/evidence/contract.js +169 -0
  830. package/dist/core/verify/evidence/contract.js.map +1 -0
  831. package/dist/core/verify/file.js +257 -0
  832. package/dist/core/verify/file.js.map +1 -0
  833. package/dist/core/verify/pins/lint.js +157 -0
  834. package/dist/core/verify/pins/lint.js.map +1 -0
  835. package/dist/core/verify/pins/pin.js +95 -0
  836. package/dist/core/verify/pins/pin.js.map +1 -0
  837. package/dist/core/verify/record.js +142 -0
  838. package/dist/core/verify/record.js.map +1 -0
  839. package/dist/core/verify/store/commit.js +89 -0
  840. package/dist/core/verify/store/commit.js.map +1 -0
  841. package/dist/core/verify/store/render.js +57 -0
  842. package/dist/core/verify/store/render.js.map +1 -0
  843. package/dist/core/vocabulary/health.js +91 -0
  844. package/dist/core/vocabulary/health.js.map +1 -0
  845. package/dist/core/vocabulary/issue.js +58 -0
  846. package/dist/core/vocabulary/issue.js.map +1 -0
  847. package/dist/core/vocabulary/maturity.js +145 -0
  848. package/dist/core/vocabulary/maturity.js.map +1 -0
  849. package/dist/core/{report.js → vocabulary/report.js} +30 -2
  850. package/dist/core/vocabulary/report.js.map +1 -0
  851. package/dist/core/vocabulary/steps.js +266 -0
  852. package/dist/core/vocabulary/steps.js.map +1 -0
  853. package/dist/core/workspace/discover.js +239 -0
  854. package/dist/core/workspace/discover.js.map +1 -0
  855. package/dist/core/workspace/render.js +52 -0
  856. package/dist/core/workspace/render.js.map +1 -0
  857. package/examples/README.md +189 -0
  858. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  859. package/examples/docs/architecture/capabilities.yaml +31 -0
  860. package/examples/docs/architecture/landscape.likec4 +280 -0
  861. package/examples/docs/architecture/obligations.yaml +23 -0
  862. package/examples/docs/architecture/permissions.yaml +50 -0
  863. package/examples/docs/architecture/subsystems.likec4 +11 -0
  864. package/examples/docs/architecture/usecases/order-notification.likec4 +65 -0
  865. package/examples/docs/capabilities/checkout/spec.md +55 -0
  866. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  867. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  868. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  869. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  870. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  871. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  872. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +129 -0
  873. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  874. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  875. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  876. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  877. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  878. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +28 -0
  879. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  880. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  881. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  882. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  883. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  884. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  885. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  886. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  887. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  888. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  889. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +70 -0
  890. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  891. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  892. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  893. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  894. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  895. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  896. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  897. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  898. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  899. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  900. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  901. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  902. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  903. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  904. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  905. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  906. package/examples/docs/glossary/order.md +15 -0
  907. package/examples/docs/glossary/payments/authorization.md +14 -0
  908. package/examples/docs/likec4.config.json +9 -0
  909. package/examples/docs/loam.json +3 -0
  910. package/examples/docs/services/checkout-web/model.likec4 +109 -0
  911. package/examples/docs/services/checkout-web/spec.md +91 -0
  912. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  913. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  914. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  915. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  916. package/examples/docs/services/order-service/arch.spec.md +127 -0
  917. package/examples/docs/services/order-service/asyncapi.yaml +108 -0
  918. package/examples/docs/services/order-service/health.yaml +57 -0
  919. package/examples/docs/services/order-service/model.likec4 +138 -0
  920. package/examples/docs/services/order-service/openapi.yaml +257 -0
  921. package/examples/docs/services/order-service/runbook.md +62 -0
  922. package/examples/docs/services/order-service/spec.md +134 -0
  923. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  924. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  925. package/examples/docs/services/payment-service/arch.spec.md +73 -0
  926. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  927. package/examples/docs/services/payment-service/health.yaml +39 -0
  928. package/examples/docs/services/payment-service/model.likec4 +67 -0
  929. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  930. package/examples/docs/services/payment-service/runbook.md +37 -0
  931. package/examples/docs/services/payment-service/spec.md +88 -0
  932. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  933. package/examples/docs/services/platform/identity-service/arch.spec.md +117 -0
  934. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  935. package/examples/docs/services/platform/identity-service/model.likec4 +83 -0
  936. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  937. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  938. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  939. package/examples/docs/services/platform/notification-service/asyncapi.yaml +199 -0
  940. package/examples/docs/services/platform/notification-service/health.yaml +35 -0
  941. package/examples/docs/services/platform/notification-service/model.likec4 +118 -0
  942. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  943. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  944. package/examples/docs/services/platform/subsystem.yaml +2 -0
  945. package/examples/fleet.yaml +57 -0
  946. package/package.json +19 -6
  947. package/dist/commands/adopt.js +0 -240
  948. package/dist/commands/adopt.js.map +0 -1
  949. package/dist/commands/archive.js +0 -1313
  950. package/dist/commands/archive.js.map +0 -1
  951. package/dist/commands/delta.js +0 -388
  952. package/dist/commands/delta.js.map +0 -1
  953. package/dist/commands/docs-repo-gate.js.map +0 -1
  954. package/dist/commands/format.js +0 -17
  955. package/dist/commands/format.js.map +0 -1
  956. package/dist/commands/gherkin.js +0 -309
  957. package/dist/commands/gherkin.js.map +0 -1
  958. package/dist/commands/init.js.map +0 -1
  959. package/dist/commands/list.js +0 -295
  960. package/dist/commands/list.js.map +0 -1
  961. package/dist/commands/migrate-openspec.js +0 -950
  962. package/dist/commands/migrate-openspec.js.map +0 -1
  963. package/dist/commands/new.js +0 -413
  964. package/dist/commands/new.js.map +0 -1
  965. package/dist/commands/rebase.js +0 -356
  966. package/dist/commands/rebase.js.map +0 -1
  967. package/dist/commands/show.js.map +0 -1
  968. package/dist/commands/status.js +0 -262
  969. package/dist/commands/status.js.map +0 -1
  970. package/dist/commands/unarchive.js.map +0 -1
  971. package/dist/commands/validate.js +0 -1773
  972. package/dist/commands/validate.js.map +0 -1
  973. package/dist/commands/verify.js +0 -775
  974. package/dist/commands/verify.js.map +0 -1
  975. package/dist/commands/vouch.js +0 -421
  976. package/dist/commands/vouch.js.map +0 -1
  977. package/dist/core/agent.js +0 -2173
  978. package/dist/core/agent.js.map +0 -1
  979. package/dist/core/agents-stamp.js.map +0 -1
  980. package/dist/core/arch.js +0 -130
  981. package/dist/core/arch.js.map +0 -1
  982. package/dist/core/asyncapi.js.map +0 -1
  983. package/dist/core/brief.js +0 -755
  984. package/dist/core/brief.js.map +0 -1
  985. package/dist/core/coherence.js +0 -577
  986. package/dist/core/coherence.js.map +0 -1
  987. package/dist/core/concurrency.js.map +0 -1
  988. package/dist/core/config.js.map +0 -1
  989. package/dist/core/delta.js +0 -476
  990. package/dist/core/delta.js.map +0 -1
  991. package/dist/core/dependencies.js +0 -356
  992. package/dist/core/dependencies.js.map +0 -1
  993. package/dist/core/doctor.js +0 -596
  994. package/dist/core/doctor.js.map +0 -1
  995. package/dist/core/document-bytes.js.map +0 -1
  996. package/dist/core/explore.js.map +0 -1
  997. package/dist/core/frontmatter.js.map +0 -1
  998. package/dist/core/gherkin.js +0 -463
  999. package/dist/core/gherkin.js.map +0 -1
  1000. package/dist/core/health.js +0 -67
  1001. package/dist/core/health.js.map +0 -1
  1002. package/dist/core/ids.js +0 -122
  1003. package/dist/core/ids.js.map +0 -1
  1004. package/dist/core/issue.js +0 -9
  1005. package/dist/core/issue.js.map +0 -1
  1006. package/dist/core/json.js +0 -74
  1007. package/dist/core/json.js.map +0 -1
  1008. package/dist/core/likec4.js +0 -489
  1009. package/dist/core/likec4.js.map +0 -1
  1010. package/dist/core/maturity.js +0 -66
  1011. package/dist/core/maturity.js.map +0 -1
  1012. package/dist/core/openapi-merge.js +0 -552
  1013. package/dist/core/openapi-merge.js.map +0 -1
  1014. package/dist/core/openapi.js.map +0 -1
  1015. package/dist/core/openspec-inventory.js +0 -1440
  1016. package/dist/core/openspec-inventory.js.map +0 -1
  1017. package/dist/core/path-safety.js.map +0 -1
  1018. package/dist/core/provenance.js +0 -787
  1019. package/dist/core/provenance.js.map +0 -1
  1020. package/dist/core/records.js.map +0 -1
  1021. package/dist/core/repo.js +0 -438
  1022. package/dist/core/repo.js.map +0 -1
  1023. package/dist/core/report.js.map +0 -1
  1024. package/dist/core/spec.js +0 -505
  1025. package/dist/core/spec.js.map +0 -1
  1026. package/dist/core/staging.js +0 -890
  1027. package/dist/core/staging.js.map +0 -1
  1028. package/dist/core/status.js +0 -1132
  1029. package/dist/core/status.js.map +0 -1
  1030. package/dist/core/steps.js +0 -72
  1031. package/dist/core/steps.js.map +0 -1
  1032. package/dist/core/verify.js +0 -807
  1033. package/dist/core/verify.js.map +0 -1
  1034. package/dist/core/version.js.map +0 -1
  1035. /package/dist/core/{concurrency.js → kernel/concurrency.js} +0 -0
  1036. /package/dist/core/{records.js → kernel/records.js} +0 -0
@@ -0,0 +1,279 @@
1
+ import { existsSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { loadConfig } from "../../core/envelope/config.js";
4
+ import { InvalidIdError, assertServiceId } from "../../core/kernel/ids/service.js";
5
+ import { emitJson, emitJsonError, fail, repoPath, reportNoConfig, sayExplain } from "../../core/envelope/json.js";
6
+ import { loadFile } from "../../core/c4/likec4.js";
7
+ import { compareIds, nearestIds } from "../../core/repo/entries.js";
8
+ import { featurePaths, featureSpecPaths } from "../../core/repo/paths.js";
9
+ import { missingFeatureMessage, resolveFeature } from "../../core/repo/repo.js";
10
+ import { parseRequirements } from "../../core/document/parse.js";
11
+ import {} from "../../core/document/spec.js";
12
+ import { stripFrontmatter } from "../../core/document/frontmatter.js";
13
+ import { apiChanges } from "../../core/projection/api.js";
14
+ import { eventChanges } from "../../core/projection/events.js";
15
+ import { archSlice, introducedServices, livingServices } from "../../core/projection/arch-slice.js";
16
+ import { useCaseBlastRadius } from "../../core/usecases/touch.js";
17
+ import { featureCapabilityDeltas } from "../../core/capabilities/delta/tree.js";
18
+ import { capabilityDeltaSummaries } from "../../core/capabilities/delta/summary.js";
19
+ import { printApi, printArchSlice, printCapabilities, printEvents, printRequirements, printUseCases } from "./print.js";
20
+ import { indent } from "./print.js";
21
+ export function registerDelta(program) {
22
+ program
23
+ .command("delta")
24
+ .argument("<featureId>", "feature id, e.g. FEAT-101")
25
+ .description("Project a feature onto a service: why + requirement delta + C4 changes")
26
+ .option("--service <id>", "service to project onto (defaults to the configured service)")
27
+ .option("--json", "emit the machine contract instead of the human view")
28
+ .action(async (featureId, opts) => {
29
+ const json = opts.json === true;
30
+ const loaded = await loadConfig();
31
+ if (loaded.kind !== "loaded") {
32
+ reportNoConfig(json, loaded);
33
+ return;
34
+ }
35
+ const config = loaded.config;
36
+ // The id grammar first, and on the RAW argument: `--service ../../etc`
37
+ // reaches `featureSpecPaths` and reads from outside the feature directory.
38
+ // One grammar for the whole tool (core/kernel/ids/service.ts).
39
+ if (opts.service !== undefined) {
40
+ try {
41
+ assertServiceId(opts.service, "--service");
42
+ }
43
+ catch (err) {
44
+ if (!(err instanceof InvalidIdError))
45
+ throw err;
46
+ fail(json, "invalid-option", err.message);
47
+ return;
48
+ }
49
+ }
50
+ // The feature is resolved BEFORE the service is chosen, because every
51
+ // sentence about the service ("which ones does this feature touch?") is
52
+ // only answerable once the feature is known.
53
+ const feature = await resolveFeature(config.docsDir, featureId, "exclude");
54
+ if (!feature) {
55
+ fail(json, "unknown-target", await missingFeatureMessage(config.docsDir, featureId));
56
+ return;
57
+ }
58
+ // Canonical id from here on — the delta's tags carry `#FEAT-5`, so a raw
59
+ // `FEAT-5-slug` argument used to empty the architecture slice silently.
60
+ const { id } = feature;
61
+ const paths = featurePaths(feature.dir);
62
+ const deltaDoc = existsSync(paths.delta) ? await loadFile(paths.delta) : null;
63
+ // Services the feature speaks about at all: one with a requirement delta,
64
+ // or one its C4 delta introduces. This is the list a refusal quotes.
65
+ const featureServices = [
66
+ ...new Set([...feature.services, ...introducedServices(deltaDoc, id)]),
67
+ ].sort(compareIds);
68
+ const service = opts.service ?? config.service;
69
+ if (!service) {
70
+ // The refusal NAMES the choices. "No service. Pass --service <id>" told
71
+ // the reader the shape of the flag and nothing about the answer, so the
72
+ // next step was always to go list the feature's specs/ by hand — and an
73
+ // agent had no way to recover at all. The list rides the JSON envelope
74
+ // for the same reason.
75
+ const message = `No service to project ${id} onto. Pass --service <id> or set 'service' in loam.json.` +
76
+ (featureServices.length === 0
77
+ ? ` ${id} carries no per-service delta yet.`
78
+ : ` ${id} touches: ${featureServices.join(", ")}.`);
79
+ if (json)
80
+ emitJsonError("invalid-option", message, { feature: id, services: featureServices });
81
+ else {
82
+ console.error(message);
83
+ // This arm refuses by hand because the envelope carries `services` as
84
+ // data, which `fail()` has no room for — so the code and its lookup
85
+ // are asked for explicitly, with the same code the branch above
86
+ // emits. Without it this was one of the two refusals that most needed
87
+ // `loam explain` and had no way to name it.
88
+ sayExplain("invalid-option");
89
+ process.exitCode = 1;
90
+ }
91
+ return;
92
+ }
93
+ // A service nobody has heard of produces a perfectly plausible EMPTY
94
+ // report — no requirements, no edges, "no architecture change" — which an
95
+ // agent consuming this as a task brief reads as "nothing to do here".
96
+ // A typo must never be indistinguishable from a finished service.
97
+ const living = await livingServices(config.docsDir);
98
+ if (!featureServices.includes(service) && !living.includes(service)) {
99
+ const near = nearestIds(service, [...new Set([...featureServices, ...living])]);
100
+ fail(json, "unknown-target", `No service '${service}': it is neither a services/${service}/ in the docs repo nor a service ${id} touches` +
101
+ (featureServices.length === 0 ? "" : ` (${featureServices.join(", ")})`) +
102
+ (near.length === 0 ? "." : ` — did you mean ${near.map((n) => `'${n}'`).join(" or ")}?`));
103
+ return;
104
+ }
105
+ // Why — business intent
106
+ const intent = existsSync(paths.intent)
107
+ ? stripFrontmatter(await readFile(paths.intent, "utf8")).trim()
108
+ : null;
109
+ // Requirement delta for this service (OpenSpec style), business and arch:
110
+ // the same projection covers both axes, in the same shape, so the payload
111
+ // stays one task — the arch requirements are the integration/ops half the
112
+ // business ones never mention.
113
+ const specPaths = featureSpecPaths(feature.dir, service);
114
+ const reqs = existsSync(specPaths.spec)
115
+ ? parseRequirements(await readFile(specPaths.spec, "utf8"))
116
+ : [];
117
+ const archReqs = existsSync(specPaths.archSpec)
118
+ ? parseRequirements(await readFile(specPaths.archSpec, "utf8"))
119
+ : [];
120
+ // The contract axis. Until now no command surfaced it at all: the feature's
121
+ // openapi.yaml was read by validate and by archive, and the one command
122
+ // whose output IS the implementation task never mentioned it — so "add the
123
+ // endpoint" was the half of the work the brief left out.
124
+ const api = await apiChanges(specPaths.openapi);
125
+ // The event axis, same reasoning: a feature's asyncapi.yaml is merged by
126
+ // archive and graded by validate, so the brief must name what it changes
127
+ // — a message the implementer was never told to publish is the same
128
+ // dropped work as an endpoint the brief left out.
129
+ const events = await eventChanges(specPaths.asyncapi);
130
+ // C4 architecture slice. The fleet union mirrors coherence's: services/
131
+ // plus the feature's own specs/ names, so the slice and the validator
132
+ // resolve a container-targeted edge to the same owner.
133
+ const fleet = new Set([...living, ...featureServices]);
134
+ const arch = archSlice(deltaDoc, service, id, fleet);
135
+ // The use-case axis, and the one section here that is a fact about the
136
+ // FLEET rather than about the feature's own files: which declared business
137
+ // flows already run through this service, and at which hop. An implementer
138
+ // handed "add the endpoint" and not told that step 4 of Checkout is the
139
+ // caller has to go find that out, and on a fleet of a hundred nobody does.
140
+ //
141
+ // The fleet set is `living ∪ featureServices`, the same union `archSlice`
142
+ // resolves with, so a service this feature INTRODUCES resolves to itself
143
+ // rather than to a container's title. And `useCaseBlastRadius` gates its
144
+ // own load: a docs repo whose architecture/ never mentions the reserved
145
+ // tag prefix costs a readdir and a few file reads here, not a LikeC4
146
+ // workspace — which is what keeps this command usable inside
147
+ // /loam-implement's inner loop.
148
+ const useCases = await useCaseBlastRadius({
149
+ docsDir: config.docsDir,
150
+ known: fleet,
151
+ services: new Set([service]),
152
+ });
153
+ // The business axis. Like the use-case section above it is a fact about
154
+ // the FEATURE rather than about this service's own files, and it is here
155
+ // for the sharper version of that section's reason: a capability delta
156
+ // NAMES NO SERVICE, so projecting the feature onto a service would drop
157
+ // it entirely — and the implementer handed "add the endpoint" would never
158
+ // learn which business promise the requirement they are about to write is
159
+ // supposed to keep. `Realizes: <capability>#<id>` is the line that says
160
+ // so, it is written on the SERVICE requirement, and the id in it is the
161
+ // one thing here that cannot be guessed.
162
+ //
163
+ // Not narrowed by `--service`, deliberately: the promise is what the
164
+ // whole feature is for, and narrowing it would report a capability-only
165
+ // feature as having nothing to say about every service in turn. One
166
+ // `existsSync` for a fleet that has not adopted the axis.
167
+ const capabilities = await capabilityDeltaSummaries((await featureCapabilityDeltas(feature.dir)).docs, async (path) => parseRequirements(await readFile(path, "utf8")));
168
+ // An unparseable delta.likec4 empties the C4 slice, and a consumer
169
+ // reading this projection as a task brief — the JSON payload and the
170
+ // printed view alike — would take that as "no architecture change": the
171
+ // vacuously-green pattern. The output stays as informative as ever (and
172
+ // `ok` stays true under --json: the command ran); the exit code is what
173
+ // stops a pipeline from building on it, so it is set BEFORE the format
174
+ // fork — the guard is about the delta, not about how it is rendered.
175
+ //
176
+ // The two contract axes fail the same way and earn the same guard: an
177
+ // openapi.yaml or asyncapi.yaml that does not parse projects as an empty
178
+ // change list. `validate --feature` does catch both these days
179
+ // (`openapi.invalid` / `asyncapi.invalid` on the feature's own files),
180
+ // but the guard stays this command's own: the brief is consumed by
181
+ // agents that never ran validate, so the exit code must carry the
182
+ // failure itself.
183
+ if (arch.errors.length > 0 || api.unreadable || events.unreadable)
184
+ process.exitCode = 1;
185
+ if (json) {
186
+ const reqJson = (r) => ({
187
+ kind: r.kind,
188
+ id: r.id,
189
+ name: r.name,
190
+ text: r.text.join("\n").trim(),
191
+ operations: r.operations,
192
+ covers: r.covers,
193
+ // Scenarios go out verbatim: they are the acceptance criteria and the
194
+ // source for the tests whoever picks this up is expected to write.
195
+ scenarios: r.scenarios.map((s) => ({ name: s.name, lines: s.lines })),
196
+ });
197
+ emitJson({
198
+ command: "delta",
199
+ feature: id,
200
+ service,
201
+ services: featureServices,
202
+ path: repoPath(config.docsDir, feature.dir),
203
+ intent,
204
+ requirements: reqs.map(reqJson),
205
+ // Same shape, separate section: an arch requirement's scenarios are
206
+ // integration/ops tests, and a consumer must not have to parse prose
207
+ // to tell the two apart.
208
+ archRequirements: archReqs.map(reqJson),
209
+ api: api.changes,
210
+ // `api` stays exactly the operations array it has always been — a
211
+ // consumer indexing it must not have to learn a new shape — so the
212
+ // readability of the document rides alongside as its own key,
213
+ // spelled the way `loam show` already spells it for a living
214
+ // contract. Additive, which the envelope permits (core/envelope/json.ts).
215
+ openapi: {
216
+ unreadable: api.unreadable,
217
+ ...(api.error === undefined ? {} : { error: api.error }),
218
+ },
219
+ // The event axis arrives after the api/openapi pair settled its
220
+ // split shape, so it is one additive key carrying both halves:
221
+ // the declarations and the document's readability.
222
+ events: {
223
+ changes: events.changes,
224
+ unreadable: events.unreadable,
225
+ ...(events.error === undefined ? {} : { error: events.error }),
226
+ },
227
+ architecture: arch,
228
+ // Additive, which the envelope permits (core/envelope/json.ts), and
229
+ // deliberately NOT wired into the exit-code guard above. The three
230
+ // conditions there are about the FEATURE's own documents; an
231
+ // `architecture/` that does not parse is a pre-existing fleet defect
232
+ // `validate` already reports as `landscape.invalid`, and making every
233
+ // `loam delta` in such a repo exit 1 would be a new gate wearing the
234
+ // clothes of a new field. `unreadable` is how this payload says it
235
+ // could not look.
236
+ useCases: {
237
+ unreadable: useCases.unreadable,
238
+ ...(useCases.error === undefined ? {} : { error: useCases.error }),
239
+ flows: useCases.flows,
240
+ },
241
+ // Additive, and an empty array rather than an absent key for the same
242
+ // reason `loam show`'s is: a consumer must not have to tell "this
243
+ // feature changes no capability" from "this loam does not report
244
+ // them". The shape is `show`'s, verbatim — the two commands are read
245
+ // side by side, and a second shape for one idea is a second thing to
246
+ // learn.
247
+ capabilities: capabilities.map((c) => ({
248
+ id: c.id,
249
+ path: repoPath(config.docsDir, c.spec),
250
+ added: c.added,
251
+ modified: c.modified,
252
+ removed: c.removed,
253
+ promises: c.promises,
254
+ })),
255
+ });
256
+ return;
257
+ }
258
+ console.log(`${id} · ${service}\n`);
259
+ if (intent) {
260
+ console.log(indent(intent, " "));
261
+ console.log();
262
+ }
263
+ if (existsSync(specPaths.spec))
264
+ printRequirements(reqs, "Requirements");
265
+ else
266
+ console.log("Requirements: (none for this service)\n");
267
+ if (existsSync(specPaths.archSpec))
268
+ printRequirements(archReqs, "Arch requirements");
269
+ if (existsSync(specPaths.openapi))
270
+ printApi(api);
271
+ if (existsSync(specPaths.asyncapi))
272
+ printEvents(events);
273
+ if (existsSync(paths.delta))
274
+ printArchSlice(arch, service);
275
+ printCapabilities(capabilities);
276
+ printUseCases(useCases, service);
277
+ });
278
+ }
279
+ //# sourceMappingURL=delta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delta.js","sourceRoot":"","sources":["../../../src/commands/delta/delta.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAClH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAoB,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACpG,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACxH,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAOpC,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,QAAQ,CAAC,aAAa,EAAE,2BAA2B,CAAC;SACpD,WAAW,CAAC,wEAAwE,CAAC;SACrF,MAAM,CAAC,gBAAgB,EAAE,8DAA8D,CAAC;SACxF,MAAM,CAAC,QAAQ,EAAE,qDAAqD,CAAC;SACvE,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,IAAkB,EAAE,EAAE;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE7B,uEAAuE;QACvE,2EAA2E;QAC3E,+DAA+D;QAC/D,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,CAAC,GAAG,YAAY,cAAc,CAAC;oBAAE,MAAM,GAAG,CAAC;gBAChD,IAAI,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC1C,OAAO;YACT,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,wEAAwE;QACxE,6CAA6C;QAC7C,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC3E,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;YACrF,OAAO;QACT,CAAC;QACD,yEAAyE;QACzE,wEAAwE;QACxE,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;QACvB,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAExC,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9E,0EAA0E;QAC1E,qEAAqE;QACrE,MAAM,eAAe,GAAG;YACtB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,GAAG,kBAAkB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;SACvE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEnB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC;QAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,wEAAwE;YACxE,wEAAwE;YACxE,wEAAwE;YACxE,uEAAuE;YACvE,uBAAuB;YACvB,MAAM,OAAO,GACX,yBAAyB,EAAE,2DAA2D;gBACtF,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC;oBAC3B,CAAC,CAAC,IAAI,EAAE,oCAAoC;oBAC5C,CAAC,CAAC,IAAI,EAAE,aAAa,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxD,IAAI,IAAI;gBAAE,aAAa,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;iBAC1F,CAAC;gBACJ,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACvB,sEAAsE;gBACtE,oEAAoE;gBACpE,gEAAgE;gBAChE,sEAAsE;gBACtE,4CAA4C;gBAC5C,UAAU,CAAC,gBAAgB,CAAC,CAAC;gBAC7B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACvB,CAAC;YACD,OAAO;QACT,CAAC;QAED,qEAAqE;QACrE,0EAA0E;QAC1E,sEAAsE;QACtE,kEAAkE;QAClE,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACpE,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,eAAe,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAChF,IAAI,CACF,IAAI,EACJ,gBAAgB,EAChB,eAAe,OAAO,+BAA+B,OAAO,oCAAoC,EAAE,UAAU;gBAC1G,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;gBACxE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAC3F,CAAC;YACF,OAAO;QACT,CAAC;QAED,wBAAwB;QACxB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;YACrC,CAAC,CAAC,gBAAgB,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE;YAC/D,CAAC,CAAC,IAAI,CAAC;QAET,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,+BAA+B;QAC/B,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC;YACrC,CAAC,CAAC,iBAAiB,CAAC,MAAM,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC3D,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC;YAC7C,CAAC,CAAC,iBAAiB,CAAC,MAAM,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC/D,CAAC,CAAC,EAAE,CAAC;QAEP,4EAA4E;QAC5E,wEAAwE;QACxE,2EAA2E;QAC3E,yDAAyD;QACzD,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAEhD,yEAAyE;QACzE,yEAAyE;QACzE,oEAAoE;QACpE,kDAAkD;QAClD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAEtD,wEAAwE;QACxE,sEAAsE;QACtE,uDAAuD;QACvD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;QAErD,uEAAuE;QACvE,2EAA2E;QAC3E,2EAA2E;QAC3E,wEAAwE;QACxE,2EAA2E;QAC3E,EAAE;QACF,0EAA0E;QAC1E,yEAAyE;QACzE,yEAAyE;QACzE,wEAAwE;QACxE,qEAAqE;QACrE,6DAA6D;QAC7D,gCAAgC;QAChC,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;YACxC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;SAC7B,CAAC,CAAC;QAEH,wEAAwE;QACxE,yEAAyE;QACzE,uEAAuE;QACvE,wEAAwE;QACxE,0EAA0E;QAC1E,0EAA0E;QAC1E,wEAAwE;QACxE,wEAAwE;QACxE,yCAAyC;QACzC,EAAE;QACF,qEAAqE;QACrE,wEAAwE;QACxE,oEAAoE;QACpE,0DAA0D;QAC1D,MAAM,YAAY,GAAG,MAAM,wBAAwB,CACjD,CAAC,MAAM,uBAAuB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EACjD,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAChE,CAAC;QAEF,mEAAmE;QACnE,qEAAqE;QACrE,wEAAwE;QACxE,wEAAwE;QACxE,wEAAwE;QACxE,uEAAuE;QACvE,qEAAqE;QACrE,EAAE;QACF,sEAAsE;QACtE,yEAAyE;QACzE,+DAA+D;QAC/D,uEAAuE;QACvE,mEAAmE;QACnE,kEAAkE;QAClE,kBAAkB;QAClB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU;YAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QAExF,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,OAAO,GAAG,CAAC,CAAc,EAA2B,EAAE,CAAC,CAAC;gBAC5D,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE;gBAC9B,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,sEAAsE;gBACtE,mEAAmE;gBACnE,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;aACtE,CAAC,CAAC;YACH,QAAQ,CAAC;gBACP,OAAO,EAAE,OAAO;gBAChB,OAAO,EAAE,EAAE;gBACX,OAAO;gBACP,QAAQ,EAAE,eAAe;gBACzB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC;gBAC3C,MAAM;gBACN,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;gBAC/B,oEAAoE;gBACpE,qEAAqE;gBACrE,yBAAyB;gBACzB,gBAAgB,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;gBACvC,GAAG,EAAE,GAAG,CAAC,OAAO;gBAChB,kEAAkE;gBAClE,mEAAmE;gBACnE,8DAA8D;gBAC9D,6DAA6D;gBAC7D,0EAA0E;gBAC1E,OAAO,EAAE;oBACP,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;iBACzD;gBACD,gEAAgE;gBAChE,+DAA+D;gBAC/D,mDAAmD;gBACnD,MAAM,EAAE;oBACN,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,UAAU,EAAE,MAAM,CAAC,UAAU;oBAC7B,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;iBAC/D;gBACD,YAAY,EAAE,IAAI;gBAClB,oEAAoE;gBACpE,mEAAmE;gBACnE,6DAA6D;gBAC7D,qEAAqE;gBACrE,sEAAsE;gBACtE,qEAAqE;gBACrE,mEAAmE;gBACnE,kBAAkB;gBAClB,QAAQ,EAAE;oBACR,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,GAAG,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;oBAClE,KAAK,EAAE,QAAQ,CAAC,KAAK;iBACtB;gBACD,sEAAsE;gBACtE,kEAAkE;gBAClE,iEAAiE;gBACjE,qEAAqE;gBACrE,qEAAqE;gBACrE,SAAS;gBACT,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACrC,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC;oBACtC,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;oBACpB,OAAO,EAAE,CAAC,CAAC,OAAO;oBAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ;iBACrB,CAAC,CAAC;aACJ,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,OAAO,IAAI,CAAC,CAAC;QACpC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;YAClC,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,CAAC;QACD,IAAI,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC;YAAE,iBAAiB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;;YACnE,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QAC5D,IAAI,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC;YAAE,iBAAiB,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;QACrF,IAAI,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC;YAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjD,IAAI,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC;YAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACxD,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3D,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAChC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import type { Command } from \"commander\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { loadConfig } from \"../../core/envelope/config.js\";\nimport { InvalidIdError, assertServiceId } from \"../../core/kernel/ids/service.js\";\nimport { emitJson, emitJsonError, fail, repoPath, reportNoConfig, sayExplain } from \"../../core/envelope/json.js\";\nimport { loadFile } from \"../../core/c4/likec4.js\";\nimport { compareIds, nearestIds } from \"../../core/repo/entries.js\";\nimport { featurePaths, featureSpecPaths } from \"../../core/repo/paths.js\";\nimport { missingFeatureMessage, resolveFeature } from \"../../core/repo/repo.js\";\nimport { parseRequirements } from \"../../core/document/parse.js\";\nimport { type Requirement } from \"../../core/document/spec.js\";\nimport { stripFrontmatter } from \"../../core/document/frontmatter.js\";\nimport { apiChanges } from \"../../core/projection/api.js\";\nimport { eventChanges } from \"../../core/projection/events.js\";\nimport { archSlice, introducedServices, livingServices } from \"../../core/projection/arch-slice.js\";\nimport { useCaseBlastRadius } from \"../../core/usecases/touch.js\";\nimport { featureCapabilityDeltas } from \"../../core/capabilities/delta/tree.js\";\nimport { capabilityDeltaSummaries } from \"../../core/capabilities/delta/summary.js\";\nimport { printApi, printArchSlice, printCapabilities, printEvents, printRequirements, printUseCases } from \"./print.js\";\nimport { indent } from \"./print.js\";\n\ninterface DeltaOptions {\n service?: string;\n json?: boolean;\n}\n\nexport function registerDelta(program: Command): void {\n program\n .command(\"delta\")\n .argument(\"<featureId>\", \"feature id, e.g. FEAT-101\")\n .description(\"Project a feature onto a service: why + requirement delta + C4 changes\")\n .option(\"--service <id>\", \"service to project onto (defaults to the configured service)\")\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .action(async (featureId: string, opts: DeltaOptions) => {\n const json = opts.json === true;\n const loaded = await loadConfig();\n if (loaded.kind !== \"loaded\") {\n reportNoConfig(json, loaded);\n return;\n }\n const config = loaded.config;\n\n // The id grammar first, and on the RAW argument: `--service ../../etc`\n // reaches `featureSpecPaths` and reads from outside the feature directory.\n // One grammar for the whole tool (core/kernel/ids/service.ts).\n if (opts.service !== undefined) {\n try {\n assertServiceId(opts.service, \"--service\");\n } catch (err) {\n if (!(err instanceof InvalidIdError)) throw err;\n fail(json, \"invalid-option\", err.message);\n return;\n }\n }\n\n // The feature is resolved BEFORE the service is chosen, because every\n // sentence about the service (\"which ones does this feature touch?\") is\n // only answerable once the feature is known.\n const feature = await resolveFeature(config.docsDir, featureId, \"exclude\");\n if (!feature) {\n fail(json, \"unknown-target\", await missingFeatureMessage(config.docsDir, featureId));\n return;\n }\n // Canonical id from here on — the delta's tags carry `#FEAT-5`, so a raw\n // `FEAT-5-slug` argument used to empty the architecture slice silently.\n const { id } = feature;\n const paths = featurePaths(feature.dir);\n\n const deltaDoc = existsSync(paths.delta) ? await loadFile(paths.delta) : null;\n // Services the feature speaks about at all: one with a requirement delta,\n // or one its C4 delta introduces. This is the list a refusal quotes.\n const featureServices = [\n ...new Set([...feature.services, ...introducedServices(deltaDoc, id)]),\n ].sort(compareIds);\n\n const service = opts.service ?? config.service;\n if (!service) {\n // The refusal NAMES the choices. \"No service. Pass --service <id>\" told\n // the reader the shape of the flag and nothing about the answer, so the\n // next step was always to go list the feature's specs/ by hand — and an\n // agent had no way to recover at all. The list rides the JSON envelope\n // for the same reason.\n const message =\n `No service to project ${id} onto. Pass --service <id> or set 'service' in loam.json.` +\n (featureServices.length === 0\n ? ` ${id} carries no per-service delta yet.`\n : ` ${id} touches: ${featureServices.join(\", \")}.`);\n if (json) emitJsonError(\"invalid-option\", message, { feature: id, services: featureServices });\n else {\n console.error(message);\n // This arm refuses by hand because the envelope carries `services` as\n // data, which `fail()` has no room for — so the code and its lookup\n // are asked for explicitly, with the same code the branch above\n // emits. Without it this was one of the two refusals that most needed\n // `loam explain` and had no way to name it.\n sayExplain(\"invalid-option\");\n process.exitCode = 1;\n }\n return;\n }\n\n // A service nobody has heard of produces a perfectly plausible EMPTY\n // report — no requirements, no edges, \"no architecture change\" — which an\n // agent consuming this as a task brief reads as \"nothing to do here\".\n // A typo must never be indistinguishable from a finished service.\n const living = await livingServices(config.docsDir);\n if (!featureServices.includes(service) && !living.includes(service)) {\n const near = nearestIds(service, [...new Set([...featureServices, ...living])]);\n fail(\n json,\n \"unknown-target\",\n `No service '${service}': it is neither a services/${service}/ in the docs repo nor a service ${id} touches` +\n (featureServices.length === 0 ? \"\" : ` (${featureServices.join(\", \")})`) +\n (near.length === 0 ? \".\" : ` — did you mean ${near.map((n) => `'${n}'`).join(\" or \")}?`),\n );\n return;\n }\n\n // Why — business intent\n const intent = existsSync(paths.intent)\n ? stripFrontmatter(await readFile(paths.intent, \"utf8\")).trim()\n : null;\n\n // Requirement delta for this service (OpenSpec style), business and arch:\n // the same projection covers both axes, in the same shape, so the payload\n // stays one task — the arch requirements are the integration/ops half the\n // business ones never mention.\n const specPaths = featureSpecPaths(feature.dir, service);\n const reqs = existsSync(specPaths.spec)\n ? parseRequirements(await readFile(specPaths.spec, \"utf8\"))\n : [];\n const archReqs = existsSync(specPaths.archSpec)\n ? parseRequirements(await readFile(specPaths.archSpec, \"utf8\"))\n : [];\n\n // The contract axis. Until now no command surfaced it at all: the feature's\n // openapi.yaml was read by validate and by archive, and the one command\n // whose output IS the implementation task never mentioned it — so \"add the\n // endpoint\" was the half of the work the brief left out.\n const api = await apiChanges(specPaths.openapi);\n\n // The event axis, same reasoning: a feature's asyncapi.yaml is merged by\n // archive and graded by validate, so the brief must name what it changes\n // — a message the implementer was never told to publish is the same\n // dropped work as an endpoint the brief left out.\n const events = await eventChanges(specPaths.asyncapi);\n\n // C4 architecture slice. The fleet union mirrors coherence's: services/\n // plus the feature's own specs/ names, so the slice and the validator\n // resolve a container-targeted edge to the same owner.\n const fleet = new Set([...living, ...featureServices]);\n const arch = archSlice(deltaDoc, service, id, fleet);\n\n // The use-case axis, and the one section here that is a fact about the\n // FLEET rather than about the feature's own files: which declared business\n // flows already run through this service, and at which hop. An implementer\n // handed \"add the endpoint\" and not told that step 4 of Checkout is the\n // caller has to go find that out, and on a fleet of a hundred nobody does.\n //\n // The fleet set is `living ∪ featureServices`, the same union `archSlice`\n // resolves with, so a service this feature INTRODUCES resolves to itself\n // rather than to a container's title. And `useCaseBlastRadius` gates its\n // own load: a docs repo whose architecture/ never mentions the reserved\n // tag prefix costs a readdir and a few file reads here, not a LikeC4\n // workspace — which is what keeps this command usable inside\n // /loam-implement's inner loop.\n const useCases = await useCaseBlastRadius({\n docsDir: config.docsDir,\n known: fleet,\n services: new Set([service]),\n });\n\n // The business axis. Like the use-case section above it is a fact about\n // the FEATURE rather than about this service's own files, and it is here\n // for the sharper version of that section's reason: a capability delta\n // NAMES NO SERVICE, so projecting the feature onto a service would drop\n // it entirely — and the implementer handed \"add the endpoint\" would never\n // learn which business promise the requirement they are about to write is\n // supposed to keep. `Realizes: <capability>#<id>` is the line that says\n // so, it is written on the SERVICE requirement, and the id in it is the\n // one thing here that cannot be guessed.\n //\n // Not narrowed by `--service`, deliberately: the promise is what the\n // whole feature is for, and narrowing it would report a capability-only\n // feature as having nothing to say about every service in turn. One\n // `existsSync` for a fleet that has not adopted the axis.\n const capabilities = await capabilityDeltaSummaries(\n (await featureCapabilityDeltas(feature.dir)).docs,\n async (path) => parseRequirements(await readFile(path, \"utf8\")),\n );\n\n // An unparseable delta.likec4 empties the C4 slice, and a consumer\n // reading this projection as a task brief — the JSON payload and the\n // printed view alike — would take that as \"no architecture change\": the\n // vacuously-green pattern. The output stays as informative as ever (and\n // `ok` stays true under --json: the command ran); the exit code is what\n // stops a pipeline from building on it, so it is set BEFORE the format\n // fork — the guard is about the delta, not about how it is rendered.\n //\n // The two contract axes fail the same way and earn the same guard: an\n // openapi.yaml or asyncapi.yaml that does not parse projects as an empty\n // change list. `validate --feature` does catch both these days\n // (`openapi.invalid` / `asyncapi.invalid` on the feature's own files),\n // but the guard stays this command's own: the brief is consumed by\n // agents that never ran validate, so the exit code must carry the\n // failure itself.\n if (arch.errors.length > 0 || api.unreadable || events.unreadable) process.exitCode = 1;\n\n if (json) {\n const reqJson = (r: Requirement): Record<string, unknown> => ({\n kind: r.kind,\n id: r.id,\n name: r.name,\n text: r.text.join(\"\\n\").trim(),\n operations: r.operations,\n covers: r.covers,\n // Scenarios go out verbatim: they are the acceptance criteria and the\n // source for the tests whoever picks this up is expected to write.\n scenarios: r.scenarios.map((s) => ({ name: s.name, lines: s.lines })),\n });\n emitJson({\n command: \"delta\",\n feature: id,\n service,\n services: featureServices,\n path: repoPath(config.docsDir, feature.dir),\n intent,\n requirements: reqs.map(reqJson),\n // Same shape, separate section: an arch requirement's scenarios are\n // integration/ops tests, and a consumer must not have to parse prose\n // to tell the two apart.\n archRequirements: archReqs.map(reqJson),\n api: api.changes,\n // `api` stays exactly the operations array it has always been — a\n // consumer indexing it must not have to learn a new shape — so the\n // readability of the document rides alongside as its own key,\n // spelled the way `loam show` already spells it for a living\n // contract. Additive, which the envelope permits (core/envelope/json.ts).\n openapi: {\n unreadable: api.unreadable,\n ...(api.error === undefined ? {} : { error: api.error }),\n },\n // The event axis arrives after the api/openapi pair settled its\n // split shape, so it is one additive key carrying both halves:\n // the declarations and the document's readability.\n events: {\n changes: events.changes,\n unreadable: events.unreadable,\n ...(events.error === undefined ? {} : { error: events.error }),\n },\n architecture: arch,\n // Additive, which the envelope permits (core/envelope/json.ts), and\n // deliberately NOT wired into the exit-code guard above. The three\n // conditions there are about the FEATURE's own documents; an\n // `architecture/` that does not parse is a pre-existing fleet defect\n // `validate` already reports as `landscape.invalid`, and making every\n // `loam delta` in such a repo exit 1 would be a new gate wearing the\n // clothes of a new field. `unreadable` is how this payload says it\n // could not look.\n useCases: {\n unreadable: useCases.unreadable,\n ...(useCases.error === undefined ? {} : { error: useCases.error }),\n flows: useCases.flows,\n },\n // Additive, and an empty array rather than an absent key for the same\n // reason `loam show`'s is: a consumer must not have to tell \"this\n // feature changes no capability\" from \"this loam does not report\n // them\". The shape is `show`'s, verbatim — the two commands are read\n // side by side, and a second shape for one idea is a second thing to\n // learn.\n capabilities: capabilities.map((c) => ({\n id: c.id,\n path: repoPath(config.docsDir, c.spec),\n added: c.added,\n modified: c.modified,\n removed: c.removed,\n promises: c.promises,\n })),\n });\n return;\n }\n\n console.log(`${id} · ${service}\\n`);\n if (intent) {\n console.log(indent(intent, \" \"));\n console.log();\n }\n if (existsSync(specPaths.spec)) printRequirements(reqs, \"Requirements\");\n else console.log(\"Requirements: (none for this service)\\n\");\n if (existsSync(specPaths.archSpec)) printRequirements(archReqs, \"Arch requirements\");\n if (existsSync(specPaths.openapi)) printApi(api);\n if (existsSync(specPaths.asyncapi)) printEvents(events);\n if (existsSync(paths.delta)) printArchSlice(arch, service);\n printCapabilities(capabilities);\n printUseCases(useCases, service);\n });\n}\n"]}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * The delta as a person reads it: requirements, contract changes, the
3
+ * architecture slice for one service, and the business promises the feature
4
+ * changes.
5
+ *
6
+ * Rendering only. Everything printed here comes from `../../core/projection/`
7
+ * or `../../core/capabilities/`, which is also what `--json` emits.
8
+ */
9
+ import {} from "../../core/document/spec.js";
10
+ import {} from "../../core/projection/api.js";
11
+ import {} from "../../core/projection/arch-slice.js";
12
+ import {} from "../../core/projection/events.js";
13
+ import {} from "../../core/usecases/touch.js";
14
+ import {} from "../../core/capabilities/delta/summary.js";
15
+ /**
16
+ * The requirement delta, in full.
17
+ *
18
+ * The text view used to print headings and scenario NAMES only, which made it a
19
+ * table of contents for a file the reader then had to open — while `--json`
20
+ * carried the requirement body and the Given/When/Then lines verbatim. The two
21
+ * are the same briefing, so they carry the same content: a person reading this
22
+ * in a terminal is being asked to implement it, exactly like the agent reading
23
+ * the payload.
24
+ */
25
+ export function printRequirements(reqs, label) {
26
+ if (reqs.length === 0) {
27
+ console.log(`${label}: (none)\n`);
28
+ return;
29
+ }
30
+ console.log(`${label}:`);
31
+ for (const r of reqs) {
32
+ const tag = r.kind === "BASE" ? "" : `[${r.kind}] `;
33
+ const n = r.scenarios.length;
34
+ console.log(` ${tag}${r.name} (${n} scenario${n === 1 ? "" : "s"})`);
35
+ // The body VERBATIM, and that is the whole of the requirement's text —
36
+ // `Operations:`, `Covers:`, `Publishes:`, `Consumes:`, `Requires:`,
37
+ // `Realizes:`, `Requirement-ID:` and `Based-On:` are body lines, kept in
38
+ // `text` on purpose so a requirement round-trips through
39
+ // `serializeRequirements` and rides inside its own digest
40
+ // (core/document/parse.ts states that rule).
41
+ //
42
+ // This used to print `Operations:` and `Covers:` AGAIN from the parsed
43
+ // fields underneath, so every requirement carrying either line showed it
44
+ // twice — and the other five directives, which have no such re-print, showed
45
+ // it once. Nothing caught it: the human view is not asserted anywhere, and
46
+ // the duplication is only visible on a requirement that has one. Found by
47
+ // running `loam delta` over loam's own self-model, which is the kind of
48
+ // pressure ROADMAP.md's self-hosting section says the axis buys.
49
+ const body = r.text.join("\n").trim();
50
+ if (body.length > 0)
51
+ console.log(indent(body, " "));
52
+ for (const s of r.scenarios) {
53
+ console.log(`\n Scenario: ${s.name}`);
54
+ // Verbatim, bullets and markdown emphasis included: these lines are the
55
+ // acceptance criteria, and paraphrasing them here would put a second
56
+ // wording of the contract in front of whoever implements it.
57
+ for (const line of s.lines)
58
+ console.log(` ${line}`);
59
+ }
60
+ console.log();
61
+ }
62
+ }
63
+ export function printApi(api) {
64
+ if (api.unreadable) {
65
+ // Worded like `loam show`'s answer for the same failure on a living
66
+ // contract, and deliberately WITHOUT a "run `loam validate`" hint: the
67
+ // parser's own message is already quoted below and the exit code carries
68
+ // the failure, so another command adds a hop, not information.
69
+ // (`validate --feature` does grade `openapi.invalid` on this same file
70
+ // these days; the fix is still in the YAML, not in its output.)
71
+ console.log("API: openapi.yaml does not parse");
72
+ if (api.error !== undefined)
73
+ console.log(` ${api.error}`);
74
+ console.log();
75
+ return;
76
+ }
77
+ if (api.changes.length === 0) {
78
+ console.log("API: (the openapi delta defines no operations)\n");
79
+ return;
80
+ }
81
+ console.log("API (this feature's openapi.yaml for the service):");
82
+ for (const op of api.changes) {
83
+ const marker = op.remove ? "REMOVE " : "";
84
+ console.log(` ${marker}${op.method} ${op.path} ${op.operationId}${op.summary === null ? "" : ` — ${op.summary}`}`);
85
+ }
86
+ console.log();
87
+ }
88
+ export function printEvents(events) {
89
+ if (events.unreadable) {
90
+ // Same wording stance as printApi above, `asyncapi.invalid` being the
91
+ // validate finding on this file.
92
+ console.log("Events: asyncapi.yaml does not parse");
93
+ if (events.error !== undefined)
94
+ console.log(` ${events.error}`);
95
+ console.log();
96
+ return;
97
+ }
98
+ if (events.changes.length === 0) {
99
+ console.log("Events: (the asyncapi delta declares no messages)\n");
100
+ return;
101
+ }
102
+ console.log("Events (this feature's asyncapi.yaml for the service):");
103
+ for (const m of events.changes) {
104
+ const marker = m.remove ? "REMOVE " : "";
105
+ const direction = m.direction === null ? "" : `${m.direction.toUpperCase()} `;
106
+ console.log(` ${marker}${direction}${m.message} (${m.slot})`);
107
+ }
108
+ console.log();
109
+ }
110
+ export function printArchSlice(arch, service) {
111
+ if (arch.errors.length > 0) {
112
+ console.log("Architecture: delta.likec4 has errors — run `loam validate`.");
113
+ return;
114
+ }
115
+ console.log("Architecture:");
116
+ if (arch.isNew)
117
+ console.log(` NEW service — create ${service}`);
118
+ if (arch.outbound.length > 0) {
119
+ console.log(" Outbound (new calls from this service):");
120
+ for (const e of arch.outbound)
121
+ console.log(` → ${e.service} "${e.title ?? ""}"`);
122
+ }
123
+ if (arch.inbound.length > 0) {
124
+ console.log(" Inbound (this service is newly called):");
125
+ for (const e of arch.inbound)
126
+ console.log(` ← ${e.service} "${e.title ?? ""}"`);
127
+ }
128
+ if (!arch.isNew && arch.outbound.length === 0 && arch.inbound.length === 0) {
129
+ console.log(" (no architecture change for this service)");
130
+ }
131
+ console.log();
132
+ }
133
+ /**
134
+ * The business flows this service already appears in.
135
+ *
136
+ * Printed even when it is empty, unlike the sections above, which are skipped
137
+ * when the feature has no such file. Those absences are facts about the FEATURE
138
+ * — no asyncapi.yaml means this change declares no events — while this one is a
139
+ * fact about the fleet, and "no use case draws this service" is the answer an
140
+ * implementer most needs to see stated rather than inferred from a missing
141
+ * heading.
142
+ *
143
+ * The unreadable arm exists so that emptiness is never ambiguous: an
144
+ * `architecture/` that does not parse produces the same empty list as a fleet
145
+ * that draws nothing, and only this line tells the two apart.
146
+ */
147
+ export function printUseCases(useCases, service) {
148
+ if (useCases.unreadable) {
149
+ console.log("Use cases: architecture/ does not parse, so the flows through this service could not be read");
150
+ if (useCases.error !== undefined)
151
+ console.log(` ${useCases.error}`);
152
+ console.log();
153
+ return;
154
+ }
155
+ if (useCases.flows.length === 0) {
156
+ console.log(`Use cases: (no declared flow draws ${service})\n`);
157
+ return;
158
+ }
159
+ console.log("Use cases (business flows this service is already a hop of):");
160
+ for (const flow of useCases.flows) {
161
+ console.log(` ${flow.title ?? flow.id} [${flow.id}] ${flow.file}`);
162
+ for (const step of flow.steps) {
163
+ const label = step.title === undefined ? "" : ` '${step.title}'`;
164
+ console.log(` step ${step.ordinal}${label}: ${step.source} -> ${step.target}`);
165
+ }
166
+ }
167
+ console.log();
168
+ }
169
+ /**
170
+ * The business promises this feature changes, and the exact `Realizes:` entry
171
+ * each one is addressed by.
172
+ *
173
+ * SILENT WHEN THERE ARE NONE, unlike the use-case section above, and the
174
+ * asymmetry is deliberate. "No declared flow draws this service" is an answer
175
+ * about the FLEET — the flows exist and none of them names you — so saying so
176
+ * is informative. A feature with no capability delta is the normal state of
177
+ * every feature in a fleet that has not adopted the business axis, and a line
178
+ * announcing that on every projection would be the noise that teaches people to
179
+ * skim the brief.
180
+ *
181
+ * The entry is printed WHOLE (`Realizes: refunds#REF-1`) rather than as a
182
+ * capability and an id a reader has to assemble: it is text somebody is about
183
+ * to paste into a requirement, and the one spelling mistake it can carry —
184
+ * the `#` — is the one nothing downstream can suggest a fix for.
185
+ */
186
+ export function printCapabilities(capabilities) {
187
+ if (capabilities.length === 0)
188
+ return;
189
+ console.log("Capabilities (business promises this feature changes):");
190
+ for (const c of capabilities) {
191
+ console.log(` ${c.id} +${c.added} ~${c.modified} -${c.removed}`);
192
+ for (const p of c.promises) {
193
+ const entry = p.id === null ? "(no Requirement-ID: yet)" : `Realizes: ${c.id}#${p.id}`;
194
+ console.log(` ${p.kind} '${p.name}' — ${entry}`);
195
+ }
196
+ }
197
+ console.log();
198
+ }
199
+ export function indent(text, pad) {
200
+ return text
201
+ .split("\n")
202
+ .map((l) => (l.length > 0 ? pad + l : l))
203
+ .join("\n");
204
+ }
205
+ //# sourceMappingURL=print.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print.js","sourceRoot":"","sources":["../../../src/commands/delta/print.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAoB,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAiB,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAkB,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAmB,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAA2B,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAA+B,MAAM,0CAA0C,CAAC;AAEvF;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAmB,EAAE,KAAa;IAClE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC;QACpD,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QACvE,uEAAuE;QACvE,oEAAoE;QACpE,yEAAyE;QACzE,yDAAyD;QACzD,0DAA0D;QAC1D,6CAA6C;QAC7C,EAAE;QACF,uEAAuE;QACvE,yEAAyE;QACzE,6EAA6E;QAC7E,2EAA2E;QAC3E,0EAA0E;QAC1E,wEAAwE;QACxE,iEAAiE;QACjE,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QACvD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACzC,wEAAwE;YACxE,qEAAqE;YACrE,6DAA6D;YAC7D,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAa;IACpC,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACnB,oEAAoE;QACpE,uEAAuE;QACvE,yEAAyE;QACzE,+DAA+D;QAC/D,uEAAuE;QACvE,gEAAgE;QAChE,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IAClE,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,CACT,KAAK,MAAM,GAAG,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,WAAW,GAAG,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CACxG,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAkB;IAC5C,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,sEAAsE;QACtE,iCAAiC;QACjC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO;IACT,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;QACnE,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;IACtE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,GAAG,SAAS,GAAG,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAe,EAAE,OAAe;IAC7D,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;QAC5E,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,IAAI,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B,OAAO,EAAE,CAAC,CAAC;IACjE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,GAAG,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,GAAG,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,QAA4B,EAAE,OAAe;IACzE,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,8FAA8F,CAAC,CAAC;QAC5G,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO;IACT,CAAC;IACD,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,sCAAsC,OAAO,KAAK,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC5E,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACtE,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,GAAG,CAAC;YACjE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAA+C;IAC/E,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACtC,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;IACtE,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACnE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;YACvF,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAY,EAAE,GAAW;IAC9C,OAAO,IAAI;SACR,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACxC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC","sourcesContent":["/**\n * The delta as a person reads it: requirements, contract changes, the\n * architecture slice for one service, and the business promises the feature\n * changes.\n *\n * Rendering only. Everything printed here comes from `../../core/projection/`\n * or `../../core/capabilities/`, which is also what `--json` emits.\n */\nimport { type Requirement } from \"../../core/document/spec.js\";\nimport { type ApiSlice } from \"../../core/projection/api.js\";\nimport { type ArchSlice } from \"../../core/projection/arch-slice.js\";\nimport { type EventSlice } from \"../../core/projection/events.js\";\nimport { type UseCaseBlastRadius } from \"../../core/usecases/touch.js\";\nimport { type CapabilityDeltaSummary } from \"../../core/capabilities/delta/summary.js\";\n\n/**\n * The requirement delta, in full.\n *\n * The text view used to print headings and scenario NAMES only, which made it a\n * table of contents for a file the reader then had to open — while `--json`\n * carried the requirement body and the Given/When/Then lines verbatim. The two\n * are the same briefing, so they carry the same content: a person reading this\n * in a terminal is being asked to implement it, exactly like the agent reading\n * the payload.\n */\nexport function printRequirements(reqs: Requirement[], label: string): void {\n if (reqs.length === 0) {\n console.log(`${label}: (none)\\n`);\n return;\n }\n console.log(`${label}:`);\n for (const r of reqs) {\n const tag = r.kind === \"BASE\" ? \"\" : `[${r.kind}] `;\n const n = r.scenarios.length;\n console.log(` ${tag}${r.name} (${n} scenario${n === 1 ? \"\" : \"s\"})`);\n // The body VERBATIM, and that is the whole of the requirement's text —\n // `Operations:`, `Covers:`, `Publishes:`, `Consumes:`, `Requires:`,\n // `Realizes:`, `Requirement-ID:` and `Based-On:` are body lines, kept in\n // `text` on purpose so a requirement round-trips through\n // `serializeRequirements` and rides inside its own digest\n // (core/document/parse.ts states that rule).\n //\n // This used to print `Operations:` and `Covers:` AGAIN from the parsed\n // fields underneath, so every requirement carrying either line showed it\n // twice — and the other five directives, which have no such re-print, showed\n // it once. Nothing caught it: the human view is not asserted anywhere, and\n // the duplication is only visible on a requirement that has one. Found by\n // running `loam delta` over loam's own self-model, which is the kind of\n // pressure ROADMAP.md's self-hosting section says the axis buys.\n const body = r.text.join(\"\\n\").trim();\n if (body.length > 0) console.log(indent(body, \" \"));\n for (const s of r.scenarios) {\n console.log(`\\n Scenario: ${s.name}`);\n // Verbatim, bullets and markdown emphasis included: these lines are the\n // acceptance criteria, and paraphrasing them here would put a second\n // wording of the contract in front of whoever implements it.\n for (const line of s.lines) console.log(` ${line}`);\n }\n console.log();\n }\n}\n\nexport function printApi(api: ApiSlice): void {\n if (api.unreadable) {\n // Worded like `loam show`'s answer for the same failure on a living\n // contract, and deliberately WITHOUT a \"run `loam validate`\" hint: the\n // parser's own message is already quoted below and the exit code carries\n // the failure, so another command adds a hop, not information.\n // (`validate --feature` does grade `openapi.invalid` on this same file\n // these days; the fix is still in the YAML, not in its output.)\n console.log(\"API: openapi.yaml does not parse\");\n if (api.error !== undefined) console.log(` ${api.error}`);\n console.log();\n return;\n }\n if (api.changes.length === 0) {\n console.log(\"API: (the openapi delta defines no operations)\\n\");\n return;\n }\n console.log(\"API (this feature's openapi.yaml for the service):\");\n for (const op of api.changes) {\n const marker = op.remove ? \"REMOVE \" : \"\";\n console.log(\n ` ${marker}${op.method} ${op.path} ${op.operationId}${op.summary === null ? \"\" : ` — ${op.summary}`}`,\n );\n }\n console.log();\n}\n\nexport function printEvents(events: EventSlice): void {\n if (events.unreadable) {\n // Same wording stance as printApi above, `asyncapi.invalid` being the\n // validate finding on this file.\n console.log(\"Events: asyncapi.yaml does not parse\");\n if (events.error !== undefined) console.log(` ${events.error}`);\n console.log();\n return;\n }\n if (events.changes.length === 0) {\n console.log(\"Events: (the asyncapi delta declares no messages)\\n\");\n return;\n }\n console.log(\"Events (this feature's asyncapi.yaml for the service):\");\n for (const m of events.changes) {\n const marker = m.remove ? \"REMOVE \" : \"\";\n const direction = m.direction === null ? \"\" : `${m.direction.toUpperCase()} `;\n console.log(` ${marker}${direction}${m.message} (${m.slot})`);\n }\n console.log();\n}\n\nexport function printArchSlice(arch: ArchSlice, service: string): void {\n if (arch.errors.length > 0) {\n console.log(\"Architecture: delta.likec4 has errors — run `loam validate`.\");\n return;\n }\n console.log(\"Architecture:\");\n if (arch.isNew) console.log(` NEW service — create ${service}`);\n if (arch.outbound.length > 0) {\n console.log(\" Outbound (new calls from this service):\");\n for (const e of arch.outbound) console.log(` → ${e.service} \"${e.title ?? \"\"}\"`);\n }\n if (arch.inbound.length > 0) {\n console.log(\" Inbound (this service is newly called):\");\n for (const e of arch.inbound) console.log(` ← ${e.service} \"${e.title ?? \"\"}\"`);\n }\n if (!arch.isNew && arch.outbound.length === 0 && arch.inbound.length === 0) {\n console.log(\" (no architecture change for this service)\");\n }\n console.log();\n}\n\n/**\n * The business flows this service already appears in.\n *\n * Printed even when it is empty, unlike the sections above, which are skipped\n * when the feature has no such file. Those absences are facts about the FEATURE\n * — no asyncapi.yaml means this change declares no events — while this one is a\n * fact about the fleet, and \"no use case draws this service\" is the answer an\n * implementer most needs to see stated rather than inferred from a missing\n * heading.\n *\n * The unreadable arm exists so that emptiness is never ambiguous: an\n * `architecture/` that does not parse produces the same empty list as a fleet\n * that draws nothing, and only this line tells the two apart.\n */\nexport function printUseCases(useCases: UseCaseBlastRadius, service: string): void {\n if (useCases.unreadable) {\n console.log(\"Use cases: architecture/ does not parse, so the flows through this service could not be read\");\n if (useCases.error !== undefined) console.log(` ${useCases.error}`);\n console.log();\n return;\n }\n if (useCases.flows.length === 0) {\n console.log(`Use cases: (no declared flow draws ${service})\\n`);\n return;\n }\n console.log(\"Use cases (business flows this service is already a hop of):\");\n for (const flow of useCases.flows) {\n console.log(` ${flow.title ?? flow.id} [${flow.id}] ${flow.file}`);\n for (const step of flow.steps) {\n const label = step.title === undefined ? \"\" : ` '${step.title}'`;\n console.log(` step ${step.ordinal}${label}: ${step.source} -> ${step.target}`);\n }\n }\n console.log();\n}\n\n/**\n * The business promises this feature changes, and the exact `Realizes:` entry\n * each one is addressed by.\n *\n * SILENT WHEN THERE ARE NONE, unlike the use-case section above, and the\n * asymmetry is deliberate. \"No declared flow draws this service\" is an answer\n * about the FLEET — the flows exist and none of them names you — so saying so\n * is informative. A feature with no capability delta is the normal state of\n * every feature in a fleet that has not adopted the business axis, and a line\n * announcing that on every projection would be the noise that teaches people to\n * skim the brief.\n *\n * The entry is printed WHOLE (`Realizes: refunds#REF-1`) rather than as a\n * capability and an id a reader has to assemble: it is text somebody is about\n * to paste into a requirement, and the one spelling mistake it can carry —\n * the `#` — is the one nothing downstream can suggest a fix for.\n */\nexport function printCapabilities(capabilities: readonly CapabilityDeltaSummary[]): void {\n if (capabilities.length === 0) return;\n console.log(\"Capabilities (business promises this feature changes):\");\n for (const c of capabilities) {\n console.log(` ${c.id} +${c.added} ~${c.modified} -${c.removed}`);\n for (const p of c.promises) {\n const entry = p.id === null ? \"(no Requirement-ID: yet)\" : `Realizes: ${c.id}#${p.id}`;\n console.log(` ${p.kind} '${p.name}' — ${entry}`);\n }\n }\n console.log();\n}\n\nexport function indent(text: string, pad: string): string {\n return text\n .split(\"\\n\")\n .map((l) => (l.length > 0 ? pad + l : l))\n .join(\"\\n\");\n}\n"]}
@@ -1,8 +1,9 @@
1
- import { loadConfig } from "../core/config.js";
2
- import { analyzeDependencies, } from "../core/dependencies.js";
1
+ import { loadConfig } from "../core/envelope/config.js";
2
+ import { analyzeDependencies } from "../core/dependencies/dependencies.js";
3
+ import {} from "../core/dependencies/facts.js";
3
4
  import { FleetContext } from "../core/fleet-context.js";
4
- import { emitJson, fail, reportNoConfig } from "../core/json.js";
5
- import { missingFeatureMessage, resolveFeature } from "../core/repo.js";
5
+ import { emitJson, fail, reportNoConfig } from "../core/envelope/json.js";
6
+ import { missingFeatureMessage, resolveFeature } from "../core/repo/repo.js";
6
7
  export function registerDependencies(program) {
7
8
  program
8
9
  .command("dependencies")
@@ -11,11 +12,12 @@ export function registerDependencies(program) {
11
12
  .option("--json", "emit the machine contract instead of the human view")
12
13
  .action(async (featureArg, opts) => {
13
14
  const json = opts.json === true;
14
- const config = await loadConfig();
15
- if (!config) {
16
- reportNoConfig(json);
15
+ const loaded = await loadConfig();
16
+ if (loaded.kind !== "loaded") {
17
+ reportNoConfig(json, loaded);
17
18
  return;
18
19
  }
20
+ const config = loaded.config;
19
21
  const context = new FleetContext();
20
22
  const feature = featureArg === undefined
21
23
  ? null