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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1256) hide show
  1. package/CHANGELOG.md +5992 -82
  2. package/COMPARISON.md +168 -63
  3. package/CONTRIBUTING.md +121 -0
  4. package/MIGRATING-from-OpenSpec.md +238 -55
  5. package/QUICKSTART.md +302 -0
  6. package/README.md +653 -144
  7. package/ROADMAP.md +1035 -0
  8. package/SCHEMA.md +3916 -263
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +927 -0
  11. package/dist/cli.js +133 -21
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +204 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +309 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +74 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/closing.js +42 -0
  20. package/dist/commands/archive/closing.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
  22. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  23. package/dist/commands/archive/plan/contracts/consumers.js +56 -0
  24. package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
  25. package/dist/commands/archive/plan/contracts/openapi.js +193 -0
  26. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  27. package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
  28. package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
  29. package/dist/commands/archive/plan/document/head.js +151 -0
  30. package/dist/commands/archive/plan/document/head.js.map +1 -0
  31. package/dist/commands/archive/plan/document/links.js +284 -0
  32. package/dist/commands/archive/plan/document/links.js.map +1 -0
  33. package/dist/commands/archive/plan/document/run.js +136 -0
  34. package/dist/commands/archive/plan/document/run.js.map +1 -0
  35. package/dist/commands/archive/plan/gate.js +319 -0
  36. package/dist/commands/archive/plan/gate.js.map +1 -0
  37. package/dist/commands/archive/plan/landscape.js +298 -0
  38. package/dist/commands/archive/plan/landscape.js.map +1 -0
  39. package/dist/commands/archive/plan/model/extending.js +85 -0
  40. package/dist/commands/archive/plan/model/extending.js.map +1 -0
  41. package/dist/commands/archive/plan/refusal.js +106 -0
  42. package/dist/commands/archive/plan/refusal.js.map +1 -0
  43. package/dist/commands/archive/plan/specs.js +318 -0
  44. package/dist/commands/archive/plan/specs.js.map +1 -0
  45. package/dist/commands/archive/plan/state.js +30 -0
  46. package/dist/commands/archive/plan/state.js.map +1 -0
  47. package/dist/commands/archive/run.js +355 -0
  48. package/dist/commands/archive/run.js.map +1 -0
  49. package/dist/commands/archive/shipped.js +49 -0
  50. package/dist/commands/archive/shipped.js.map +1 -0
  51. package/dist/commands/context/context.js +166 -0
  52. package/dist/commands/context/context.js.map +1 -0
  53. package/dist/commands/context/print.js +305 -0
  54. package/dist/commands/context/print.js.map +1 -0
  55. package/dist/commands/delta/delta.js +367 -0
  56. package/dist/commands/delta/delta.js.map +1 -0
  57. package/dist/commands/delta/print.js +221 -0
  58. package/dist/commands/delta/print.js.map +1 -0
  59. package/dist/commands/dependencies.js +6 -8
  60. package/dist/commands/dependencies.js.map +1 -1
  61. package/dist/commands/diff/diff.js +86 -0
  62. package/dist/commands/diff/diff.js.map +1 -0
  63. package/dist/commands/diff/print.js +38 -0
  64. package/dist/commands/diff/print.js.map +1 -0
  65. package/dist/commands/doctor.js +65 -5
  66. package/dist/commands/doctor.js.map +1 -1
  67. package/dist/commands/explain/explain.js +227 -0
  68. package/dist/commands/explain/explain.js.map +1 -0
  69. package/dist/commands/explore.js +39 -28
  70. package/dist/commands/explore.js.map +1 -1
  71. package/dist/commands/gate/gate.js +152 -0
  72. package/dist/commands/gate/gate.js.map +1 -0
  73. package/dist/commands/gate/print.js +66 -0
  74. package/dist/commands/gate/print.js.map +1 -0
  75. package/dist/commands/gherkin/commit.js +105 -0
  76. package/dist/commands/gherkin/commit.js.map +1 -0
  77. package/dist/commands/gherkin/gherkin.js +262 -0
  78. package/dist/commands/gherkin/gherkin.js.map +1 -0
  79. package/dist/commands/gherkin/reconcile.js +146 -0
  80. package/dist/commands/gherkin/reconcile.js.map +1 -0
  81. package/dist/commands/gherkin/render.js +77 -0
  82. package/dist/commands/gherkin/render.js.map +1 -0
  83. package/dist/commands/init/example.js +204 -0
  84. package/dist/commands/init/example.js.map +1 -0
  85. package/dist/commands/init/first-hour.js +72 -0
  86. package/dist/commands/init/first-hour.js.map +1 -0
  87. package/dist/commands/{init.js → init/init.js} +142 -71
  88. package/dist/commands/init/init.js.map +1 -0
  89. package/dist/commands/init/mcp.js +131 -0
  90. package/dist/commands/init/mcp.js.map +1 -0
  91. package/dist/commands/init/options.js +78 -0
  92. package/dist/commands/init/options.js.map +1 -0
  93. package/dist/commands/instructions.js +72 -14
  94. package/dist/commands/instructions.js.map +1 -1
  95. package/dist/commands/list/campaign/campaign.js +63 -0
  96. package/dist/commands/list/campaign/campaign.js.map +1 -0
  97. package/dist/commands/list/campaign/owners.js +65 -0
  98. package/dist/commands/list/campaign/owners.js.map +1 -0
  99. package/dist/commands/list/json.js +155 -0
  100. package/dist/commands/list/json.js.map +1 -0
  101. package/dist/commands/list/list.js +358 -0
  102. package/dist/commands/list/list.js.map +1 -0
  103. package/dist/commands/list/print.js +344 -0
  104. package/dist/commands/list/print.js.map +1 -0
  105. package/dist/commands/list/review.js +120 -0
  106. package/dist/commands/list/review.js.map +1 -0
  107. package/dist/commands/list/suites/suites.js +140 -0
  108. package/dist/commands/list/suites/suites.js.map +1 -0
  109. package/dist/commands/list/views.js +108 -0
  110. package/dist/commands/list/views.js.map +1 -0
  111. package/dist/commands/mcp/dispatch.js +238 -0
  112. package/dist/commands/mcp/dispatch.js.map +1 -0
  113. package/dist/commands/mcp/mcp.js +75 -0
  114. package/dist/commands/mcp/mcp.js.map +1 -0
  115. package/dist/commands/mcp/serve.js +55 -0
  116. package/dist/commands/mcp/serve.js.map +1 -0
  117. package/dist/commands/migrate-openspec/materialize/active.js +175 -0
  118. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  119. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  120. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  121. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  122. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  123. package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
  124. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  125. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  126. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  127. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  128. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  129. package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
  130. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  131. package/dist/commands/migrate-openspec/openspec/error.js +18 -0
  132. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  133. package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
  134. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  135. package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
  136. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  137. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  138. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  139. package/dist/commands/migrate-openspec/print.js +89 -0
  140. package/dist/commands/migrate-openspec/print.js.map +1 -0
  141. package/dist/commands/new/capability-template.js +118 -0
  142. package/dist/commands/new/capability-template.js.map +1 -0
  143. package/dist/commands/new/commit.js +62 -0
  144. package/dist/commands/new/commit.js.map +1 -0
  145. package/dist/commands/new/modifies.js +206 -0
  146. package/dist/commands/new/modifies.js.map +1 -0
  147. package/dist/commands/new/new.js +328 -0
  148. package/dist/commands/new/new.js.map +1 -0
  149. package/dist/commands/new/templates.js +279 -0
  150. package/dist/commands/new/templates.js.map +1 -0
  151. package/dist/commands/open.js +199 -0
  152. package/dist/commands/open.js.map +1 -0
  153. package/dist/commands/policy/format.js +152 -0
  154. package/dist/commands/policy/format.js.map +1 -0
  155. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
  156. package/dist/commands/policy/gate.js.map +1 -0
  157. package/dist/commands/rebase/edit.js +106 -0
  158. package/dist/commands/rebase/edit.js.map +1 -0
  159. package/dist/commands/rebase/living.js +185 -0
  160. package/dist/commands/rebase/living.js.map +1 -0
  161. package/dist/commands/rebase/plan.js +245 -0
  162. package/dist/commands/rebase/plan.js.map +1 -0
  163. package/dist/commands/rebase/rebase.js +300 -0
  164. package/dist/commands/rebase/rebase.js.map +1 -0
  165. package/dist/commands/seed/commit.js +221 -0
  166. package/dist/commands/seed/commit.js.map +1 -0
  167. package/dist/commands/seed/plan.js +278 -0
  168. package/dist/commands/seed/plan.js.map +1 -0
  169. package/dist/commands/seed/seed.js +174 -0
  170. package/dist/commands/seed/seed.js.map +1 -0
  171. package/dist/commands/show/feature.js +182 -0
  172. package/dist/commands/show/feature.js.map +1 -0
  173. package/dist/commands/show/introduced.js +157 -0
  174. package/dist/commands/show/introduced.js.map +1 -0
  175. package/dist/commands/show/marks.js +53 -0
  176. package/dist/commands/show/marks.js.map +1 -0
  177. package/dist/commands/show/service.js +239 -0
  178. package/dist/commands/show/service.js.map +1 -0
  179. package/dist/commands/show/show.js +87 -0
  180. package/dist/commands/show/show.js.map +1 -0
  181. package/dist/commands/status/fleet-next.js +90 -0
  182. package/dist/commands/status/fleet-next.js.map +1 -0
  183. package/dist/commands/status/json.js +47 -0
  184. package/dist/commands/status/json.js.map +1 -0
  185. package/dist/commands/status/print.js +209 -0
  186. package/dist/commands/status/print.js.map +1 -0
  187. package/dist/commands/status/status.js +115 -0
  188. package/dist/commands/status/status.js.map +1 -0
  189. package/dist/commands/steps/steps.js +269 -0
  190. package/dist/commands/steps/steps.js.map +1 -0
  191. package/dist/commands/subsystem/edit.js +192 -0
  192. package/dist/commands/subsystem/edit.js.map +1 -0
  193. package/dist/commands/subsystem/move.js +325 -0
  194. package/dist/commands/subsystem/move.js.map +1 -0
  195. package/dist/commands/subsystem/query.js +113 -0
  196. package/dist/commands/subsystem/query.js.map +1 -0
  197. package/dist/commands/subsystem/subsystem.js +98 -0
  198. package/dist/commands/subsystem/subsystem.js.map +1 -0
  199. package/dist/commands/subsystem/sync.js +318 -0
  200. package/dist/commands/subsystem/sync.js.map +1 -0
  201. package/dist/commands/subsystem/txn/exclude.js +132 -0
  202. package/dist/commands/subsystem/txn/exclude.js.map +1 -0
  203. package/dist/commands/subsystem/txn/links.js +128 -0
  204. package/dist/commands/subsystem/txn/links.js.map +1 -0
  205. package/dist/commands/subsystem/txn/report.js +174 -0
  206. package/dist/commands/subsystem/txn/report.js.map +1 -0
  207. package/dist/commands/subsystem/txn/txn.js +196 -0
  208. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  209. package/dist/commands/subsystem/txn/views.js +249 -0
  210. package/dist/commands/subsystem/txn/views.js.map +1 -0
  211. package/dist/commands/tasks/actions.js +107 -0
  212. package/dist/commands/tasks/actions.js.map +1 -0
  213. package/dist/commands/tasks/render.js +253 -0
  214. package/dist/commands/tasks/render.js.map +1 -0
  215. package/dist/commands/tasks/tasks.js +119 -0
  216. package/dist/commands/tasks/tasks.js.map +1 -0
  217. package/dist/commands/unarchive/manifest.js +176 -0
  218. package/dist/commands/unarchive/manifest.js.map +1 -0
  219. package/dist/commands/unarchive/restore.js +254 -0
  220. package/dist/commands/unarchive/restore.js.map +1 -0
  221. package/dist/commands/unarchive/unarchive.js +59 -0
  222. package/dist/commands/unarchive/unarchive.js.map +1 -0
  223. package/dist/commands/validate/arch-coverage.js +245 -0
  224. package/dist/commands/validate/arch-coverage.js.map +1 -0
  225. package/dist/commands/validate/checks/fleet-shape.js +204 -0
  226. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  227. package/dist/commands/validate/checks/health-deps.js +58 -0
  228. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  229. package/dist/commands/validate/checks/introduced.js +102 -0
  230. package/dist/commands/validate/checks/introduced.js.map +1 -0
  231. package/dist/commands/validate/checks/requirements.js +264 -0
  232. package/dist/commands/validate/checks/requirements.js.map +1 -0
  233. package/dist/commands/validate/checks/sources.js +85 -0
  234. package/dist/commands/validate/checks/sources.js.map +1 -0
  235. package/dist/commands/validate/coverage/covers-after.js +105 -0
  236. package/dist/commands/validate/coverage/covers-after.js.map +1 -0
  237. package/dist/commands/validate/feature.js +222 -0
  238. package/dist/commands/validate/feature.js.map +1 -0
  239. package/dist/commands/validate/fleet/census.js +93 -0
  240. package/dist/commands/validate/fleet/census.js.map +1 -0
  241. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  242. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  243. package/dist/commands/validate/fleet/landscape.js +371 -0
  244. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  245. package/dist/commands/validate/fleet/load.js +118 -0
  246. package/dist/commands/validate/fleet/load.js.map +1 -0
  247. package/dist/commands/validate/fleet/map/attest.js +98 -0
  248. package/dist/commands/validate/fleet/map/attest.js.map +1 -0
  249. package/dist/commands/validate/fleet/map/bindings.js +107 -0
  250. package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
  251. package/dist/commands/validate/fleet/map/consumers.js +244 -0
  252. package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
  253. package/dist/commands/validate/fleet/map/isolation.js +116 -0
  254. package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
  255. package/dist/commands/validate/fleet/map/usecases.js +54 -0
  256. package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
  257. package/dist/commands/validate/fleet/obligations.js +266 -0
  258. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  259. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  260. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  261. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  262. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  263. package/dist/commands/validate/fleet/scorecard/print.js +71 -0
  264. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  265. package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
  266. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  267. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  268. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  269. package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
  270. package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
  271. package/dist/commands/validate/fleet/views/ids.js +75 -0
  272. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  273. package/dist/commands/validate/fleet/views/projects.js +278 -0
  274. package/dist/commands/validate/fleet/views/projects.js.map +1 -0
  275. package/dist/commands/validate/fleet/views/root-documents.js +83 -0
  276. package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
  277. package/dist/commands/validate/fleet/views/stale.js +52 -0
  278. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  279. package/dist/commands/validate/links/corpus.js +89 -0
  280. package/dist/commands/validate/links/corpus.js.map +1 -0
  281. package/dist/commands/validate/links/glossary.js +75 -0
  282. package/dist/commands/validate/links/glossary.js.map +1 -0
  283. package/dist/commands/validate/render/repeats.js +63 -0
  284. package/dist/commands/validate/render/repeats.js.map +1 -0
  285. package/dist/commands/validate/render/rollups.js +115 -0
  286. package/dist/commands/validate/render/rollups.js.map +1 -0
  287. package/dist/commands/validate/render/text.js +199 -0
  288. package/dist/commands/validate/render/text.js.map +1 -0
  289. package/dist/commands/validate/report.js +145 -0
  290. package/dist/commands/validate/report.js.map +1 -0
  291. package/dist/commands/validate/scope.js +113 -0
  292. package/dist/commands/validate/scope.js.map +1 -0
  293. package/dist/commands/validate/service/api.js +252 -0
  294. package/dist/commands/validate/service/api.js.map +1 -0
  295. package/dist/commands/validate/service/contracts/generated.js +134 -0
  296. package/dist/commands/validate/service/contracts/generated.js.map +1 -0
  297. package/dist/commands/validate/service/events/events.js +241 -0
  298. package/dist/commands/validate/service/events/events.js.map +1 -0
  299. package/dist/commands/validate/service/events/message-producers.js +77 -0
  300. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  301. package/dist/commands/validate/service/evidence-pins.js +177 -0
  302. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  303. package/dist/commands/validate/service/model/diverged.js +226 -0
  304. package/dist/commands/validate/service/model/diverged.js.map +1 -0
  305. package/dist/commands/validate/service/model/grade.js +163 -0
  306. package/dist/commands/validate/service/model/grade.js.map +1 -0
  307. package/dist/commands/validate/service/service.js +310 -0
  308. package/dist/commands/validate/service/service.js.map +1 -0
  309. package/dist/commands/validate/service/specs.js +279 -0
  310. package/dist/commands/validate/service/specs.js.map +1 -0
  311. package/dist/commands/validate/service/spine.js +148 -0
  312. package/dist/commands/validate/service/spine.js.map +1 -0
  313. package/dist/commands/validate/service/usecases/tags.js +113 -0
  314. package/dist/commands/validate/service/usecases/tags.js.map +1 -0
  315. package/dist/commands/validate/service/usecases/usecases.js +209 -0
  316. package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
  317. package/dist/commands/validate/validate.js +363 -0
  318. package/dist/commands/validate/validate.js.map +1 -0
  319. package/dist/commands/verify/cross/diff.js +178 -0
  320. package/dist/commands/verify/cross/diff.js.map +1 -0
  321. package/dist/commands/verify/evidence/contract.js +32 -0
  322. package/dist/commands/verify/evidence/contract.js.map +1 -0
  323. package/dist/commands/verify/evidence/pins.js +52 -0
  324. package/dist/commands/verify/evidence/pins.js.map +1 -0
  325. package/dist/commands/verify/evidence/read.js +81 -0
  326. package/dist/commands/verify/evidence/read.js.map +1 -0
  327. package/dist/commands/verify/frozen.js +263 -0
  328. package/dist/commands/verify/frozen.js.map +1 -0
  329. package/dist/commands/verify/record.js +278 -0
  330. package/dist/commands/verify/record.js.map +1 -0
  331. package/dist/commands/verify/report.js +206 -0
  332. package/dist/commands/verify/report.js.map +1 -0
  333. package/dist/commands/verify/results.js +328 -0
  334. package/dist/commands/verify/results.js.map +1 -0
  335. package/dist/commands/verify/verify.js +220 -0
  336. package/dist/commands/verify/verify.js.map +1 -0
  337. package/dist/commands/vouch/contract.js +11 -0
  338. package/dist/commands/vouch/contract.js.map +1 -0
  339. package/dist/commands/vouch/pack/contract.js +2 -0
  340. package/dist/commands/vouch/pack/contract.js.map +1 -0
  341. package/dist/commands/vouch/pack/pack.js +266 -0
  342. package/dist/commands/vouch/pack/pack.js.map +1 -0
  343. package/dist/commands/vouch/pack/print.js +266 -0
  344. package/dist/commands/vouch/pack/print.js.map +1 -0
  345. package/dist/commands/vouch/pack/sections.js +141 -0
  346. package/dist/commands/vouch/pack/sections.js.map +1 -0
  347. package/dist/commands/vouch/prompt/confirm.js +46 -0
  348. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  349. package/dist/commands/vouch/report.js +101 -0
  350. package/dist/commands/vouch/report.js.map +1 -0
  351. package/dist/commands/vouch/run.js +230 -0
  352. package/dist/commands/vouch/run.js.map +1 -0
  353. package/dist/commands/vouch/sample/plan.js +111 -0
  354. package/dist/commands/vouch/sample/plan.js.map +1 -0
  355. package/dist/commands/vouch/sample/print.js +109 -0
  356. package/dist/commands/vouch/sample/print.js.map +1 -0
  357. package/dist/commands/vouch/vet/verify.js +155 -0
  358. package/dist/commands/vouch/vet/verify.js.map +1 -0
  359. package/dist/commands/vouch/vouch.js +169 -0
  360. package/dist/commands/vouch/vouch.js.map +1 -0
  361. package/dist/core/agent/agents-md/command-map.js +299 -0
  362. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  363. package/dist/core/agent/agents-md/map/explain.js +46 -0
  364. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  365. package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
  366. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  367. package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
  368. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  369. package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
  370. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  371. package/dist/core/agent/agents-md/map/mcp.js +44 -0
  372. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  373. package/dist/core/agent/agents-md/map/status.js +78 -0
  374. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  375. package/dist/core/agent/agents-md/map/subsystem.js +104 -0
  376. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  377. package/dist/core/agent/agents-md/map/usecases.js +138 -0
  378. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  379. package/dist/core/agent/agents-md/refusals.js +273 -0
  380. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  381. package/dist/core/agent/agents-md.js +203 -0
  382. package/dist/core/agent/agents-md.js.map +1 -0
  383. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
  384. package/dist/core/agent/agents-stamp.js.map +1 -0
  385. package/dist/core/agent/contract.js +2 -0
  386. package/dist/core/agent/contract.js.map +1 -0
  387. package/dist/core/agent/protocol.js +193 -0
  388. package/dist/core/agent/protocol.js.map +1 -0
  389. package/dist/core/agent/scaffold.js +254 -0
  390. package/dist/core/agent/scaffold.js.map +1 -0
  391. package/dist/core/agent/support/report.js +144 -0
  392. package/dist/core/agent/support/report.js.map +1 -0
  393. package/dist/core/agent/tools/dialects.js +151 -0
  394. package/dist/core/agent/tools/dialects.js.map +1 -0
  395. package/dist/core/agent/tools/registry.js +193 -0
  396. package/dist/core/agent/tools/registry.js.map +1 -0
  397. package/dist/core/agent/workflows/adopt.js +280 -0
  398. package/dist/core/agent/workflows/adopt.js.map +1 -0
  399. package/dist/core/agent/workflows/check.js +373 -0
  400. package/dist/core/agent/workflows/check.js.map +1 -0
  401. package/dist/core/agent/workflows/closing.js +323 -0
  402. package/dist/core/agent/workflows/closing.js.map +1 -0
  403. package/dist/core/agent/workflows/feature.js +220 -0
  404. package/dist/core/agent/workflows/feature.js.map +1 -0
  405. package/dist/core/agent/workflows/implement.js +188 -0
  406. package/dist/core/agent/workflows/implement.js.map +1 -0
  407. package/dist/core/agent/workflows/reference/authoring.js +311 -0
  408. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  409. package/dist/core/agent/workflows/reference/codes.js +67 -0
  410. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  411. package/dist/core/agent/workflows/reference/done-check.js +210 -0
  412. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  413. package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
  414. package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
  415. package/dist/core/agent/workflows/reference/reference.js +19 -0
  416. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  417. package/dist/core/agent/workflows/reference/spine.js +338 -0
  418. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  419. package/dist/core/asyncapi/baseline/plan.js +43 -0
  420. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  421. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  422. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  423. package/dist/core/asyncapi/depth.js +164 -0
  424. package/dist/core/asyncapi/depth.js.map +1 -0
  425. package/dist/core/asyncapi/digest.js +146 -0
  426. package/dist/core/asyncapi/digest.js.map +1 -0
  427. package/dist/core/asyncapi/merge/components.js +92 -0
  428. package/dist/core/asyncapi/merge/components.js.map +1 -0
  429. package/dist/core/asyncapi/merge/error.js +38 -0
  430. package/dist/core/asyncapi/merge/error.js.map +1 -0
  431. package/dist/core/asyncapi/merge/markers.js +290 -0
  432. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  433. package/dist/core/asyncapi/merge/merge.js +195 -0
  434. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  435. package/dist/core/asyncapi/merge/pin.js +83 -0
  436. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  437. package/dist/core/asyncapi/model.js +11 -0
  438. package/dist/core/asyncapi/model.js.map +1 -0
  439. package/dist/core/asyncapi/producers.js +50 -0
  440. package/dist/core/asyncapi/producers.js.map +1 -0
  441. package/dist/core/asyncapi/read.js +263 -0
  442. package/dist/core/asyncapi/read.js.map +1 -0
  443. package/dist/core/brief/brief.js +285 -0
  444. package/dist/core/brief/brief.js.map +1 -0
  445. package/dist/core/brief/checks.js +385 -0
  446. package/dist/core/brief/checks.js.map +1 -0
  447. package/dist/core/brief/landscape.js +273 -0
  448. package/dist/core/brief/landscape.js.map +1 -0
  449. package/dist/core/brief/map/extend.js +84 -0
  450. package/dist/core/brief/map/extend.js.map +1 -0
  451. package/dist/core/brief/map/owed.js +266 -0
  452. package/dist/core/brief/map/owed.js.map +1 -0
  453. package/dist/core/brief/targets.js +304 -0
  454. package/dist/core/brief/targets.js.map +1 -0
  455. package/dist/core/brief/unchecked.js +58 -0
  456. package/dist/core/brief/unchecked.js.map +1 -0
  457. package/dist/core/c4/arch.js +190 -0
  458. package/dist/core/c4/arch.js.map +1 -0
  459. package/dist/core/c4/direction/direction.js +114 -0
  460. package/dist/core/c4/direction/direction.js.map +1 -0
  461. package/dist/core/c4/likec4.js +243 -0
  462. package/dist/core/c4/likec4.js.map +1 -0
  463. package/dist/core/c4/locate/unlocated.js +150 -0
  464. package/dist/core/c4/locate/unlocated.js.map +1 -0
  465. package/dist/core/c4/parsed/deployment.js +160 -0
  466. package/dist/core/c4/parsed/deployment.js.map +1 -0
  467. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  468. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  469. package/dist/core/c4/parsed/specification.js +78 -0
  470. package/dist/core/c4/parsed/specification.js.map +1 -0
  471. package/dist/core/c4/parsed/values.js +110 -0
  472. package/dist/core/c4/parsed/values.js.map +1 -0
  473. package/dist/core/c4/parsed/view-ids.js +113 -0
  474. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  475. package/dist/core/c4/prefetch/fleet.js +134 -0
  476. package/dist/core/c4/prefetch/fleet.js.map +1 -0
  477. package/dist/core/c4/project/architecture.js +161 -0
  478. package/dist/core/c4/project/architecture.js.map +1 -0
  479. package/dist/core/c4/project/batch.js +140 -0
  480. package/dist/core/c4/project/batch.js.map +1 -0
  481. package/dist/core/c4/project/documents.js +89 -0
  482. package/dist/core/c4/project/documents.js.map +1 -0
  483. package/dist/core/c4/project/load.js +219 -0
  484. package/dist/core/c4/project/load.js.map +1 -0
  485. package/dist/core/c4/project/staged.js +277 -0
  486. package/dist/core/c4/project/staged.js.map +1 -0
  487. package/dist/core/c4/resolve/attested.js +0 -0
  488. package/dist/core/c4/resolve/attested.js.map +1 -0
  489. package/dist/core/c4/resolve/external.js +51 -0
  490. package/dist/core/c4/resolve/external.js.map +1 -0
  491. package/dist/core/c4/resolve/service.js +174 -0
  492. package/dist/core/c4/resolve/service.js.map +1 -0
  493. package/dist/core/c4/resolve/steps.js +290 -0
  494. package/dist/core/c4/resolve/steps.js.map +1 -0
  495. package/dist/core/c4/resolve/systems.js +154 -0
  496. package/dist/core/c4/resolve/systems.js.map +1 -0
  497. package/dist/core/c4/root-project/exclude.js +352 -0
  498. package/dist/core/c4/root-project/exclude.js.map +1 -0
  499. package/dist/core/c4/seed/fleet-file.js +201 -0
  500. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  501. package/dist/core/c4/seed/items.js +91 -0
  502. package/dist/core/c4/seed/items.js.map +1 -0
  503. package/dist/core/c4/seed/stamp.js +48 -0
  504. package/dist/core/c4/seed/stamp.js.map +1 -0
  505. package/dist/core/c4/seed/template.js +173 -0
  506. package/dist/core/c4/seed/template.js.map +1 -0
  507. package/dist/core/c4/service-model/created/models.js +96 -0
  508. package/dist/core/c4/service-model/created/models.js.map +1 -0
  509. package/dist/core/c4/service-model/documents.js +47 -0
  510. package/dist/core/c4/service-model/documents.js.map +1 -0
  511. package/dist/core/c4/service-model/fleet/extending.js +82 -0
  512. package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
  513. package/dist/core/c4/service-model/load.js +165 -0
  514. package/dist/core/c4/service-model/load.js.map +1 -0
  515. package/dist/core/c4/service-model/renderer.js +128 -0
  516. package/dist/core/c4/service-model/renderer.js.map +1 -0
  517. package/dist/core/c4/service-model/shape.js +106 -0
  518. package/dist/core/c4/service-model/shape.js.map +1 -0
  519. package/dist/core/c4/service-model/slice.js +188 -0
  520. package/dist/core/c4/service-model/slice.js.map +1 -0
  521. package/dist/core/c4/source-mask.js +369 -0
  522. package/dist/core/c4/source-mask.js.map +1 -0
  523. package/dist/core/c4/source-scan.js +308 -0
  524. package/dist/core/c4/source-scan.js.map +1 -0
  525. package/dist/core/c4/splice/authored-source.js +167 -0
  526. package/dist/core/c4/splice/authored-source.js.map +1 -0
  527. package/dist/core/c4/splice/contract.js +30 -0
  528. package/dist/core/c4/splice/contract.js.map +1 -0
  529. package/dist/core/c4/splice/delta-blocks.js +126 -0
  530. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  531. package/dist/core/c4/splice/identity/declared.js +87 -0
  532. package/dist/core/c4/splice/identity/declared.js.map +1 -0
  533. package/dist/core/c4/splice/identity/edges.js +73 -0
  534. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  535. package/dist/core/c4/splice/identity/existing.js +80 -0
  536. package/dist/core/c4/splice/identity/existing.js.map +1 -0
  537. package/dist/core/c4/splice/identity/interior.js +80 -0
  538. package/dist/core/c4/splice/identity/interior.js.map +1 -0
  539. package/dist/core/c4/splice/identity/owner.js +50 -0
  540. package/dist/core/c4/splice/identity/owner.js.map +1 -0
  541. package/dist/core/c4/splice/landscape-merge.js +337 -0
  542. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  543. package/dist/core/c4/splice/model/merge.js +151 -0
  544. package/dist/core/c4/splice/model/merge.js.map +1 -0
  545. package/dist/core/c4/splice/placement.js +298 -0
  546. package/dist/core/c4/splice/placement.js.map +1 -0
  547. package/dist/core/c4/splice/text/spot.js +131 -0
  548. package/dist/core/c4/splice/text/spot.js.map +1 -0
  549. package/dist/core/c4/workspace.js +166 -0
  550. package/dist/core/c4/workspace.js.map +1 -0
  551. package/dist/core/capabilities/authoring/notes.js +141 -0
  552. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  553. package/dist/core/capabilities/capabilities.js +124 -0
  554. package/dist/core/capabilities/capabilities.js.map +1 -0
  555. package/dist/core/capabilities/delta/doc.js +47 -0
  556. package/dist/core/capabilities/delta/doc.js.map +1 -0
  557. package/dist/core/capabilities/delta/overlay.js +129 -0
  558. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  559. package/dist/core/capabilities/delta/summary.js +57 -0
  560. package/dist/core/capabilities/delta/summary.js.map +1 -0
  561. package/dist/core/capabilities/delta/tree.js +43 -0
  562. package/dist/core/capabilities/delta/tree.js.map +1 -0
  563. package/dist/core/capabilities/delta/uncovered.js +222 -0
  564. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  565. package/dist/core/capabilities/findings.js +338 -0
  566. package/dist/core/capabilities/findings.js.map +1 -0
  567. package/dist/core/capabilities/realizes/findings.js +174 -0
  568. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  569. package/dist/core/capabilities/realizes/join.js +123 -0
  570. package/dist/core/capabilities/realizes/join.js.map +1 -0
  571. package/dist/core/capabilities/rollup.js +205 -0
  572. package/dist/core/capabilities/rollup.js.map +1 -0
  573. package/dist/core/capabilities/tree.js +104 -0
  574. package/dist/core/capabilities/tree.js.map +1 -0
  575. package/dist/core/capabilities/usecase-join.js +267 -0
  576. package/dist/core/capabilities/usecase-join.js.map +1 -0
  577. package/dist/core/coherence/authoring/scaffold.js +185 -0
  578. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  579. package/dist/core/coherence/authoring/sentinels.js +75 -0
  580. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  581. package/dist/core/coherence/calls/called.js +52 -0
  582. package/dist/core/coherence/calls/called.js.map +1 -0
  583. package/dist/core/coherence/coherence.js +332 -0
  584. package/dist/core/coherence/coherence.js.map +1 -0
  585. package/dist/core/coherence/consumed/operations.js +70 -0
  586. package/dist/core/coherence/consumed/operations.js.map +1 -0
  587. package/dist/core/coherence/consumed/refusal.js +38 -0
  588. package/dist/core/coherence/consumed/refusal.js.map +1 -0
  589. package/dist/core/coherence/covers/health.js +85 -0
  590. package/dist/core/coherence/covers/health.js.map +1 -0
  591. package/dist/core/coherence/declared.js +295 -0
  592. package/dist/core/coherence/declared.js.map +1 -0
  593. package/dist/core/coherence/events/declared.js +191 -0
  594. package/dist/core/coherence/events/declared.js.map +1 -0
  595. package/dist/core/coherence/events/events.js +335 -0
  596. package/dist/core/coherence/events/events.js.map +1 -0
  597. package/dist/core/coherence/events/grades.js +189 -0
  598. package/dist/core/coherence/events/grades.js.map +1 -0
  599. package/dist/core/coherence/events/lookups.js +63 -0
  600. package/dist/core/coherence/events/lookups.js.map +1 -0
  601. package/dist/core/coherence/events/produced.js +100 -0
  602. package/dist/core/coherence/events/produced.js.map +1 -0
  603. package/dist/core/coherence/living.js +198 -0
  604. package/dist/core/coherence/living.js.map +1 -0
  605. package/dist/core/coherence/lookups.js +95 -0
  606. package/dist/core/coherence/lookups.js.map +1 -0
  607. package/dist/core/coherence/pending.js +39 -0
  608. package/dist/core/coherence/pending.js.map +1 -0
  609. package/dist/core/coherence/retired/archived.js +285 -0
  610. package/dist/core/coherence/retired/archived.js.map +1 -0
  611. package/dist/core/coherence/retired/event-pair.js +62 -0
  612. package/dist/core/coherence/retired/event-pair.js.map +1 -0
  613. package/dist/core/coherence/retired/merged.js +79 -0
  614. package/dist/core/coherence/retired/merged.js.map +1 -0
  615. package/dist/core/coherence/retired/retirement.js +49 -0
  616. package/dist/core/coherence/retired/retirement.js.map +1 -0
  617. package/dist/core/coherence/retired/revival/arrivals.js +131 -0
  618. package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
  619. package/dist/core/coherence/retired/revival/revived.js +297 -0
  620. package/dist/core/coherence/retired/revival/revived.js.map +1 -0
  621. package/dist/core/conflict-markers.js +60 -0
  622. package/dist/core/conflict-markers.js.map +1 -0
  623. package/dist/core/consumers/after.js +113 -0
  624. package/dist/core/consumers/after.js.map +1 -0
  625. package/dist/core/consumers/consumers.js +296 -0
  626. package/dist/core/consumers/consumers.js.map +1 -0
  627. package/dist/core/consumers/current.js +211 -0
  628. package/dist/core/consumers/current.js.map +1 -0
  629. package/dist/core/consumers/scan.js +46 -0
  630. package/dist/core/consumers/scan.js.map +1 -0
  631. package/dist/core/consumers/state.js +27 -0
  632. package/dist/core/consumers/state.js.map +1 -0
  633. package/dist/core/delta/claims.js +73 -0
  634. package/dist/core/delta/claims.js.map +1 -0
  635. package/dist/core/delta/delta.js +341 -0
  636. package/dist/core/delta/delta.js.map +1 -0
  637. package/dist/core/delta/document.js +177 -0
  638. package/dist/core/delta/document.js.map +1 -0
  639. package/dist/core/delta/scope.js +48 -0
  640. package/dist/core/delta/scope.js.map +1 -0
  641. package/dist/core/delta/select.js +237 -0
  642. package/dist/core/delta/select.js.map +1 -0
  643. package/dist/core/dependencies/dependencies.js +141 -0
  644. package/dist/core/dependencies/dependencies.js.map +1 -0
  645. package/dist/core/dependencies/facts.js +165 -0
  646. package/dist/core/dependencies/facts.js.map +1 -0
  647. package/dist/core/dependencies/fanin.js +88 -0
  648. package/dist/core/dependencies/fanin.js.map +1 -0
  649. package/dist/core/dependencies/graph.js +106 -0
  650. package/dist/core/dependencies/graph.js.map +1 -0
  651. package/dist/core/deployment/delta.js +191 -0
  652. package/dist/core/deployment/delta.js.map +1 -0
  653. package/dist/core/deployment/objects.js +145 -0
  654. package/dist/core/deployment/objects.js.map +1 -0
  655. package/dist/core/diff/base-git.js +230 -0
  656. package/dist/core/diff/base-git.js.map +1 -0
  657. package/dist/core/diff/base-state.js +237 -0
  658. package/dist/core/diff/base-state.js.map +1 -0
  659. package/dist/core/diff/joins.js +136 -0
  660. package/dist/core/diff/joins.js.map +1 -0
  661. package/dist/core/diff/scope/changed-paths.js +204 -0
  662. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  663. package/dist/core/diff/scope/edges.js +82 -0
  664. package/dist/core/diff/scope/edges.js.map +1 -0
  665. package/dist/core/diff/semantic.js +312 -0
  666. package/dist/core/diff/semantic.js.map +1 -0
  667. package/dist/core/docs.js +37 -85
  668. package/dist/core/docs.js.map +1 -1
  669. package/dist/core/doctor/agents.js +238 -0
  670. package/dist/core/doctor/agents.js.map +1 -0
  671. package/dist/core/doctor/config.js +139 -0
  672. package/dist/core/doctor/config.js.map +1 -0
  673. package/dist/core/doctor/doctor.js +355 -0
  674. package/dist/core/doctor/doctor.js.map +1 -0
  675. package/dist/core/doctor/report.js +13 -0
  676. package/dist/core/doctor/report.js.map +1 -0
  677. package/dist/core/doctor/reports/scan.js +242 -0
  678. package/dist/core/doctor/reports/scan.js.map +1 -0
  679. package/dist/core/doctor/residue.js +110 -0
  680. package/dist/core/doctor/residue.js.map +1 -0
  681. package/dist/core/document/apply.js +224 -0
  682. package/dist/core/document/apply.js.map +1 -0
  683. package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
  684. package/dist/core/document/frontmatter.js.map +1 -0
  685. package/dist/core/document/grammar/directives.js +143 -0
  686. package/dist/core/document/grammar/directives.js.map +1 -0
  687. package/dist/core/document/parse.js +286 -0
  688. package/dist/core/document/parse.js.map +1 -0
  689. package/dist/core/document/scenarios.js +238 -0
  690. package/dist/core/document/scenarios.js.map +1 -0
  691. package/dist/core/document/spec.js +234 -0
  692. package/dist/core/document/spec.js.map +1 -0
  693. package/dist/core/{config.js → envelope/config.js} +89 -18
  694. package/dist/core/envelope/config.js.map +1 -0
  695. package/dist/core/envelope/json.js +209 -0
  696. package/dist/core/envelope/json.js.map +1 -0
  697. package/dist/core/{version.js → envelope/version.js} +3 -3
  698. package/dist/core/envelope/version.js.map +1 -0
  699. package/dist/core/explain/families.js +180 -0
  700. package/dist/core/explain/families.js.map +1 -0
  701. package/dist/core/explain/fix-tables.js +178 -0
  702. package/dist/core/explain/fix-tables.js.map +1 -0
  703. package/dist/core/explain/lookup.js +194 -0
  704. package/dist/core/explain/lookup.js.map +1 -0
  705. package/dist/core/explain/refusals.js +49 -0
  706. package/dist/core/explain/refusals.js.map +1 -0
  707. package/dist/core/explain/terms/documents.js +227 -0
  708. package/dist/core/explain/terms/documents.js.map +1 -0
  709. package/dist/core/explain/terms/done-check.js +144 -0
  710. package/dist/core/explain/terms/done-check.js.map +1 -0
  711. package/dist/core/explain/terms/entry.js +14 -0
  712. package/dist/core/explain/terms/entry.js.map +1 -0
  713. package/dist/core/explain/terms/stages.js +71 -0
  714. package/dist/core/explain/terms/stages.js.map +1 -0
  715. package/dist/core/explain/terms/tasks.js +97 -0
  716. package/dist/core/explain/terms/tasks.js.map +1 -0
  717. package/dist/core/explain/terms.js +103 -0
  718. package/dist/core/explain/terms.js.map +1 -0
  719. package/dist/core/explore/describe.js +105 -0
  720. package/dist/core/explore/describe.js.map +1 -0
  721. package/dist/core/explore/explore.js +204 -0
  722. package/dist/core/explore/explore.js.map +1 -0
  723. package/dist/core/fleet-context.js +174 -146
  724. package/dist/core/fleet-context.js.map +1 -1
  725. package/dist/core/gate/checks.js +208 -0
  726. package/dist/core/gate/checks.js.map +1 -0
  727. package/dist/core/gate/partners.js +246 -0
  728. package/dist/core/gate/partners.js.map +1 -0
  729. package/dist/core/gate/report.js +47 -0
  730. package/dist/core/gate/report.js.map +1 -0
  731. package/dist/core/gate/verification.js +176 -0
  732. package/dist/core/gate/verification.js.map +1 -0
  733. package/dist/core/gherkin/digest.js +60 -0
  734. package/dist/core/gherkin/digest.js.map +1 -0
  735. package/dist/core/gherkin/emit.js +177 -0
  736. package/dist/core/gherkin/emit.js.map +1 -0
  737. package/dist/core/gherkin/read.js +76 -0
  738. package/dist/core/gherkin/read.js.map +1 -0
  739. package/dist/core/gherkin/stale.js +210 -0
  740. package/dist/core/gherkin/stale.js.map +1 -0
  741. package/dist/core/gherkin/stamp.js +77 -0
  742. package/dist/core/gherkin/stamp.js.map +1 -0
  743. package/dist/core/gherkin/steps/catalogue.js +154 -0
  744. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  745. package/dist/core/gherkin/steps/inventory.js +98 -0
  746. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  747. package/dist/core/gherkin/steps/phrase.js +72 -0
  748. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  749. package/dist/core/glossary/delta.js +109 -0
  750. package/dist/core/glossary/delta.js.map +1 -0
  751. package/dist/core/glossary/tree.js +73 -0
  752. package/dist/core/glossary/tree.js.map +1 -0
  753. package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
  754. package/dist/core/kernel/concurrency.js.map +1 -0
  755. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  756. package/dist/core/kernel/document-bytes.js.map +1 -0
  757. package/dist/core/kernel/fences.js +42 -0
  758. package/dist/core/kernel/fences.js.map +1 -0
  759. package/dist/core/kernel/ids/capability.js +72 -0
  760. package/dist/core/kernel/ids/capability.js.map +1 -0
  761. package/dist/core/kernel/ids/dirs.js +33 -0
  762. package/dist/core/kernel/ids/dirs.js.map +1 -0
  763. package/dist/core/kernel/ids/feature.js +75 -0
  764. package/dist/core/kernel/ids/feature.js.map +1 -0
  765. package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
  766. package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
  767. package/dist/core/kernel/ids/service.js +156 -0
  768. package/dist/core/kernel/ids/service.js.map +1 -0
  769. package/dist/core/kernel/ids/subsystem.js +63 -0
  770. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  771. package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
  772. package/dist/core/kernel/path-safety.js.map +1 -0
  773. package/dist/core/{records.js → kernel/records.js} +11 -0
  774. package/dist/core/kernel/records.js.map +1 -0
  775. package/dist/core/links/backlinks.js +66 -0
  776. package/dist/core/links/backlinks.js.map +1 -0
  777. package/dist/core/links/case.js +74 -0
  778. package/dist/core/links/case.js.map +1 -0
  779. package/dist/core/links/corpus.js +118 -0
  780. package/dist/core/links/corpus.js.map +1 -0
  781. package/dist/core/links/findings.js +110 -0
  782. package/dist/core/links/findings.js.map +1 -0
  783. package/dist/core/links/parse.js +265 -0
  784. package/dist/core/links/parse.js.map +1 -0
  785. package/dist/core/mcp/argv.js +212 -0
  786. package/dist/core/mcp/argv.js.map +1 -0
  787. package/dist/core/mcp/author-tools.js +73 -0
  788. package/dist/core/mcp/author-tools.js.map +1 -0
  789. package/dist/core/mcp/framing.js +46 -0
  790. package/dist/core/mcp/framing.js.map +1 -0
  791. package/dist/core/mcp/protocol.js +280 -0
  792. package/dist/core/mcp/protocol.js.map +1 -0
  793. package/dist/core/mcp/tools.js +324 -0
  794. package/dist/core/mcp/tools.js.map +1 -0
  795. package/dist/core/obligations/obligations.js +106 -0
  796. package/dist/core/obligations/obligations.js.map +1 -0
  797. package/dist/core/openapi/baseline/gate.js +207 -0
  798. package/dist/core/openapi/baseline/gate.js.map +1 -0
  799. package/dist/core/openapi/baseline/plan.js +142 -0
  800. package/dist/core/openapi/baseline/plan.js.map +1 -0
  801. package/dist/core/openapi/baseline/record.js +174 -0
  802. package/dist/core/openapi/baseline/record.js.map +1 -0
  803. package/dist/core/openapi/contract-text.js +33 -0
  804. package/dist/core/openapi/contract-text.js.map +1 -0
  805. package/dist/core/openapi/contract-tree.js +301 -0
  806. package/dist/core/openapi/contract-tree.js.map +1 -0
  807. package/dist/core/openapi/depth.js +136 -0
  808. package/dist/core/openapi/depth.js.map +1 -0
  809. package/dist/core/openapi/digest.js +239 -0
  810. package/dist/core/openapi/digest.js.map +1 -0
  811. package/dist/core/{openapi.js → openapi/doc.js} +54 -108
  812. package/dist/core/openapi/doc.js.map +1 -0
  813. package/dist/core/openapi/merge/components.js +199 -0
  814. package/dist/core/openapi/merge/components.js.map +1 -0
  815. package/dist/core/openapi/merge/error.js +16 -0
  816. package/dist/core/openapi/merge/error.js.map +1 -0
  817. package/dist/core/openapi/merge/markers.js +204 -0
  818. package/dist/core/openapi/merge/markers.js.map +1 -0
  819. package/dist/core/openapi/merge/merge.js +232 -0
  820. package/dist/core/openapi/merge/merge.js.map +1 -0
  821. package/dist/core/openapi/merge/pin.js +110 -0
  822. package/dist/core/openapi/merge/pin.js.map +1 -0
  823. package/dist/core/openspec/decide/capabilities.js +244 -0
  824. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  825. package/dist/core/openspec/decide/dispositions.js +63 -0
  826. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  827. package/dist/core/openspec/decide/renames.js +179 -0
  828. package/dist/core/openspec/decide/renames.js.map +1 -0
  829. package/dist/core/openspec/decide/verdict.js +84 -0
  830. package/dist/core/openspec/decide/verdict.js.map +1 -0
  831. package/dist/core/openspec/inventory.js +220 -0
  832. package/dist/core/openspec/inventory.js.map +1 -0
  833. package/dist/core/openspec/model/mapping.js +78 -0
  834. package/dist/core/openspec/model/mapping.js.map +1 -0
  835. package/dist/core/openspec/model/model.js +70 -0
  836. package/dist/core/openspec/model/model.js.map +1 -0
  837. package/dist/core/openspec/scan/changes.js +241 -0
  838. package/dist/core/openspec/scan/changes.js.map +1 -0
  839. package/dist/core/openspec/scan/config.js +191 -0
  840. package/dist/core/openspec/scan/config.js.map +1 -0
  841. package/dist/core/openspec/scan/shape.js +304 -0
  842. package/dist/core/openspec/scan/shape.js.map +1 -0
  843. package/dist/core/openspec/scan/walk.js +116 -0
  844. package/dist/core/openspec/scan/walk.js.map +1 -0
  845. package/dist/core/openspec/scan/workspace.js +71 -0
  846. package/dist/core/openspec/scan/workspace.js.map +1 -0
  847. package/dist/core/owners/codeowners.js +141 -0
  848. package/dist/core/owners/codeowners.js.map +1 -0
  849. package/dist/core/pack/features.js +120 -0
  850. package/dist/core/pack/features.js.map +1 -0
  851. package/dist/core/pack/joins.js +112 -0
  852. package/dist/core/pack/joins.js.map +1 -0
  853. package/dist/core/pack/living.js +157 -0
  854. package/dist/core/pack/living.js.map +1 -0
  855. package/dist/core/pack/pack.js +120 -0
  856. package/dist/core/pack/pack.js.map +1 -0
  857. package/dist/core/permissions/permissions.js +87 -0
  858. package/dist/core/permissions/permissions.js.map +1 -0
  859. package/dist/core/projection/api.js +84 -0
  860. package/dist/core/projection/api.js.map +1 -0
  861. package/dist/core/projection/arch-slice.js +63 -0
  862. package/dist/core/projection/arch-slice.js.map +1 -0
  863. package/dist/core/projection/events.js +34 -0
  864. package/dist/core/projection/events.js.map +1 -0
  865. package/dist/core/projection/introduced.js +14 -0
  866. package/dist/core/projection/introduced.js.map +1 -0
  867. package/dist/core/provenance/findings.js +244 -0
  868. package/dist/core/provenance/findings.js.map +1 -0
  869. package/dist/core/provenance/git.js +201 -0
  870. package/dist/core/provenance/git.js.map +1 -0
  871. package/dist/core/provenance/gitq/moves.js +139 -0
  872. package/dist/core/provenance/gitq/moves.js.map +1 -0
  873. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  874. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  875. package/dist/core/provenance/sample/scope.js +238 -0
  876. package/dist/core/provenance/sample/scope.js.map +1 -0
  877. package/dist/core/provenance/sample/sections.js +61 -0
  878. package/dist/core/provenance/sample/sections.js.map +1 -0
  879. package/dist/core/provenance/sources.js +280 -0
  880. package/dist/core/provenance/sources.js.map +1 -0
  881. package/dist/core/provenance/stamp.js +220 -0
  882. package/dist/core/provenance/stamp.js.map +1 -0
  883. package/dist/core/provenance/walk.js +157 -0
  884. package/dist/core/provenance/walk.js.map +1 -0
  885. package/dist/core/repo/authored/paths.js +210 -0
  886. package/dist/core/repo/authored/paths.js.map +1 -0
  887. package/dist/core/repo/entries.js +126 -0
  888. package/dist/core/repo/entries.js.map +1 -0
  889. package/dist/core/repo/paths.js +322 -0
  890. package/dist/core/repo/paths.js.map +1 -0
  891. package/dist/core/repo/repo.js +308 -0
  892. package/dist/core/repo/repo.js.map +1 -0
  893. package/dist/core/repo/service-target.js +153 -0
  894. package/dist/core/repo/service-target.js.map +1 -0
  895. package/dist/core/repo/state.js +58 -0
  896. package/dist/core/repo/state.js.map +1 -0
  897. package/dist/core/repo/tree/find.js +61 -0
  898. package/dist/core/repo/tree/find.js.map +1 -0
  899. package/dist/core/repo/tree/fs.js +90 -0
  900. package/dist/core/repo/tree/fs.js.map +1 -0
  901. package/dist/core/repo/tree/marker.js +61 -0
  902. package/dist/core/repo/tree/marker.js.map +1 -0
  903. package/dist/core/repo/tree/render/body.js +258 -0
  904. package/dist/core/repo/tree/render/body.js.map +1 -0
  905. package/dist/core/repo/tree/render/projects.js +182 -0
  906. package/dist/core/repo/tree/render/projects.js.map +1 -0
  907. package/dist/core/repo/tree/render/service/header.js +125 -0
  908. package/dist/core/repo/tree/render/service/header.js.map +1 -0
  909. package/dist/core/repo/tree/render/service/peers.js +28 -0
  910. package/dist/core/repo/tree/render/service/peers.js.map +1 -0
  911. package/dist/core/repo/tree/render/service/view-id.js +67 -0
  912. package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
  913. package/dist/core/repo/tree/render/service/views.js +78 -0
  914. package/dist/core/repo/tree/render/service/views.js.map +1 -0
  915. package/dist/core/repo/tree/render/stale.js +42 -0
  916. package/dist/core/repo/tree/render/stale.js.map +1 -0
  917. package/dist/core/repo/tree/render/text.js +84 -0
  918. package/dist/core/repo/tree/render/text.js.map +1 -0
  919. package/dist/core/repo/tree/render/views.js +293 -0
  920. package/dist/core/repo/tree/render/views.js.map +1 -0
  921. package/dist/core/repo/tree/walk.js +255 -0
  922. package/dist/core/repo/tree/walk.js.map +1 -0
  923. package/dist/core/results.js +146 -14
  924. package/dist/core/results.js.map +1 -1
  925. package/dist/core/scaffold/landscape.js +239 -0
  926. package/dist/core/scaffold/landscape.js.map +1 -0
  927. package/dist/core/scaffold/legacy.js +271 -0
  928. package/dist/core/scaffold/legacy.js.map +1 -0
  929. package/dist/core/scaffold/readme.js +84 -0
  930. package/dist/core/scaffold/readme.js.map +1 -0
  931. package/dist/core/staging/commit.js +252 -0
  932. package/dist/core/staging/commit.js.map +1 -0
  933. package/dist/core/staging/interrupted.js +96 -0
  934. package/dist/core/staging/interrupted.js.map +1 -0
  935. package/dist/core/staging/lock.js +268 -0
  936. package/dist/core/staging/lock.js.map +1 -0
  937. package/dist/core/staging/recovery/finding.js +35 -0
  938. package/dist/core/staging/recovery/finding.js.map +1 -0
  939. package/dist/core/staging/recovery/intent.js +95 -0
  940. package/dist/core/staging/recovery/intent.js.map +1 -0
  941. package/dist/core/staging/recovery/recover.js +204 -0
  942. package/dist/core/staging/recovery/recover.js.map +1 -0
  943. package/dist/core/staging/recovery/residue.js +62 -0
  944. package/dist/core/staging/recovery/residue.js.map +1 -0
  945. package/dist/core/staging/snapshot/manifest.js +188 -0
  946. package/dist/core/staging/snapshot/manifest.js.map +1 -0
  947. package/dist/core/staging/snapshot/snapshot.js +196 -0
  948. package/dist/core/staging/snapshot/snapshot.js.map +1 -0
  949. package/dist/core/staging/txn/forward.js +181 -0
  950. package/dist/core/staging/txn/forward.js.map +1 -0
  951. package/dist/core/staging/txn/journal.js +139 -0
  952. package/dist/core/staging/txn/journal.js.map +1 -0
  953. package/dist/core/staging/txn/transaction.js +75 -0
  954. package/dist/core/staging/txn/transaction.js.map +1 -0
  955. package/dist/core/staging/writes.js +113 -0
  956. package/dist/core/staging/writes.js.map +1 -0
  957. package/dist/core/status/actions/execution.js +60 -0
  958. package/dist/core/status/actions/execution.js.map +1 -0
  959. package/dist/core/status/contracts.js +126 -0
  960. package/dist/core/status/contracts.js.map +1 -0
  961. package/dist/core/status/feature/artifacts.js +196 -0
  962. package/dist/core/status/feature/artifacts.js.map +1 -0
  963. package/dist/core/status/feature/feature.js +214 -0
  964. package/dist/core/status/feature/feature.js.map +1 -0
  965. package/dist/core/status/feature/next.js +163 -0
  966. package/dist/core/status/feature/next.js.map +1 -0
  967. package/dist/core/status/feature/state.js +21 -0
  968. package/dist/core/status/feature/state.js.map +1 -0
  969. package/dist/core/status/feature/words.js +96 -0
  970. package/dist/core/status/feature/words.js.map +1 -0
  971. package/dist/core/status/fleet/fleet.js +216 -0
  972. package/dist/core/status/fleet/fleet.js.map +1 -0
  973. package/dist/core/status/fleet/next.js +302 -0
  974. package/dist/core/status/fleet/next.js.map +1 -0
  975. package/dist/core/status/interrupted.js +97 -0
  976. package/dist/core/status/interrupted.js.map +1 -0
  977. package/dist/core/status/report.js +31 -0
  978. package/dist/core/status/report.js.map +1 -0
  979. package/dist/core/status/scan.js +41 -0
  980. package/dist/core/status/scan.js.map +1 -0
  981. package/dist/core/status/verification.js +216 -0
  982. package/dist/core/status/verification.js.map +1 -0
  983. package/dist/core/tasks/packet.js +199 -0
  984. package/dist/core/tasks/packet.js.map +1 -0
  985. package/dist/core/tasks/record.js +43 -0
  986. package/dist/core/tasks/record.js.map +1 -0
  987. package/dist/core/tasks/sources.js +181 -0
  988. package/dist/core/tasks/sources.js.map +1 -0
  989. package/dist/core/tasks/stamps.js +76 -0
  990. package/dist/core/tasks/stamps.js.map +1 -0
  991. package/dist/core/tasks/unit.js +0 -0
  992. package/dist/core/tasks/unit.js.map +1 -0
  993. package/dist/core/usecases/capability.js +166 -0
  994. package/dist/core/usecases/capability.js.map +1 -0
  995. package/dist/core/usecases/delta/claims.js +140 -0
  996. package/dist/core/usecases/delta/claims.js.map +1 -0
  997. package/dist/core/usecases/delta/flows.js +101 -0
  998. package/dist/core/usecases/delta/flows.js.map +1 -0
  999. package/dist/core/usecases/delta/modified.js +315 -0
  1000. package/dist/core/usecases/delta/modified.js.map +1 -0
  1001. package/dist/core/usecases/delta/overlay.js +76 -0
  1002. package/dist/core/usecases/delta/overlay.js.map +1 -0
  1003. package/dist/core/usecases/fleet.js +296 -0
  1004. package/dist/core/usecases/fleet.js.map +1 -0
  1005. package/dist/core/usecases/grade/capability-tag.js +93 -0
  1006. package/dist/core/usecases/grade/capability-tag.js.map +1 -0
  1007. package/dist/core/usecases/grade/feature.js +88 -0
  1008. package/dist/core/usecases/grade/feature.js.map +1 -0
  1009. package/dist/core/usecases/grade/requirement-tag.js +94 -0
  1010. package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
  1011. package/dist/core/usecases/grade/steps.js +266 -0
  1012. package/dist/core/usecases/grade/steps.js.map +1 -0
  1013. package/dist/core/usecases/grade/usecases.js +112 -0
  1014. package/dist/core/usecases/grade/usecases.js.map +1 -0
  1015. package/dist/core/usecases/operations.js +123 -0
  1016. package/dist/core/usecases/operations.js.map +1 -0
  1017. package/dist/core/usecases/place.js +44 -0
  1018. package/dist/core/usecases/place.js.map +1 -0
  1019. package/dist/core/usecases/service/exclude.js +119 -0
  1020. package/dist/core/usecases/service/exclude.js.map +1 -0
  1021. package/dist/core/usecases/service/flows.js +164 -0
  1022. package/dist/core/usecases/service/flows.js.map +1 -0
  1023. package/dist/core/usecases/suites/participants.js +83 -0
  1024. package/dist/core/usecases/suites/participants.js.map +1 -0
  1025. package/dist/core/usecases/suites/suites.js +45 -0
  1026. package/dist/core/usecases/suites/suites.js.map +1 -0
  1027. package/dist/core/usecases/touch.js +101 -0
  1028. package/dist/core/usecases/touch.js.map +1 -0
  1029. package/dist/core/verify/answers.js +180 -0
  1030. package/dist/core/verify/answers.js.map +1 -0
  1031. package/dist/core/verify/build.js +170 -0
  1032. package/dist/core/verify/build.js.map +1 -0
  1033. package/dist/core/verify/checklist.js +259 -0
  1034. package/dist/core/verify/checklist.js.map +1 -0
  1035. package/dist/core/verify/claims/identity.js +61 -0
  1036. package/dist/core/verify/claims/identity.js.map +1 -0
  1037. package/dist/core/verify/cross/diff.js +97 -0
  1038. package/dist/core/verify/cross/diff.js.map +1 -0
  1039. package/dist/core/verify/evidence/contract.js +169 -0
  1040. package/dist/core/verify/evidence/contract.js.map +1 -0
  1041. package/dist/core/verify/location.js +67 -0
  1042. package/dist/core/verify/location.js.map +1 -0
  1043. package/dist/core/verify/pins/lint.js +158 -0
  1044. package/dist/core/verify/pins/lint.js.map +1 -0
  1045. package/dist/core/verify/pins/pin.js +95 -0
  1046. package/dist/core/verify/pins/pin.js.map +1 -0
  1047. package/dist/core/verify/read/file.js +224 -0
  1048. package/dist/core/verify/read/file.js.map +1 -0
  1049. package/dist/core/verify/read/shape.js +169 -0
  1050. package/dist/core/verify/read/shape.js.map +1 -0
  1051. package/dist/core/verify/read/union.js +105 -0
  1052. package/dist/core/verify/read/union.js.map +1 -0
  1053. package/dist/core/verify/record.js +165 -0
  1054. package/dist/core/verify/record.js.map +1 -0
  1055. package/dist/core/verify/store/commit.js +99 -0
  1056. package/dist/core/verify/store/commit.js.map +1 -0
  1057. package/dist/core/verify/store/render.js +61 -0
  1058. package/dist/core/verify/store/render.js.map +1 -0
  1059. package/dist/core/vocabulary/health.js +91 -0
  1060. package/dist/core/vocabulary/health.js.map +1 -0
  1061. package/dist/core/vocabulary/issue.js +59 -0
  1062. package/dist/core/vocabulary/issue.js.map +1 -0
  1063. package/dist/core/vocabulary/maturity.js +216 -0
  1064. package/dist/core/vocabulary/maturity.js.map +1 -0
  1065. package/dist/core/vocabulary/report.js +90 -0
  1066. package/dist/core/vocabulary/report.js.map +1 -0
  1067. package/dist/core/vocabulary/steps.js +266 -0
  1068. package/dist/core/vocabulary/steps.js.map +1 -0
  1069. package/dist/core/workspace/discover.js +239 -0
  1070. package/dist/core/workspace/discover.js.map +1 -0
  1071. package/dist/core/workspace/render.js +52 -0
  1072. package/dist/core/workspace/render.js.map +1 -0
  1073. package/examples/README.md +232 -0
  1074. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  1075. package/examples/docs/architecture/capabilities.yaml +31 -0
  1076. package/examples/docs/architecture/landscape.likec4 +336 -0
  1077. package/examples/docs/architecture/obligations.yaml +23 -0
  1078. package/examples/docs/architecture/permissions.yaml +50 -0
  1079. package/examples/docs/architecture/services.likec4 +70 -0
  1080. package/examples/docs/architecture/subsystems.likec4 +18 -0
  1081. package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
  1082. package/examples/docs/capabilities/checkout/spec.md +55 -0
  1083. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  1084. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  1085. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  1086. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  1087. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  1088. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  1089. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
  1090. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  1091. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  1092. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  1093. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  1094. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  1095. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
  1096. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  1097. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  1098. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  1099. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  1100. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  1101. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  1102. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  1103. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  1104. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  1105. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  1106. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
  1107. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  1108. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  1109. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  1110. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  1111. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  1112. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  1113. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  1114. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  1115. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  1116. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  1117. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  1118. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  1119. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  1120. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  1121. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  1122. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  1123. package/examples/docs/glossary/order.md +15 -0
  1124. package/examples/docs/glossary/payments/authorization.md +14 -0
  1125. package/examples/docs/likec4.config.json +8 -0
  1126. package/examples/docs/loam.json +3 -0
  1127. package/examples/docs/services/checkout-web/model.likec4 +92 -0
  1128. package/examples/docs/services/checkout-web/spec.md +91 -0
  1129. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  1130. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  1131. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  1132. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  1133. package/examples/docs/services/order-service/arch.spec.md +134 -0
  1134. package/examples/docs/services/order-service/asyncapi.yaml +109 -0
  1135. package/examples/docs/services/order-service/health.yaml +57 -0
  1136. package/examples/docs/services/order-service/model.likec4 +126 -0
  1137. package/examples/docs/services/order-service/openapi.yaml +257 -0
  1138. package/examples/docs/services/order-service/runbook.md +62 -0
  1139. package/examples/docs/services/order-service/spec.md +134 -0
  1140. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  1141. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  1142. package/examples/docs/services/payment-service/arch.spec.md +76 -0
  1143. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  1144. package/examples/docs/services/payment-service/health.yaml +39 -0
  1145. package/examples/docs/services/payment-service/model.likec4 +68 -0
  1146. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  1147. package/examples/docs/services/payment-service/runbook.md +37 -0
  1148. package/examples/docs/services/payment-service/spec.md +88 -0
  1149. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  1150. package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
  1151. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  1152. package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
  1153. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  1154. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  1155. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  1156. package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
  1157. package/examples/docs/services/platform/notification-service/health.yaml +40 -0
  1158. package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
  1159. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  1160. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  1161. package/examples/docs/services/platform/subsystem.yaml +2 -0
  1162. package/examples/fleet.yaml +57 -0
  1163. package/package.json +19 -6
  1164. package/dist/commands/adopt.js +0 -240
  1165. package/dist/commands/adopt.js.map +0 -1
  1166. package/dist/commands/archive.js +0 -1313
  1167. package/dist/commands/archive.js.map +0 -1
  1168. package/dist/commands/delta.js +0 -388
  1169. package/dist/commands/delta.js.map +0 -1
  1170. package/dist/commands/docs-repo-gate.js.map +0 -1
  1171. package/dist/commands/format.js +0 -17
  1172. package/dist/commands/format.js.map +0 -1
  1173. package/dist/commands/gherkin.js +0 -309
  1174. package/dist/commands/gherkin.js.map +0 -1
  1175. package/dist/commands/init.js.map +0 -1
  1176. package/dist/commands/list.js +0 -295
  1177. package/dist/commands/list.js.map +0 -1
  1178. package/dist/commands/migrate-openspec.js +0 -950
  1179. package/dist/commands/migrate-openspec.js.map +0 -1
  1180. package/dist/commands/new.js +0 -413
  1181. package/dist/commands/new.js.map +0 -1
  1182. package/dist/commands/rebase.js +0 -356
  1183. package/dist/commands/rebase.js.map +0 -1
  1184. package/dist/commands/show.js +0 -320
  1185. package/dist/commands/show.js.map +0 -1
  1186. package/dist/commands/status.js +0 -262
  1187. package/dist/commands/status.js.map +0 -1
  1188. package/dist/commands/unarchive.js +0 -317
  1189. package/dist/commands/unarchive.js.map +0 -1
  1190. package/dist/commands/validate.js +0 -1773
  1191. package/dist/commands/validate.js.map +0 -1
  1192. package/dist/commands/verify.js +0 -775
  1193. package/dist/commands/verify.js.map +0 -1
  1194. package/dist/commands/vouch.js +0 -421
  1195. package/dist/commands/vouch.js.map +0 -1
  1196. package/dist/core/agent.js +0 -2173
  1197. package/dist/core/agent.js.map +0 -1
  1198. package/dist/core/agents-stamp.js.map +0 -1
  1199. package/dist/core/arch.js +0 -130
  1200. package/dist/core/arch.js.map +0 -1
  1201. package/dist/core/asyncapi.js +0 -253
  1202. package/dist/core/asyncapi.js.map +0 -1
  1203. package/dist/core/brief.js +0 -755
  1204. package/dist/core/brief.js.map +0 -1
  1205. package/dist/core/coherence.js +0 -577
  1206. package/dist/core/coherence.js.map +0 -1
  1207. package/dist/core/concurrency.js.map +0 -1
  1208. package/dist/core/config.js.map +0 -1
  1209. package/dist/core/delta.js +0 -476
  1210. package/dist/core/delta.js.map +0 -1
  1211. package/dist/core/dependencies.js +0 -356
  1212. package/dist/core/dependencies.js.map +0 -1
  1213. package/dist/core/doctor.js +0 -596
  1214. package/dist/core/doctor.js.map +0 -1
  1215. package/dist/core/document-bytes.js.map +0 -1
  1216. package/dist/core/explore.js +0 -225
  1217. package/dist/core/explore.js.map +0 -1
  1218. package/dist/core/frontmatter.js.map +0 -1
  1219. package/dist/core/gherkin.js +0 -463
  1220. package/dist/core/gherkin.js.map +0 -1
  1221. package/dist/core/health.js +0 -67
  1222. package/dist/core/health.js.map +0 -1
  1223. package/dist/core/ids.js +0 -122
  1224. package/dist/core/ids.js.map +0 -1
  1225. package/dist/core/issue.js +0 -9
  1226. package/dist/core/issue.js.map +0 -1
  1227. package/dist/core/json.js +0 -74
  1228. package/dist/core/json.js.map +0 -1
  1229. package/dist/core/likec4.js +0 -489
  1230. package/dist/core/likec4.js.map +0 -1
  1231. package/dist/core/maturity.js +0 -66
  1232. package/dist/core/maturity.js.map +0 -1
  1233. package/dist/core/openapi-merge.js +0 -552
  1234. package/dist/core/openapi-merge.js.map +0 -1
  1235. package/dist/core/openapi.js.map +0 -1
  1236. package/dist/core/openspec-inventory.js +0 -1440
  1237. package/dist/core/openspec-inventory.js.map +0 -1
  1238. package/dist/core/path-safety.js.map +0 -1
  1239. package/dist/core/provenance.js +0 -787
  1240. package/dist/core/provenance.js.map +0 -1
  1241. package/dist/core/records.js.map +0 -1
  1242. package/dist/core/repo.js +0 -438
  1243. package/dist/core/repo.js.map +0 -1
  1244. package/dist/core/report.js +0 -47
  1245. package/dist/core/report.js.map +0 -1
  1246. package/dist/core/spec.js +0 -505
  1247. package/dist/core/spec.js.map +0 -1
  1248. package/dist/core/staging.js +0 -890
  1249. package/dist/core/staging.js.map +0 -1
  1250. package/dist/core/status.js +0 -1132
  1251. package/dist/core/status.js.map +0 -1
  1252. package/dist/core/steps.js +0 -72
  1253. package/dist/core/steps.js.map +0 -1
  1254. package/dist/core/verify.js +0 -807
  1255. package/dist/core/verify.js.map +0 -1
  1256. package/dist/core/version.js.map +0 -1
@@ -0,0 +1,269 @@
1
+ import { existsSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { relative } from "node:path";
4
+ import { decodeDocument, NotUtf8DocumentError } from "../../core/kernel/document-bytes.js";
5
+ import { configOrRefuse, emitJson, fail, NO_SERVICE_MESSAGE } from "../../core/envelope/json.js";
6
+ import { featureSpecPaths, SPEC_AXES, unfiledServicePaths } from "../../core/repo/paths.js";
7
+ import { locateServicePaths, resolveServiceTarget } from "../../core/repo/service-target.js";
8
+ import {} from "../../core/repo/entries.js";
9
+ import { introducingFeatures } from "../../core/projection/introduced.js";
10
+ import { parseRequirements } from "../../core/document/parse.js";
11
+ import { axisLabel } from "../../core/gherkin/emit.js";
12
+ import { coveringPhrases, stepInventory, } from "../../core/gherkin/steps/inventory.js";
13
+ import { compareToCatalogue, readStepCatalogue, } from "../../core/gherkin/steps/catalogue.js";
14
+ export function registerSteps(program) {
15
+ program
16
+ .command("steps")
17
+ .description("Inventory the step phrases of a service's scenarios — how many step definitions its suite needs")
18
+ .option("--service <id>", "service to inventory (defaults to the configured service)")
19
+ .option("--duplicates", "list only the near-duplicate groups — phrases that differ by an article or a trailing clause")
20
+ .option("--json", "emit the machine contract instead of the human view")
21
+ .action(async (opts) => {
22
+ const json = opts.json === true;
23
+ const config = await configOrRefuse(json);
24
+ if (config === null)
25
+ return;
26
+ const named = opts.service ?? config.service;
27
+ if (named === undefined)
28
+ return fail(json, "invalid-option", NO_SERVICE_MESSAGE);
29
+ // The enumeration's own id, not the string the caller typed: only one of
30
+ // them carries the fact that a `readdir` produced it, and it is what makes
31
+ // the name pathable. Same resolution `validate --service` performs, so the
32
+ // two commands cannot disagree about which directory a name means.
33
+ const resolved = await resolveServiceTarget(config.docsDir, named, "--service");
34
+ // A name `services/` does not hold may still be a service an active
35
+ // feature INTRODUCES — the second enumeration, a readdir of the feature's
36
+ // own specs/, so it is asked before the grammar refusal too. Its phrases
37
+ // are the delta's: the implement protocol tells whoever builds a NEW
38
+ // service to run this before writing a single step definition, and the
39
+ // answer was "No living spec … run `loam adopt`" for code that does not
40
+ // exist yet. The bound service (`config.service`) takes the same road.
41
+ const introducing = resolved.ok && resolved.dir !== undefined ? [] : await introducingFeatures(config.docsDir, named);
42
+ const introducedId = introducing[0]?.services.find((s) => s === named);
43
+ let source;
44
+ if (introducedId !== undefined) {
45
+ source = introducedSource(config.docsDir, introducedId, introducing);
46
+ }
47
+ else {
48
+ if (!resolved.ok)
49
+ return fail(json, "invalid-option", resolved.problem);
50
+ const paths = await locateServicePaths(config.docsDir, resolved.id);
51
+ if (!existsSync(paths.spec)) {
52
+ return fail(json, "unknown-target", `No living spec at ${paths.spec}. Run \`loam adopt\` for '${resolved.id}' first.`);
53
+ }
54
+ source = {
55
+ service: resolved.id,
56
+ files: SPEC_AXES.map((axis) => ({ axis, path: paths[axis.key] })),
57
+ steps: paths.steps,
58
+ introducedBy: [],
59
+ };
60
+ }
61
+ const { service } = source;
62
+ const axes = [];
63
+ try {
64
+ for (const { axis, path } of source.files) {
65
+ // An absent arch.spec.md is not a finding anywhere else and is not one
66
+ // here: partial adoption is supported, and an empty axis contributes
67
+ // no phrases rather than an empty section nobody asked for.
68
+ const reqs = existsSync(path)
69
+ ? parseRequirements(decodeDocument(await readFile(path), path))
70
+ : [];
71
+ axes.push({ axis: axisLabel(axis), reqs });
72
+ }
73
+ }
74
+ catch (err) {
75
+ if (!(err instanceof NotUtf8DocumentError))
76
+ throw err;
77
+ return fail(json, "repository-unavailable", `Cannot inventory steps: ${err.message}`);
78
+ }
79
+ const inv = stepInventory(axes);
80
+ // The catalogue is what makes the report a DIFF rather than a
81
+ // recomputation: without it every run says the same thing about a suite
82
+ // whose glue somebody has already written. Absent is the ordinary state
83
+ // and costs one `existsSync` (`core/gherkin/steps/catalogue.ts`).
84
+ const catalogue = await readStepCatalogue(source.steps);
85
+ const against = catalogue.present && catalogue.unreadable === undefined
86
+ ? compareToCatalogue(inv, catalogue)
87
+ : null;
88
+ // Computed ONCE, above the branch, and derived from the path
89
+ // `locateServicePaths` resolved rather than joined from the id. A filed
90
+ // service lives wherever the tree walk found it — `services/commerce/
91
+ // checkout/`, not `services/checkout/` — and `core/repo/service-target.ts`
92
+ // says so at length. Two outputs of one command spelling the path two
93
+ // ways is how the human view came to name a directory that does not
94
+ // exist, and here that would be worse than cosmetic: `steps.yaml` is a
95
+ // service artifact now, so an author who created the file where this told
96
+ // them to would mint a second, empty service in the enumeration.
97
+ const where = docsRelative(config.docsDir, source.steps);
98
+ const introducedBy = source.introducedBy.map((f) => f.id);
99
+ if (json) {
100
+ emitJson({
101
+ command: "steps",
102
+ docsDir: config.docsDir,
103
+ service,
104
+ // Present only for a service a feature introduces, so a living
105
+ // service's payload stays byte-identical: `living: false` is the
106
+ // marker, and `specs` names the delta files the phrases came from.
107
+ ...(introducedBy.length === 0
108
+ ? {}
109
+ : {
110
+ living: false,
111
+ introducedBy,
112
+ specs: source.files.filter((f) => existsSync(f.path)).map((f) => docsRelative(config.docsDir, f.path)),
113
+ }),
114
+ steps: inv.steps,
115
+ phrases: inv.phrases.length,
116
+ covering80: coveringPhrases(inv),
117
+ rows: inv.phrases.map((p) => ({
118
+ key: p.key,
119
+ count: p.count,
120
+ keywords: p.keywords,
121
+ uses: p.uses,
122
+ })),
123
+ nearDuplicates: inv.nearDuplicates,
124
+ // Additive, and one key rather than columns spread through `rows`: a
125
+ // consumer that has not adopted the catalogue reads exactly what it
126
+ // read before. `present: false` and `unreadable` are different
127
+ // answers and both are real — "nobody has catalogued anything" is not
128
+ // "loam could not look".
129
+ catalogue: {
130
+ present: catalogue.present,
131
+ path: where,
132
+ entries: catalogue.entries.length,
133
+ ...(catalogue.unreadable === undefined ? {} : { unreadable: catalogue.unreadable }),
134
+ ...(against === null ? {} : against),
135
+ },
136
+ });
137
+ return;
138
+ }
139
+ const origin = introducedBy.length === 0
140
+ ? null
141
+ : {
142
+ by: introducedBy.join(", "),
143
+ dirs: source.introducedBy.map((f) => `${docsRelative(config.docsDir, featureSpecPaths(f.dir, service).dir)}/`),
144
+ };
145
+ print(inv, { service, origin, duplicatesOnly: opts.duplicates === true });
146
+ printCatalogue({ catalogue, against, where, introducedBy });
147
+ });
148
+ }
149
+ /**
150
+ * Every introducing feature's spec pair, not just the first: with two features
151
+ * each introducing the service, the suite that exists once both merge needs the
152
+ * glue for both, and this command has no flag to choose one. The catalogue path
153
+ * is the unfiled spelling — where archive materialises a new service — and is
154
+ * reported, never written: `printCatalogue` says why nobody should create it
155
+ * yet.
156
+ */
157
+ function introducedSource(docsDir, service, introducedBy) {
158
+ return {
159
+ service,
160
+ files: introducedBy.flatMap((f) => {
161
+ const paths = featureSpecPaths(f.dir, service);
162
+ return SPEC_AXES.map((axis) => ({ axis, path: paths[axis.key] }));
163
+ }),
164
+ steps: unfiledServicePaths(docsDir, service).steps,
165
+ introducedBy,
166
+ };
167
+ }
168
+ /** A docs-relative POSIX path, the spelling every path in this command's output uses. */
169
+ function docsRelative(docsDir, path) {
170
+ return relative(docsDir, path).split(/[\\/]/).join("/");
171
+ }
172
+ /**
173
+ * The human view leads with the two numbers a team plans from — how many steps
174
+ * are written, and how few definitions cover most of them — because the list
175
+ * underneath is long by construction and the headline is what decides whether
176
+ * anybody reads it.
177
+ *
178
+ * For an introduced service the source is said straight under the headline:
179
+ * the same numbers read off a delta are a proposal, and a reader who takes them
180
+ * for a living spec's would plan glue for scenarios review may still change.
181
+ */
182
+ function print(inv, view) {
183
+ const { service, origin, duplicatesOnly } = view;
184
+ const from = origin === null
185
+ ? null
186
+ : ` read from the feature delta, not a living spec: ${origin.dirs.join(", ")} — ` +
187
+ `${service} is introduced by ${origin.by} and is not in the living docs until it archives`;
188
+ if (inv.steps === 0) {
189
+ console.log(origin === null
190
+ ? `steps ${service} — the living specs hold no scenario steps yet.\n`
191
+ : `steps ${service} — the delta introducing it holds no scenario steps yet.\n${from}\n`);
192
+ return;
193
+ }
194
+ const covering = coveringPhrases(inv);
195
+ const share = Math.round((100 * inv.phrases.reduce((a, p, i) => (i < covering ? a + p.count : a), 0)) / inv.steps);
196
+ console.log(`steps ${service} — ${inv.steps} written step(s), ${inv.phrases.length} distinct phrase(s)`);
197
+ if (from !== null)
198
+ console.log(from);
199
+ console.log(` ${covering} phrase(s) cover ${share}% of them — that is the size of the step-definition registry\n`);
200
+ if (!duplicatesOnly) {
201
+ for (const p of inv.phrases) {
202
+ console.log(` ${String(p.count).padStart(4)} ${p.key}`);
203
+ console.log(` ${p.keywords.join("/")} · ${[...new Set(p.uses.map((u) => u.requirement))].join(", ")}`);
204
+ }
205
+ console.log();
206
+ }
207
+ if (inv.nearDuplicates.length === 0) {
208
+ console.log(" no near-duplicate phrases.");
209
+ return;
210
+ }
211
+ console.log(` ${inv.nearDuplicates.length} near-duplicate group(s) — one definition was probably meant:`);
212
+ for (const g of inv.nearDuplicates) {
213
+ console.log(` ${g.family}`);
214
+ for (const k of g.keys)
215
+ console.log(` · ${k}`);
216
+ }
217
+ }
218
+ /**
219
+ * The catalogue columns, printed after the inventory rather than woven into
220
+ * them.
221
+ *
222
+ * Separate because the two answers have different lifetimes: the inventory is a
223
+ * fact about the specs and is always true, while this is a diff against a
224
+ * decision that may not have been made yet. Weaving a "not catalogued" marker
225
+ * through every phrase row of a service with no `steps.yaml` would mark the
226
+ * whole report as work owed, which is the opposite of what an absent catalogue
227
+ * means.
228
+ *
229
+ * Nothing here is a finding and nothing changes the exit code. `loam steps` is a
230
+ * read, and a phrase written before its glue is the normal order of work.
231
+ */
232
+ function printCatalogue({ catalogue, against, where, introducedBy }) {
233
+ // A service still in flight gets the opposite advice. `steps.yaml` is a
234
+ // service artifact (repo/paths.ts), so writing one where it belongs mints the
235
+ // service's directory — and the service with it — before its feature merges,
236
+ // after which nothing reads the feature's specs/ as introducing it any more.
237
+ if (!catalogue.present && introducedBy.length > 0) {
238
+ console.log(`\n no catalogue yet — ${where} lands with the service when ${introducedBy.join(", ")} archives.`);
239
+ console.log(" Write it after the archive: a steps.yaml there now would put the service in the living docs before its feature merges.");
240
+ return;
241
+ }
242
+ if (!catalogue.present) {
243
+ console.log(`\n no ${where} — nothing records which phrases this suite has decided to define.`);
244
+ console.log(" Write one (a `steps:` list of step texts) and this report becomes a diff instead of a recount.");
245
+ return;
246
+ }
247
+ if (catalogue.unreadable !== undefined) {
248
+ console.log(`\n ${where} could not be read — ${catalogue.unreadable}.`);
249
+ console.log(" The catalogue columns are blank: loam did not look, which is not the same as nothing being catalogued.");
250
+ return;
251
+ }
252
+ if (against === null)
253
+ return;
254
+ console.log(`\n ${catalogue.entries.length} phrase(s) catalogued in ${where}`);
255
+ console.log(` ${against.uncatalogued.length} written but not catalogued · ${against.unwritten.length} catalogued but not written`);
256
+ for (const key of against.uncatalogued)
257
+ console.log(` + ${key}`);
258
+ for (const key of against.unwritten)
259
+ console.log(` - ${key}`);
260
+ if (against.duplicated.length === 0)
261
+ return;
262
+ console.log(` ${against.duplicated.length} catalogue entr(ies) collapse onto a phrase already listed:`);
263
+ for (const dup of against.duplicated) {
264
+ console.log(` ${dup.key}`);
265
+ for (const text of dup.texts)
266
+ console.log(` · ${text}`);
267
+ }
268
+ }
269
+ //# sourceMappingURL=steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steps.js","sourceRoot":"","sources":["../../../src/commands/steps/steps.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loam steps` — the step-phrase inventory of one service's living specs, or,\n * for a service an active feature introduces and `services/` does not hold\n * yet, of that feature's spec delta (the payload then says `living: false`).\n *\n * A READ, and that is the whole design. It emits no finding, sets no exit code\n * beyond a refusal, writes nothing, and needs no service repo to stand in: it\n * parses `spec.md` and `arch.spec.md` from the docs repo exactly as `validate\n * --service` does. `loam gherkin` refuses outside the service's own repository\n * because it WRITES there; this answers a question about documents, so the\n * restriction would buy nothing and cost the analyst who wants the number\n * before anybody has scaffolded a repo.\n *\n * What it is for is in `core/gherkin/steps/inventory.ts`. In one line: the glue\n * layer is where a generated suite dies, and until this existed nobody could\n * tell a suite needing forty step definitions from one needing four hundred.\n */\nimport type { Command } from \"commander\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { relative } from \"node:path\";\nimport { decodeDocument, NotUtf8DocumentError } from \"../../core/kernel/document-bytes.js\";\nimport { configOrRefuse, emitJson, fail, NO_SERVICE_MESSAGE } from \"../../core/envelope/json.js\";\nimport { featureSpecPaths, SPEC_AXES, unfiledServicePaths, type SpecAxis } from \"../../core/repo/paths.js\";\nimport { locateServicePaths, resolveServiceTarget } from \"../../core/repo/service-target.js\";\nimport { type FeatureEntry } from \"../../core/repo/entries.js\";\nimport { introducingFeatures } from \"../../core/projection/introduced.js\";\nimport type { DocsDir } from \"../../core/kernel/ids/dirs.js\";\nimport type { RawServiceId } from \"../../core/kernel/ids/service.js\";\nimport { parseRequirements } from \"../../core/document/parse.js\";\nimport { axisLabel } from \"../../core/gherkin/emit.js\";\nimport {\n coveringPhrases,\n stepInventory,\n type InventoryAxis,\n type StepInventory,\n} from \"../../core/gherkin/steps/inventory.js\";\nimport {\n compareToCatalogue,\n readStepCatalogue,\n type CatalogueComparison,\n type StepCatalogue,\n} from \"../../core/gherkin/steps/catalogue.js\";\n\ninterface StepsOptions {\n service?: string;\n duplicates?: boolean;\n json?: boolean;\n}\n\nexport function registerSteps(program: Command): void {\n program\n .command(\"steps\")\n .description(\"Inventory the step phrases of a service's scenarios — how many step definitions its suite needs\")\n .option(\"--service <id>\", \"service to inventory (defaults to the configured service)\")\n .option(\"--duplicates\", \"list only the near-duplicate groups — phrases that differ by an article or a trailing clause\")\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .action(async (opts: StepsOptions) => {\n const json = opts.json === true;\n const config = await configOrRefuse(json);\n if (config === null) return;\n const named = opts.service ?? config.service;\n if (named === undefined) return fail(json, \"invalid-option\", NO_SERVICE_MESSAGE);\n // The enumeration's own id, not the string the caller typed: only one of\n // them carries the fact that a `readdir` produced it, and it is what makes\n // the name pathable. Same resolution `validate --service` performs, so the\n // two commands cannot disagree about which directory a name means.\n const resolved = await resolveServiceTarget(config.docsDir, named, \"--service\");\n // A name `services/` does not hold may still be a service an active\n // feature INTRODUCES — the second enumeration, a readdir of the feature's\n // own specs/, so it is asked before the grammar refusal too. Its phrases\n // are the delta's: the implement protocol tells whoever builds a NEW\n // service to run this before writing a single step definition, and the\n // answer was \"No living spec … run `loam adopt`\" for code that does not\n // exist yet. The bound service (`config.service`) takes the same road.\n const introducing =\n resolved.ok && resolved.dir !== undefined ? [] : await introducingFeatures(config.docsDir, named);\n const introducedId = introducing[0]?.services.find((s) => s === named);\n let source: Source;\n if (introducedId !== undefined) {\n source = introducedSource(config.docsDir, introducedId, introducing);\n } else {\n if (!resolved.ok) return fail(json, \"invalid-option\", resolved.problem);\n const paths = await locateServicePaths(config.docsDir, resolved.id);\n if (!existsSync(paths.spec)) {\n return fail(\n json,\n \"unknown-target\",\n `No living spec at ${paths.spec}. Run \\`loam adopt\\` for '${resolved.id}' first.`,\n );\n }\n source = {\n service: resolved.id,\n files: SPEC_AXES.map((axis) => ({ axis, path: paths[axis.key] })),\n steps: paths.steps,\n introducedBy: [],\n };\n }\n const { service } = source;\n const axes: InventoryAxis[] = [];\n try {\n for (const { axis, path } of source.files) {\n // An absent arch.spec.md is not a finding anywhere else and is not one\n // here: partial adoption is supported, and an empty axis contributes\n // no phrases rather than an empty section nobody asked for.\n const reqs = existsSync(path)\n ? parseRequirements(decodeDocument(await readFile(path), path))\n : [];\n axes.push({ axis: axisLabel(axis), reqs });\n }\n } catch (err) {\n if (!(err instanceof NotUtf8DocumentError)) throw err;\n return fail(json, \"repository-unavailable\", `Cannot inventory steps: ${err.message}`);\n }\n\n const inv = stepInventory(axes);\n // The catalogue is what makes the report a DIFF rather than a\n // recomputation: without it every run says the same thing about a suite\n // whose glue somebody has already written. Absent is the ordinary state\n // and costs one `existsSync` (`core/gherkin/steps/catalogue.ts`).\n const catalogue = await readStepCatalogue(source.steps);\n const against = catalogue.present && catalogue.unreadable === undefined\n ? compareToCatalogue(inv, catalogue)\n : null;\n // Computed ONCE, above the branch, and derived from the path\n // `locateServicePaths` resolved rather than joined from the id. A filed\n // service lives wherever the tree walk found it — `services/commerce/\n // checkout/`, not `services/checkout/` — and `core/repo/service-target.ts`\n // says so at length. Two outputs of one command spelling the path two\n // ways is how the human view came to name a directory that does not\n // exist, and here that would be worse than cosmetic: `steps.yaml` is a\n // service artifact now, so an author who created the file where this told\n // them to would mint a second, empty service in the enumeration.\n const where = docsRelative(config.docsDir, source.steps);\n const introducedBy = source.introducedBy.map((f) => f.id);\n if (json) {\n emitJson({\n command: \"steps\",\n docsDir: config.docsDir,\n service,\n // Present only for a service a feature introduces, so a living\n // service's payload stays byte-identical: `living: false` is the\n // marker, and `specs` names the delta files the phrases came from.\n ...(introducedBy.length === 0\n ? {}\n : {\n living: false,\n introducedBy,\n specs: source.files.filter((f) => existsSync(f.path)).map((f) => docsRelative(config.docsDir, f.path)),\n }),\n steps: inv.steps,\n phrases: inv.phrases.length,\n covering80: coveringPhrases(inv),\n rows: inv.phrases.map((p) => ({\n key: p.key,\n count: p.count,\n keywords: p.keywords,\n uses: p.uses,\n })),\n nearDuplicates: inv.nearDuplicates,\n // Additive, and one key rather than columns spread through `rows`: a\n // consumer that has not adopted the catalogue reads exactly what it\n // read before. `present: false` and `unreadable` are different\n // answers and both are real — \"nobody has catalogued anything\" is not\n // \"loam could not look\".\n catalogue: {\n present: catalogue.present,\n path: where,\n entries: catalogue.entries.length,\n ...(catalogue.unreadable === undefined ? {} : { unreadable: catalogue.unreadable }),\n ...(against === null ? {} : against),\n },\n });\n return;\n }\n const origin = introducedBy.length === 0\n ? null\n : {\n by: introducedBy.join(\", \"),\n dirs: source.introducedBy.map((f) => `${docsRelative(config.docsDir, featureSpecPaths(f.dir, service).dir)}/`),\n };\n print(inv, { service, origin, duplicatesOnly: opts.duplicates === true });\n printCatalogue({ catalogue, against, where, introducedBy });\n });\n}\n\n/**\n * Where the phrases are read from. A living service reads its own spec pair; a\n * service an active feature introduces reads each introducing feature's delta\n * pair, because that is the only place its scenarios are written yet.\n */\ninterface Source {\n service: RawServiceId;\n files: Array<{ axis: SpecAxis; path: string }>;\n /** The catalogue's path — the service's own, or, for an introduced one, where its directory will land. */\n steps: string;\n /** The introducing features; empty for a living service. */\n introducedBy: FeatureEntry[];\n}\n\n/**\n * Every introducing feature's spec pair, not just the first: with two features\n * each introducing the service, the suite that exists once both merge needs the\n * glue for both, and this command has no flag to choose one. The catalogue path\n * is the unfiled spelling — where archive materialises a new service — and is\n * reported, never written: `printCatalogue` says why nobody should create it\n * yet.\n */\nfunction introducedSource(docsDir: DocsDir, service: RawServiceId, introducedBy: FeatureEntry[]): Source {\n return {\n service,\n files: introducedBy.flatMap((f) => {\n const paths = featureSpecPaths(f.dir, service);\n return SPEC_AXES.map((axis) => ({ axis, path: paths[axis.key] }));\n }),\n steps: unfiledServicePaths(docsDir, service).steps,\n introducedBy,\n };\n}\n\n/** A docs-relative POSIX path, the spelling every path in this command's output uses. */\nfunction docsRelative(docsDir: DocsDir, path: string): string {\n return relative(docsDir, path).split(/[\\\\/]/).join(\"/\");\n}\n\n/** What the human headline prints from. */\ninterface PrintView {\n service: string;\n /** For a service a feature introduces: which features, and the delta directories read. Null when living. */\n origin: { by: string; dirs: string[] } | null;\n duplicatesOnly: boolean;\n}\n\n/**\n * The human view leads with the two numbers a team plans from — how many steps\n * are written, and how few definitions cover most of them — because the list\n * underneath is long by construction and the headline is what decides whether\n * anybody reads it.\n *\n * For an introduced service the source is said straight under the headline:\n * the same numbers read off a delta are a proposal, and a reader who takes them\n * for a living spec's would plan glue for scenarios review may still change.\n */\nfunction print(inv: StepInventory, view: PrintView): void {\n const { service, origin, duplicatesOnly } = view;\n const from = origin === null\n ? null\n : ` read from the feature delta, not a living spec: ${origin.dirs.join(\", \")} — ` +\n `${service} is introduced by ${origin.by} and is not in the living docs until it archives`;\n if (inv.steps === 0) {\n console.log(\n origin === null\n ? `steps ${service} — the living specs hold no scenario steps yet.\\n`\n : `steps ${service} — the delta introducing it holds no scenario steps yet.\\n${from}\\n`,\n );\n return;\n }\n const covering = coveringPhrases(inv);\n const share = Math.round((100 * inv.phrases.reduce((a, p, i) => (i < covering ? a + p.count : a), 0)) / inv.steps);\n console.log(`steps ${service} — ${inv.steps} written step(s), ${inv.phrases.length} distinct phrase(s)`);\n if (from !== null) console.log(from);\n console.log(` ${covering} phrase(s) cover ${share}% of them — that is the size of the step-definition registry\\n`);\n\n if (!duplicatesOnly) {\n for (const p of inv.phrases) {\n console.log(` ${String(p.count).padStart(4)} ${p.key}`);\n console.log(` ${p.keywords.join(\"/\")} · ${[...new Set(p.uses.map((u) => u.requirement))].join(\", \")}`);\n }\n console.log();\n }\n\n if (inv.nearDuplicates.length === 0) {\n console.log(\" no near-duplicate phrases.\");\n return;\n }\n console.log(` ${inv.nearDuplicates.length} near-duplicate group(s) — one definition was probably meant:`);\n for (const g of inv.nearDuplicates) {\n console.log(` ${g.family}`);\n for (const k of g.keys) console.log(` · ${k}`);\n }\n}\n\n/** What the catalogue columns print from — the read and, when it was worth making, the comparison. */\ninterface CatalogueView {\n catalogue: StepCatalogue;\n /** Null when there was nothing readable to compare against. */\n against: CatalogueComparison | null;\n /**\n * The catalogue's docs-relative path, RESOLVED — never `services/<id>/…`\n * rejoined from the service name, which is right for an unfiled service and\n * wrong for every filed one. The same string `--json` reports.\n */\n where: string;\n /** The features introducing the service, by id; empty for a living one. */\n introducedBy: string[];\n}\n\n/**\n * The catalogue columns, printed after the inventory rather than woven into\n * them.\n *\n * Separate because the two answers have different lifetimes: the inventory is a\n * fact about the specs and is always true, while this is a diff against a\n * decision that may not have been made yet. Weaving a \"not catalogued\" marker\n * through every phrase row of a service with no `steps.yaml` would mark the\n * whole report as work owed, which is the opposite of what an absent catalogue\n * means.\n *\n * Nothing here is a finding and nothing changes the exit code. `loam steps` is a\n * read, and a phrase written before its glue is the normal order of work.\n */\nfunction printCatalogue({ catalogue, against, where, introducedBy }: CatalogueView): void {\n // A service still in flight gets the opposite advice. `steps.yaml` is a\n // service artifact (repo/paths.ts), so writing one where it belongs mints the\n // service's directory — and the service with it — before its feature merges,\n // after which nothing reads the feature's specs/ as introducing it any more.\n if (!catalogue.present && introducedBy.length > 0) {\n console.log(`\\n no catalogue yet — ${where} lands with the service when ${introducedBy.join(\", \")} archives.`);\n console.log(\" Write it after the archive: a steps.yaml there now would put the service in the living docs before its feature merges.\");\n return;\n }\n if (!catalogue.present) {\n console.log(`\\n no ${where} — nothing records which phrases this suite has decided to define.`);\n console.log(\" Write one (a `steps:` list of step texts) and this report becomes a diff instead of a recount.\");\n return;\n }\n if (catalogue.unreadable !== undefined) {\n console.log(`\\n ${where} could not be read — ${catalogue.unreadable}.`);\n console.log(\" The catalogue columns are blank: loam did not look, which is not the same as nothing being catalogued.\");\n return;\n }\n if (against === null) return;\n console.log(`\\n ${catalogue.entries.length} phrase(s) catalogued in ${where}`);\n console.log(\n ` ${against.uncatalogued.length} written but not catalogued · ${against.unwritten.length} catalogued but not written`,\n );\n for (const key of against.uncatalogued) console.log(` + ${key}`);\n for (const key of against.unwritten) console.log(` - ${key}`);\n if (against.duplicated.length === 0) return;\n console.log(` ${against.duplicated.length} catalogue entr(ies) collapse onto a phrase already listed:`);\n for (const dup of against.duplicated) {\n console.log(` ${dup.key}`);\n for (const text of dup.texts) console.log(` · ${text}`);\n }\n}\n"]}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * The two verbs that create and remove GROUPS: `subsystem new` and
3
+ * `subsystem rm`. Both commit the marker AND the regenerated views file in
4
+ * one journaled transaction, because a marker without its view (or a view
5
+ * outliving its marker) is exactly the `subsystem.views-stale` state the
6
+ * generated file's contract refuses to leave behind.
7
+ *
8
+ * `rm` refuses a subsystem with members — services, child subsystems, or any
9
+ * stray non-dot entry beside the marker the tree does not already count —
10
+ * naming each once, as what it is (`subsystem-not-empty`):
11
+ * a destructive command never picks targets the caller did not name, and a
12
+ * directory emptied of its marker but not of its contents would re-enter the
13
+ * walk as a phantom service.
14
+ */
15
+ import { existsSync } from "node:fs";
16
+ import { readdir, rmdir } from "node:fs/promises";
17
+ import { join } from "node:path";
18
+ import { stringify } from "yaml";
19
+ import { parseSubsystemName } from "../../core/kernel/ids/subsystem.js";
20
+ import { emitJson, fail, repoPath } from "../../core/envelope/json.js";
21
+ import { servicesDir, subsystemPathUnder } from "../../core/repo/paths.js";
22
+ import { closeNamesHint, findInTree, servicesUnder, subsystemsUnder } from "../../core/repo/tree/find.js";
23
+ import { entryIs } from "../../core/repo/tree/fs.js";
24
+ import { SUBSYSTEM_MARKER } from "../../core/repo/tree/marker.js";
25
+ import { planWrite } from "../../core/staging/writes.js";
26
+ import { commitWindow, reportViews } from "./txn/txn.js";
27
+ /** `subsystem new <name> [--under <parent>] [--title …] [--description …] [--owner …]` */
28
+ export async function runNew(docsDir, name, opts, json) {
29
+ const parsed = parseSubsystemName(name, "subsystem name");
30
+ if (!parsed.ok) {
31
+ fail(json, "invalid-option", parsed.problem);
32
+ return;
33
+ }
34
+ await commitWindow(docsDir, json, async (tree) => {
35
+ // The flat namespace: one name, one meaning, at any depth — a `new` that
36
+ // collides with ANY service or subsystem would be the exact state
37
+ // `subsystem.name-collision` refuses after the fact.
38
+ const taken = findInTree(tree, name);
39
+ if (taken !== null) {
40
+ const where = taken.kind === "service" ? taken.service.dir : taken.subsystem.dir;
41
+ fail(json, "already-exists", `'${name}' is already a ${taken.kind} (${repoPath(docsDir, where)}) — ` +
42
+ `service ids and subsystem names share one flat namespace, unique at any depth. Pick another name.`);
43
+ return null;
44
+ }
45
+ let parentDir = servicesDir(docsDir);
46
+ let parentPath = [];
47
+ if (opts.under !== undefined) {
48
+ const parent = findInTree(tree, opts.under);
49
+ if (parent === null) {
50
+ fail(json, "unknown-target", `No subsystem '${opts.under}' in the tree.` +
51
+ closeNamesHint(opts.under, tree.subsystems.map((s) => s.name), " `loam subsystem list` shows what exists."));
52
+ return null;
53
+ }
54
+ if (parent.kind === "service") {
55
+ fail(json, "invalid-option", `--under names the service '${opts.under}' — a service never contains subsystems.`);
56
+ return null;
57
+ }
58
+ parentDir = parent.subsystem.dir;
59
+ parentPath = parent.subsystem.path;
60
+ }
61
+ const dir = subsystemPathUnder(parentDir, parsed.name);
62
+ // The flat-namespace check above compares exact strings; the FILESYSTEM
63
+ // may not. On a case-folding volume (macOS APFS by default) `Billing`
64
+ // and an existing `services/billing` are one directory, so the marker
65
+ // write below would land subsystem.yaml INSIDE the live service — the
66
+ // exact marker-beside-artifacts state `subsystem.marker-misplaced`
67
+ // refuses after the fact, created by a blessed command. A plain file of
68
+ // the same name reaches here too (files at the root are not walked). So
69
+ // the disk is probed directly and anything already there refuses closed.
70
+ if (existsSync(dir)) {
71
+ fail(json, "already-exists", `${repoPath(docsDir, dir)} already exists on disk — the tree resolves no entry by that exact name, ` +
72
+ `so either this filesystem folds case (the directory answers to another spelling of the name) ` +
73
+ `or something non-loam created it. Pick another name, or move what is there first. Nothing was created.`);
74
+ return null;
75
+ }
76
+ const meta = {
77
+ ...(opts.title === undefined ? {} : { title: opts.title }),
78
+ ...(opts.description === undefined ? {} : { description: opts.description }),
79
+ ...(opts.owner === undefined ? {} : { owner: opts.owner }),
80
+ };
81
+ // An empty file is a valid marker — presence classifies, content is metadata.
82
+ const marker = Object.keys(meta).length === 0 ? "" : stringify(meta);
83
+ const after = {
84
+ ...tree,
85
+ subsystems: [...tree.subsystems, { name, path: [...parentPath, name], dir, meta }],
86
+ };
87
+ return {
88
+ target: name,
89
+ writes: [planWrite(join(dir, SUBSYSTEM_MARKER), marker)],
90
+ tree: after,
91
+ // A lost exclusive-create race on the marker IS the name being taken.
92
+ racedCode: "already-exists",
93
+ what: "created",
94
+ report: (views, recovered) => {
95
+ if (json) {
96
+ emitJson({
97
+ command: "subsystem",
98
+ created: name,
99
+ path: repoPath(docsDir, dir),
100
+ views: views.subsystems,
101
+ serviceViews: views.services,
102
+ ...(recovered === null ? {} : { recovered }),
103
+ });
104
+ return;
105
+ }
106
+ console.log(`created ${repoPath(docsDir, dir)}/ (${SUBSYSTEM_MARKER} written)${reportViews(views)}`);
107
+ },
108
+ };
109
+ });
110
+ }
111
+ /** `subsystem rm <name>` — refuses anything but an empty group. */
112
+ export async function runRm(docsDir, name, json) {
113
+ await commitWindow(docsDir, json, async (tree) => {
114
+ const hit = findInTree(tree, name);
115
+ if (hit === null) {
116
+ fail(json, "unknown-target", `No subsystem '${name}' in the tree.` +
117
+ closeNamesHint(name, tree.subsystems.map((s) => s.name), " `loam subsystem list` shows what exists."));
118
+ return null;
119
+ }
120
+ if (hit.kind === "service") {
121
+ fail(json, "invalid-option", `'${name}' is a service, not a subsystem — loam does not delete services (\`git rm -r ${repoPath(docsDir, hit.service.dir)}\` does, and version control keeps the record).`);
122
+ return null;
123
+ }
124
+ const sub = hit.subsystem;
125
+ const services = servicesUnder(tree, sub).map((s) => s.id);
126
+ const children = subsystemsUnder(tree, sub).map((s) => s.name);
127
+ // Stray entries beside the marker count as members too: after the marker
128
+ // is gone the directory would re-enter the walk as an empty "service" the
129
+ // moment anything keeps rmdir from removing it. But only entries the tree
130
+ // has NOT already counted — a member service or child subsystem is also a
131
+ // readdir entry here, and listing it a second time as "file X" made the
132
+ // count wrong and the same name appear under two kinds. What remains is
133
+ // discriminated by what it is (`entryIs`, the walk's own symlink-aware
134
+ // question): a file, or a directory the tree does not claim (an unmarked
135
+ // group, already its own `subsystem.unmarked` finding).
136
+ const counted = new Set([
137
+ ...servicesUnder(tree, sub).filter((s) => s.subsystem.length === sub.path.length).map((s) => s.id),
138
+ ...subsystemsUnder(tree, sub).filter((c) => c.path.length === sub.path.length + 1).map((c) => c.name),
139
+ ]);
140
+ const strays = (await readdir(sub.dir, { withFileTypes: true }))
141
+ .filter((e) => !e.name.startsWith(".") && e.name !== SUBSYSTEM_MARKER && !counted.has(e.name))
142
+ .map((e) => `${entryIs(sub.dir, e, "dir") ? "directory" : "file"} ${e.name}`);
143
+ const members = [
144
+ ...services.map((s) => `service ${s}`),
145
+ ...children.map((c) => `subsystem ${c}`),
146
+ ...strays,
147
+ ];
148
+ if (members.length > 0) {
149
+ fail(json, "subsystem-not-empty", `'${name}' still holds ${members.length} member(s): ${members.join(", ")}. ` +
150
+ "`loam subsystem move <name>... --into <sub|.>` moves them out; a destructive command never picks targets you did not name.");
151
+ return null;
152
+ }
153
+ const after = { ...tree, subsystems: tree.subsystems.filter((s) => s !== sub) };
154
+ return {
155
+ target: name,
156
+ writes: [{ path: join(sub.dir, SUBSYSTEM_MARKER), content: null }],
157
+ tree: after,
158
+ what: "removed",
159
+ report: async (views, recovered) => {
160
+ // The directory itself, after the transaction: the marker is gone, the
161
+ // group was verifiably empty, and an empty marker-less directory would
162
+ // read as an unfiled service. Dotfile litter (.DS_Store) can still
163
+ // defeat rmdir — reported, not swallowed.
164
+ let directoryRemoved = true;
165
+ try {
166
+ await rmdir(sub.dir);
167
+ }
168
+ catch {
169
+ directoryRemoved = !existsSync(sub.dir);
170
+ }
171
+ if (json) {
172
+ emitJson({
173
+ command: "subsystem",
174
+ removed: name,
175
+ path: repoPath(docsDir, sub.dir),
176
+ directoryRemoved,
177
+ views: views.subsystems,
178
+ serviceViews: views.services,
179
+ ...(recovered === null ? {} : { recovered }),
180
+ });
181
+ return;
182
+ }
183
+ console.log(`removed subsystem '${name}' (${repoPath(docsDir, sub.dir)}/)${reportViews(views)}`);
184
+ if (!directoryRemoved) {
185
+ console.log(`note: the directory itself could not be removed (something non-loam is still inside) — ` +
186
+ `until it is deleted by hand it will list as an empty unfiled service.`);
187
+ }
188
+ },
189
+ };
190
+ });
191
+ }
192
+ //# sourceMappingURL=edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/commands/subsystem/edit.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The two verbs that create and remove GROUPS: `subsystem new` and\n * `subsystem rm`. Both commit the marker AND the regenerated views file in\n * one journaled transaction, because a marker without its view (or a view\n * outliving its marker) is exactly the `subsystem.views-stale` state the\n * generated file's contract refuses to leave behind.\n *\n * `rm` refuses a subsystem with members — services, child subsystems, or any\n * stray non-dot entry beside the marker the tree does not already count —\n * naming each once, as what it is (`subsystem-not-empty`):\n * a destructive command never picks targets the caller did not name, and a\n * directory emptied of its marker but not of its contents would re-enter the\n * walk as a phantom service.\n */\nimport { existsSync } from \"node:fs\";\nimport { readdir, rmdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { stringify } from \"yaml\";\nimport type { DocsDir } from \"../../core/kernel/ids/dirs.js\";\nimport { parseSubsystemName } from \"../../core/kernel/ids/subsystem.js\";\nimport { emitJson, fail, repoPath } from \"../../core/envelope/json.js\";\nimport { servicesDir, subsystemPathUnder } from \"../../core/repo/paths.js\";\nimport { closeNamesHint, findInTree, servicesUnder, subsystemsUnder } from \"../../core/repo/tree/find.js\";\nimport { entryIs } from \"../../core/repo/tree/fs.js\";\nimport { SUBSYSTEM_MARKER } from \"../../core/repo/tree/marker.js\";\nimport type { FleetTree } from \"../../core/repo/tree/walk.js\";\nimport { planWrite } from \"../../core/staging/writes.js\";\nimport { commitWindow, reportViews, type SubsystemTxn } from \"./txn/txn.js\";\nimport type { SubsystemOptions } from \"./subsystem.js\";\n\n/** `subsystem new <name> [--under <parent>] [--title …] [--description …] [--owner …]` */\nexport async function runNew(\n docsDir: DocsDir,\n name: string,\n opts: SubsystemOptions,\n json: boolean,\n): Promise<void> {\n const parsed = parseSubsystemName(name, \"subsystem name\");\n if (!parsed.ok) {\n fail(json, \"invalid-option\", parsed.problem);\n return;\n }\n await commitWindow(docsDir, json, async (tree): Promise<SubsystemTxn | null> => {\n // The flat namespace: one name, one meaning, at any depth — a `new` that\n // collides with ANY service or subsystem would be the exact state\n // `subsystem.name-collision` refuses after the fact.\n const taken = findInTree(tree, name);\n if (taken !== null) {\n const where = taken.kind === \"service\" ? taken.service.dir : taken.subsystem.dir;\n fail(\n json,\n \"already-exists\",\n `'${name}' is already a ${taken.kind} (${repoPath(docsDir, where)}) — ` +\n `service ids and subsystem names share one flat namespace, unique at any depth. Pick another name.`,\n );\n return null;\n }\n let parentDir = servicesDir(docsDir);\n let parentPath: string[] = [];\n if (opts.under !== undefined) {\n const parent = findInTree(tree, opts.under);\n if (parent === null) {\n fail(\n json,\n \"unknown-target\",\n `No subsystem '${opts.under}' in the tree.` +\n closeNamesHint(opts.under, tree.subsystems.map((s) => s.name), \" `loam subsystem list` shows what exists.\"),\n );\n return null;\n }\n if (parent.kind === \"service\") {\n fail(json, \"invalid-option\", `--under names the service '${opts.under}' — a service never contains subsystems.`);\n return null;\n }\n parentDir = parent.subsystem.dir;\n parentPath = parent.subsystem.path;\n }\n const dir = subsystemPathUnder(parentDir, parsed.name);\n // The flat-namespace check above compares exact strings; the FILESYSTEM\n // may not. On a case-folding volume (macOS APFS by default) `Billing`\n // and an existing `services/billing` are one directory, so the marker\n // write below would land subsystem.yaml INSIDE the live service — the\n // exact marker-beside-artifacts state `subsystem.marker-misplaced`\n // refuses after the fact, created by a blessed command. A plain file of\n // the same name reaches here too (files at the root are not walked). So\n // the disk is probed directly and anything already there refuses closed.\n if (existsSync(dir)) {\n fail(\n json,\n \"already-exists\",\n `${repoPath(docsDir, dir)} already exists on disk — the tree resolves no entry by that exact name, ` +\n `so either this filesystem folds case (the directory answers to another spelling of the name) ` +\n `or something non-loam created it. Pick another name, or move what is there first. Nothing was created.`,\n );\n return null;\n }\n const meta = {\n ...(opts.title === undefined ? {} : { title: opts.title }),\n ...(opts.description === undefined ? {} : { description: opts.description }),\n ...(opts.owner === undefined ? {} : { owner: opts.owner }),\n };\n // An empty file is a valid marker — presence classifies, content is metadata.\n const marker = Object.keys(meta).length === 0 ? \"\" : stringify(meta);\n const after: FleetTree = {\n ...tree,\n subsystems: [...tree.subsystems, { name, path: [...parentPath, name], dir, meta }],\n };\n return {\n target: name,\n writes: [planWrite(join(dir, SUBSYSTEM_MARKER), marker)],\n tree: after,\n // A lost exclusive-create race on the marker IS the name being taken.\n racedCode: \"already-exists\",\n what: \"created\",\n report: (views, recovered) => {\n if (json) {\n emitJson({\n command: \"subsystem\",\n created: name,\n path: repoPath(docsDir, dir),\n views: views.subsystems,\n serviceViews: views.services,\n ...(recovered === null ? {} : { recovered }),\n });\n return;\n }\n console.log(`created ${repoPath(docsDir, dir)}/ (${SUBSYSTEM_MARKER} written)${reportViews(views)}`);\n },\n };\n });\n}\n\n/** `subsystem rm <name>` — refuses anything but an empty group. */\nexport async function runRm(docsDir: DocsDir, name: string, json: boolean): Promise<void> {\n await commitWindow(docsDir, json, async (tree): Promise<SubsystemTxn | null> => {\n const hit = findInTree(tree, name);\n if (hit === null) {\n fail(\n json,\n \"unknown-target\",\n `No subsystem '${name}' in the tree.` +\n closeNamesHint(name, tree.subsystems.map((s) => s.name), \" `loam subsystem list` shows what exists.\"),\n );\n return null;\n }\n if (hit.kind === \"service\") {\n fail(\n json,\n \"invalid-option\",\n `'${name}' is a service, not a subsystem — loam does not delete services (\\`git rm -r ${repoPath(docsDir, hit.service.dir)}\\` does, and version control keeps the record).`,\n );\n return null;\n }\n const sub = hit.subsystem;\n const services = servicesUnder(tree, sub).map((s) => s.id);\n const children = subsystemsUnder(tree, sub).map((s) => s.name);\n // Stray entries beside the marker count as members too: after the marker\n // is gone the directory would re-enter the walk as an empty \"service\" the\n // moment anything keeps rmdir from removing it. But only entries the tree\n // has NOT already counted — a member service or child subsystem is also a\n // readdir entry here, and listing it a second time as \"file X\" made the\n // count wrong and the same name appear under two kinds. What remains is\n // discriminated by what it is (`entryIs`, the walk's own symlink-aware\n // question): a file, or a directory the tree does not claim (an unmarked\n // group, already its own `subsystem.unmarked` finding).\n const counted = new Set<string>([\n ...servicesUnder(tree, sub).filter((s) => s.subsystem.length === sub.path.length).map((s) => s.id as string),\n ...subsystemsUnder(tree, sub).filter((c) => c.path.length === sub.path.length + 1).map((c) => c.name),\n ]);\n const strays = (await readdir(sub.dir, { withFileTypes: true }))\n .filter((e) => !e.name.startsWith(\".\") && e.name !== SUBSYSTEM_MARKER && !counted.has(e.name))\n .map((e) => `${entryIs(sub.dir, e, \"dir\") ? \"directory\" : \"file\"} ${e.name}`);\n const members = [\n ...services.map((s) => `service ${s}`),\n ...children.map((c) => `subsystem ${c}`),\n ...strays,\n ];\n if (members.length > 0) {\n fail(\n json,\n \"subsystem-not-empty\",\n `'${name}' still holds ${members.length} member(s): ${members.join(\", \")}. ` +\n \"`loam subsystem move <name>... --into <sub|.>` moves them out; a destructive command never picks targets you did not name.\",\n );\n return null;\n }\n const after: FleetTree = { ...tree, subsystems: tree.subsystems.filter((s) => s !== sub) };\n return {\n target: name,\n writes: [{ path: join(sub.dir, SUBSYSTEM_MARKER), content: null }],\n tree: after,\n what: \"removed\",\n report: async (views, recovered) => {\n // The directory itself, after the transaction: the marker is gone, the\n // group was verifiably empty, and an empty marker-less directory would\n // read as an unfiled service. Dotfile litter (.DS_Store) can still\n // defeat rmdir — reported, not swallowed.\n let directoryRemoved = true;\n try {\n await rmdir(sub.dir);\n } catch {\n directoryRemoved = !existsSync(sub.dir);\n }\n if (json) {\n emitJson({\n command: \"subsystem\",\n removed: name,\n path: repoPath(docsDir, sub.dir),\n directoryRemoved,\n views: views.subsystems,\n serviceViews: views.services,\n ...(recovered === null ? {} : { recovered }),\n });\n return;\n }\n console.log(`removed subsystem '${name}' (${repoPath(docsDir, sub.dir)}/)${reportViews(views)}`);\n if (!directoryRemoved) {\n console.log(\n `note: the directory itself could not be removed (something non-loam is still inside) — ` +\n `until it is deleted by hand it will list as an empty unfiled service.`,\n );\n }\n },\n };\n });\n}\n"]}