@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,255 @@
1
+ /**
2
+ * The tree read model: three-way classification of everything under
3
+ * `services/`, in one walk.
4
+ *
5
+ * A directory holding `subsystem.yaml` is a SUBSYSTEM and is walked; one
6
+ * holding any service artifact is a SERVICE and is not walked deeper — unless
7
+ * a marker sits BESIDE the artifacts, where the walk descends anyway (the
8
+ * marker says a group was here, and its members must not vanish); one holding
9
+ * neither while containing subdirectories is an ERROR that still names every
10
+ * service found beneath it. The third branch is the whole point:
11
+ * two-way classification loses a service silently on an ordinary clean merge —
12
+ * one branch deletes an emptied subsystem's marker while another moves a
13
+ * service into it, and the group directory is then read as a service whose
14
+ * real services vanish from the fleet with no finding. No directory under
15
+ * `services/` may ever be reinterpreted as a different kind without saying so,
16
+ * and the fleet is never reported smaller: the walk descends into the broken
17
+ * group precisely so the stranded services stay enumerated and named.
18
+ *
19
+ * The package direction is `repo → repo/tree`, never back. That is why the
20
+ * artifact-name question arrives INJECTED (`TreeWalkRequest.isServiceArtifact`
21
+ * — `repo/paths.ts` owns the spellings and `repo/repo.ts` builds the request):
22
+ * importing `paths.ts` from here while `repo.ts` delegates its enumeration to
23
+ * this walk would close the exact package cycle `scripts/package-graph.mjs`
24
+ * exists to refuse.
25
+ *
26
+ * A SERVICE'S OWN SUBDIRECTORIES ARE NEVER CLASSIFIED (`RESERVED_INTERIOR`).
27
+ * That is a different question from `isServiceArtifact`, which asks whether a
28
+ * name makes the directory holding it a service; this asks whether a child
29
+ * directory may be READ as one at all, and the two answers diverged the moment
30
+ * SCHEMA's service layout grew a slot the artifact table does not carry. A
31
+ * `services/<svc>/` holding only the documented `usecases/` flow directory was
32
+ * classified as a group: the walk descended, filed `usecases` as a service, and
33
+ * one `loam validate --all` reported `subsystem.unmarked`,
34
+ * `landscape.service-unmodelled` for `services/<svc>/usecases/` and
35
+ * `landscape.binding-unknown` for the real service — three errors whose text
36
+ * says the fleet is losing services, earned by following the instruction `loam
37
+ * init` had just scaffolded (verification 2026-09-04). The names are SCHEMA's
38
+ * service layout, and a directory named for one is service interior wherever it
39
+ * sits, so no branch of the classification descends into one.
40
+ *
41
+ * Cost: exactly one readdir per directory walked, service directories included
42
+ * (their own listing is what classifies them), plus one realpath per directory
43
+ * for the symlink-cycle guard — `entryIs` follows symlinks on purpose, and a
44
+ * followed cycle without the visited-set is an unbounded recursion.
45
+ */
46
+ import { readdir } from "node:fs/promises";
47
+ import { join } from "node:path";
48
+ import { serviceDirOf, serviceTreePath } from "../../kernel/ids/dirs.js";
49
+ import { rawServiceId } from "../../kernel/ids/service.js";
50
+ import { subsystemNameProblem } from "../../kernel/ids/subsystem.js";
51
+ import { entryIs, markDescended, subdirNames } from "./fs.js";
52
+ import { readSubsystemMarker, SUBSYSTEM_MARKER } from "./marker.js";
53
+ /**
54
+ * The subdirectory names SCHEMA's service layout reserves for a service's own
55
+ * interior (`SCHEMA.md`, "services/<svc>/"): `adrs/` the decisions, `usecases/`
56
+ * the flows drawn over its containers, `ui/` the page-specs. A directory with
57
+ * one of these names is never a service and never a subsystem — it is inside
58
+ * one — so the walk neither classifies it nor counts it as a subdirectory that
59
+ * makes its parent a group.
60
+ *
61
+ * Kept here rather than folded into `isServiceArtifact` because the two
62
+ * questions are not the same one: `adrs/` answers both (it is an artifact AND
63
+ * interior) and `usecases/` answers only this one today. Widening the injected
64
+ * artifact table instead would also make a lone `usecases/` classify its parent
65
+ * as a service by ARTIFACT, which hides a real service filed beside it — the
66
+ * silent shrink this module refuses.
67
+ *
68
+ * Exported for the one other reader of this rule: `core/diff/base-state.ts`
69
+ * classifies a base git ref's tree listing, which no walk can readdir, and its
70
+ * banner already commits it to restating this module's branches rather than
71
+ * inventing its own. It shares the SET for the reason it shares the artifact
72
+ * table — a name respelled there is the drift both modules are written to
73
+ * avoid.
74
+ */
75
+ export const RESERVED_INTERIOR = new Set(["adrs", "usecases", "ui"]);
76
+ export async function walkServicesTree(request) {
77
+ const ctx = {
78
+ request,
79
+ tree: { services: [], subsystems: [], findings: [] },
80
+ visited: new Set(),
81
+ names: new Map(),
82
+ };
83
+ const root = join(request.docsDir, "services");
84
+ markDescended(root, ctx.visited);
85
+ for (const name of await subdirNames(root)) {
86
+ await visitDir({ dir: join(root, name), name, chain: [] }, ctx);
87
+ }
88
+ namespaceFindings(ctx);
89
+ return ctx.tree;
90
+ }
91
+ /** Classify one directory and, for the group kinds, walk what is inside it. */
92
+ async function visitDir(spot, ctx) {
93
+ const rel = ["services", ...spot.chain, spot.name].join("/");
94
+ const entries = (await readdir(spot.dir, { withFileTypes: true })).filter((e) => !e.name.startsWith("."));
95
+ const files = entries.filter((e) => entryIs(spot.dir, e, "file")).map((e) => e.name);
96
+ const all = entries.filter((e) => entryIs(spot.dir, e, "dir")).map((e) => e.name).sort();
97
+ // The classifiable children — a service's own interior removed once, here, so
98
+ // every branch below agrees about it (see `RESERVED_INTERIOR`). `all` is still
99
+ // what the artifact probe reads: `adrs/` makes its parent a service, and
100
+ // `usecases/` is interior the parent may hold without becoming a group.
101
+ const dirs = all.filter((d) => !RESERVED_INTERIOR.has(d));
102
+ const marker = files.includes(SUBSYSTEM_MARKER);
103
+ const artifact = files.some((f) => ctx.request.isServiceArtifact(f, "file")) ||
104
+ all.some((d) => ctx.request.isServiceArtifact(d, "dir"));
105
+ if (marker && artifact) {
106
+ // Artifacts win the classification: the documents are somebody's work and
107
+ // the marker is one stray file, so the directory stays an addressable
108
+ // service and the finding names the contradiction instead of the walk
109
+ // quietly picking a reading. But the walk STILL descends (the module
110
+ // invariant: no reinterpretation may shrink the fleet) — the marker says
111
+ // a GROUP was here, and returning without walking made every service
112
+ // beneath it vanish with only this finding to hint why. Child directories
113
+ // that are themselves artifacts (`adrs/`) are service interior, not walked.
114
+ recordService(spot, ctx);
115
+ const stranded = await descendInto(spot, dirs.filter((d) => !ctx.request.isServiceArtifact(d, "dir")), ctx);
116
+ ctx.tree.findings.push({
117
+ severity: "error",
118
+ code: "subsystem.marker-misplaced",
119
+ subject: spot.name,
120
+ message: `${rel}/ holds ${SUBSYSTEM_MARKER} BESIDE service artifacts — a directory is a subsystem or a service, never both. ` +
121
+ `It stays classified as a service; delete ${rel}/${SUBSYSTEM_MARKER}, ` +
122
+ `or move the artifacts into a service directory of their own inside the group.` +
123
+ (stranded.length > 0 ? ` ${stranded.length} service(s) beneath it stay enumerated meanwhile: ${stranded.map((s) => s.id).join(", ")}.` : ""),
124
+ ...(stranded.length > 0 ? { details: stranded.map(serviceTreePath) } : {}),
125
+ });
126
+ return;
127
+ }
128
+ if (marker) {
129
+ await visitSubsystem(spot, { rel, dirs }, ctx);
130
+ return;
131
+ }
132
+ if (artifact) {
133
+ recordService(spot, ctx);
134
+ return;
135
+ }
136
+ if (dirs.length > 0) {
137
+ await visitUnmarked(spot, { rel, dirs }, ctx);
138
+ return;
139
+ }
140
+ // Neither marker nor artifact, and nothing beneath: today's flat behaviour —
141
+ // an empty (or not-yet-adopted) directory under services/ is a service.
142
+ recordService(spot, ctx);
143
+ }
144
+ function recordService(spot, ctx) {
145
+ ctx.tree.services.push({
146
+ id: rawServiceId(spot.name),
147
+ dir: serviceDirOf(spot.dir),
148
+ subsystem: spot.chain,
149
+ });
150
+ claimName(spot, ctx);
151
+ }
152
+ /** A subsystem: record it, report a broken marker or an illegal name, walk in. */
153
+ async function visitSubsystem(spot, at, ctx) {
154
+ const meta = await readSubsystemMarker(join(spot.dir, SUBSYSTEM_MARKER));
155
+ if (meta.invalid !== undefined) {
156
+ // Exactly one finding per marker file: presence already classified the
157
+ // directory, so the content failure is metadata, not identity.
158
+ ctx.tree.findings.push({
159
+ severity: "error",
160
+ code: "subsystem.invalid",
161
+ subject: at.rel,
162
+ message: `${at.rel}/${SUBSYSTEM_MARKER} cannot be read as subsystem metadata — ${meta.invalid}. ` +
163
+ `The directory still counts as a subsystem (presence classifies; content is metadata). ` +
164
+ `Fix the file: a YAML mapping with optional title, description and owner — an empty file is also a valid marker.`,
165
+ });
166
+ }
167
+ const problem = subsystemNameProblem(spot.name, "subsystem directory name");
168
+ if (problem !== null) {
169
+ // Walked anyway, mirroring how an illegal service id stays enumerated
170
+ // (`idProblem`): the directory exists and hiding its subtree would shrink
171
+ // the fleet over a naming mistake.
172
+ ctx.tree.findings.push({
173
+ severity: "error",
174
+ code: "subsystem.name-invalid",
175
+ subject: spot.name,
176
+ message: `${at.rel}/ — ${problem} Rename the directory; its services stay enumerated meanwhile.`,
177
+ });
178
+ }
179
+ ctx.tree.subsystems.push({
180
+ name: spot.name,
181
+ path: [...spot.chain, spot.name],
182
+ dir: spot.dir,
183
+ meta,
184
+ });
185
+ claimName(spot, ctx);
186
+ await descendInto(spot, at.dirs, ctx);
187
+ }
188
+ /**
189
+ * Walk the children of a group directory (symlink-cycle guarded), returning
190
+ * the services newly recorded beneath it — the ONE spelling of descent, so
191
+ * the three descending branches agree about the guard and the chain.
192
+ */
193
+ async function descendInto(spot, dirs, ctx) {
194
+ const before = ctx.tree.services.length;
195
+ // The guard (`./fs.ts`'s `markDescended`) protects SUBTREES, not entries: a
196
+ // directory reachable under two names is classified twice — both names
197
+ // exist and hiding the second would be the silent shrink this module
198
+ // refuses — but its children are enumerated once, so a symlink cycle
199
+ // terminates instead of recursing forever.
200
+ if (markDescended(spot.dir, ctx.visited)) {
201
+ for (const child of dirs) {
202
+ await visitDir({ dir: join(spot.dir, child), name: child, chain: [...spot.chain, spot.name] }, ctx);
203
+ }
204
+ }
205
+ return ctx.tree.services.slice(before);
206
+ }
207
+ /**
208
+ * The refusal branch — a group directory nothing marks. The walk STILL
209
+ * descends, so the services beneath stay in the enumeration and the finding
210
+ * can name them: the fleet must never be reported smaller than it is.
211
+ */
212
+ async function visitUnmarked(spot, at, ctx) {
213
+ const stranded = await descendInto(spot, at.dirs, ctx);
214
+ ctx.tree.findings.push({
215
+ severity: "error",
216
+ code: "subsystem.unmarked",
217
+ subject: at.rel,
218
+ message: `${at.rel}/ is neither a subsystem (no ${SUBSYSTEM_MARKER}) nor a service (no service artifact), ` +
219
+ `but ${stranded.length} service(s) sit beneath it` +
220
+ (stranded.length > 0 ? `: ${stranded.map((s) => s.id).join(", ")}. ` : `. `) +
221
+ `Without the marker this directory would be read as a service and everything under it would vanish from the fleet — ` +
222
+ `the shape an ordinary merge produces when one branch deletes an emptied subsystem's marker while another moves a service in. ` +
223
+ `Restore ${at.rel}/${SUBSYSTEM_MARKER} (an empty file is a valid marker), or move the directories out.`,
224
+ ...(stranded.length > 0 ? { details: stranded.map(serviceTreePath) } : {}),
225
+ });
226
+ }
227
+ function claimName(spot, ctx) {
228
+ const rel = ["services", ...spot.chain, spot.name].join("/");
229
+ ctx.names.set(spot.name, [...(ctx.names.get(spot.name) ?? []), rel]);
230
+ }
231
+ /**
232
+ * One flat namespace: every subsystem name and service id, unique across the
233
+ * whole tree at any depth, never colliding with each other. The identity
234
+ * decision demands it — a service id is its leaf directory name ALONE, so two
235
+ * leaves spelling one name are one identity claimed twice, wherever they sit.
236
+ * One finding per name, naming every claimant, so the fix is a choice rather
237
+ * than a scavenger hunt.
238
+ */
239
+ function namespaceFindings(ctx) {
240
+ for (const [name, dirs] of [...ctx.names].sort(([a], [b]) => (a < b ? -1 : 1))) {
241
+ if (dirs.length < 2)
242
+ continue;
243
+ ctx.tree.findings.push({
244
+ severity: "error",
245
+ code: "subsystem.name-collision",
246
+ subject: name,
247
+ message: `'${name}' is claimed by ${dirs.length} directories in the services/ tree: ${dirs.join(", ")} — ` +
248
+ `service ids and subsystem names share one flat namespace, unique at any depth, ` +
249
+ `because a service's identity is its leaf directory name alone and placement never disambiguates it. ` +
250
+ `Rename all but one.`,
251
+ details: dirs,
252
+ });
253
+ }
254
+ }
255
+ //# sourceMappingURL=walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.js","sourceRoot":"","sources":["../../../../src/core/repo/tree/walk.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The tree read model: three-way classification of everything under\n * `services/`, in one walk.\n *\n * A directory holding `subsystem.yaml` is a SUBSYSTEM and is walked; one\n * holding any service artifact is a SERVICE and is not walked deeper — unless\n * a marker sits BESIDE the artifacts, where the walk descends anyway (the\n * marker says a group was here, and its members must not vanish); one holding\n * neither while containing subdirectories is an ERROR that still names every\n * service found beneath it. The third branch is the whole point:\n * two-way classification loses a service silently on an ordinary clean merge —\n * one branch deletes an emptied subsystem's marker while another moves a\n * service into it, and the group directory is then read as a service whose\n * real services vanish from the fleet with no finding. No directory under\n * `services/` may ever be reinterpreted as a different kind without saying so,\n * and the fleet is never reported smaller: the walk descends into the broken\n * group precisely so the stranded services stay enumerated and named.\n *\n * The package direction is `repo → repo/tree`, never back. That is why the\n * artifact-name question arrives INJECTED (`TreeWalkRequest.isServiceArtifact`\n * — `repo/paths.ts` owns the spellings and `repo/repo.ts` builds the request):\n * importing `paths.ts` from here while `repo.ts` delegates its enumeration to\n * this walk would close the exact package cycle `scripts/package-graph.mjs`\n * exists to refuse.\n *\n * A SERVICE'S OWN SUBDIRECTORIES ARE NEVER CLASSIFIED (`RESERVED_INTERIOR`).\n * That is a different question from `isServiceArtifact`, which asks whether a\n * name makes the directory holding it a service; this asks whether a child\n * directory may be READ as one at all, and the two answers diverged the moment\n * SCHEMA's service layout grew a slot the artifact table does not carry. A\n * `services/<svc>/` holding only the documented `usecases/` flow directory was\n * classified as a group: the walk descended, filed `usecases` as a service, and\n * one `loam validate --all` reported `subsystem.unmarked`,\n * `landscape.service-unmodelled` for `services/<svc>/usecases/` and\n * `landscape.binding-unknown` for the real service — three errors whose text\n * says the fleet is losing services, earned by following the instruction `loam\n * init` had just scaffolded (verification 2026-09-04). The names are SCHEMA's\n * service layout, and a directory named for one is service interior wherever it\n * sits, so no branch of the classification descends into one.\n *\n * Cost: exactly one readdir per directory walked, service directories included\n * (their own listing is what classifies them), plus one realpath per directory\n * for the symlink-cycle guard — `entryIs` follows symlinks on purpose, and a\n * followed cycle without the visited-set is an unbounded recursion.\n */\nimport { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { serviceDirOf, serviceTreePath, type DocsDir, type ServiceDir } from \"../../kernel/ids/dirs.js\";\nimport { rawServiceId, type RawServiceId } from \"../../kernel/ids/service.js\";\nimport { subsystemNameProblem } from \"../../kernel/ids/subsystem.js\";\nimport type { Finding } from \"../../vocabulary/report.js\";\nimport { entryIs, markDescended, subdirNames } from \"./fs.js\";\nimport { readSubsystemMarker, SUBSYSTEM_MARKER, type SubsystemMeta } from \"./marker.js\";\n\n/**\n * The subdirectory names SCHEMA's service layout reserves for a service's own\n * interior (`SCHEMA.md`, \"services/<svc>/\"): `adrs/` the decisions, `usecases/`\n * the flows drawn over its containers, `ui/` the page-specs. A directory with\n * one of these names is never a service and never a subsystem — it is inside\n * one — so the walk neither classifies it nor counts it as a subdirectory that\n * makes its parent a group.\n *\n * Kept here rather than folded into `isServiceArtifact` because the two\n * questions are not the same one: `adrs/` answers both (it is an artifact AND\n * interior) and `usecases/` answers only this one today. Widening the injected\n * artifact table instead would also make a lone `usecases/` classify its parent\n * as a service by ARTIFACT, which hides a real service filed beside it — the\n * silent shrink this module refuses.\n *\n * Exported for the one other reader of this rule: `core/diff/base-state.ts`\n * classifies a base git ref's tree listing, which no walk can readdir, and its\n * banner already commits it to restating this module's branches rather than\n * inventing its own. It shares the SET for the reason it shares the artifact\n * table — a name respelled there is the drift both modules are written to\n * avoid.\n */\nexport const RESERVED_INTERIOR: ReadonlySet<string> = new Set([\"adrs\", \"usecases\", \"ui\"]);\n\nexport interface WalkedService {\n id: RawServiceId;\n dir: ServiceDir;\n /**\n * Names of the directories between `services/` and the service, outermost\n * first. Empty = unfiled — directly under `services/`, which is permanent,\n * normal and SILENT. For a service stranded under an unmarked group the\n * chain still records the physical placement: the path is a fact even while\n * `subsystem.unmarked` says the grouping is broken.\n */\n subsystem: string[];\n}\n\nexport interface SubsystemEntry {\n /** The directory name — the subsystem's name in the flat namespace. */\n name: string;\n /** Names from `services/` down to and including this one. */\n path: string[];\n /** Absolute path of the subsystem directory. */\n dir: string;\n meta: SubsystemMeta;\n}\n\nexport interface FleetTree {\n services: WalkedService[];\n subsystems: SubsystemEntry[];\n findings: Finding[];\n}\n\nexport interface TreeWalkRequest {\n docsDir: DocsDir;\n /** Does this entry name a service artifact? `repo/paths.ts`'s table, injected — the module doc says why. */\n isServiceArtifact: (name: string, kind: \"file\" | \"dir\") => boolean;\n}\n\ninterface WalkContext {\n request: TreeWalkRequest;\n tree: FleetTree;\n /** Realpaths already DESCENDED into — the symlink-cycle guard. */\n visited: Set<string>;\n /** Every name in the flat namespace → the directories that claim it. */\n names: Map<string, string[]>;\n}\n\n/** One directory the walk is looking at: where it is, and how it is reached. */\ninterface Spot {\n dir: string;\n name: string;\n /** Directory names between `services/` and this one, outermost first. */\n chain: string[];\n}\n\nexport async function walkServicesTree(request: TreeWalkRequest): Promise<FleetTree> {\n const ctx: WalkContext = {\n request,\n tree: { services: [], subsystems: [], findings: [] },\n visited: new Set(),\n names: new Map(),\n };\n const root = join(request.docsDir, \"services\");\n markDescended(root, ctx.visited);\n for (const name of await subdirNames(root)) {\n await visitDir({ dir: join(root, name), name, chain: [] }, ctx);\n }\n namespaceFindings(ctx);\n return ctx.tree;\n}\n\n/** Classify one directory and, for the group kinds, walk what is inside it. */\nasync function visitDir(spot: Spot, ctx: WalkContext): Promise<void> {\n const rel = [\"services\", ...spot.chain, spot.name].join(\"/\");\n const entries = (await readdir(spot.dir, { withFileTypes: true })).filter((e) => !e.name.startsWith(\".\"));\n const files = entries.filter((e) => entryIs(spot.dir, e, \"file\")).map((e) => e.name);\n const all = entries.filter((e) => entryIs(spot.dir, e, \"dir\")).map((e) => e.name).sort();\n // The classifiable children — a service's own interior removed once, here, so\n // every branch below agrees about it (see `RESERVED_INTERIOR`). `all` is still\n // what the artifact probe reads: `adrs/` makes its parent a service, and\n // `usecases/` is interior the parent may hold without becoming a group.\n const dirs = all.filter((d) => !RESERVED_INTERIOR.has(d));\n const marker = files.includes(SUBSYSTEM_MARKER);\n const artifact =\n files.some((f) => ctx.request.isServiceArtifact(f, \"file\")) ||\n all.some((d) => ctx.request.isServiceArtifact(d, \"dir\"));\n\n if (marker && artifact) {\n // Artifacts win the classification: the documents are somebody's work and\n // the marker is one stray file, so the directory stays an addressable\n // service and the finding names the contradiction instead of the walk\n // quietly picking a reading. But the walk STILL descends (the module\n // invariant: no reinterpretation may shrink the fleet) — the marker says\n // a GROUP was here, and returning without walking made every service\n // beneath it vanish with only this finding to hint why. Child directories\n // that are themselves artifacts (`adrs/`) are service interior, not walked.\n recordService(spot, ctx);\n const stranded = await descendInto(spot, dirs.filter((d) => !ctx.request.isServiceArtifact(d, \"dir\")), ctx);\n ctx.tree.findings.push({\n severity: \"error\",\n code: \"subsystem.marker-misplaced\",\n subject: spot.name,\n message:\n `${rel}/ holds ${SUBSYSTEM_MARKER} BESIDE service artifacts — a directory is a subsystem or a service, never both. ` +\n `It stays classified as a service; delete ${rel}/${SUBSYSTEM_MARKER}, ` +\n `or move the artifacts into a service directory of their own inside the group.` +\n (stranded.length > 0 ? ` ${stranded.length} service(s) beneath it stay enumerated meanwhile: ${stranded.map((s) => s.id).join(\", \")}.` : \"\"),\n ...(stranded.length > 0 ? { details: stranded.map(serviceTreePath) } : {}),\n });\n return;\n }\n if (marker) {\n await visitSubsystem(spot, { rel, dirs }, ctx);\n return;\n }\n if (artifact) {\n recordService(spot, ctx);\n return;\n }\n if (dirs.length > 0) {\n await visitUnmarked(spot, { rel, dirs }, ctx);\n return;\n }\n // Neither marker nor artifact, and nothing beneath: today's flat behaviour —\n // an empty (or not-yet-adopted) directory under services/ is a service.\n recordService(spot, ctx);\n}\n\nfunction recordService(spot: Spot, ctx: WalkContext): void {\n ctx.tree.services.push({\n id: rawServiceId(spot.name),\n dir: serviceDirOf(spot.dir),\n subsystem: spot.chain,\n });\n claimName(spot, ctx);\n}\n\n/** A subsystem: record it, report a broken marker or an illegal name, walk in. */\nasync function visitSubsystem(spot: Spot, at: { rel: string; dirs: string[] }, ctx: WalkContext): Promise<void> {\n const meta = await readSubsystemMarker(join(spot.dir, SUBSYSTEM_MARKER));\n if (meta.invalid !== undefined) {\n // Exactly one finding per marker file: presence already classified the\n // directory, so the content failure is metadata, not identity.\n ctx.tree.findings.push({\n severity: \"error\",\n code: \"subsystem.invalid\",\n subject: at.rel,\n message:\n `${at.rel}/${SUBSYSTEM_MARKER} cannot be read as subsystem metadata — ${meta.invalid}. ` +\n `The directory still counts as a subsystem (presence classifies; content is metadata). ` +\n `Fix the file: a YAML mapping with optional title, description and owner — an empty file is also a valid marker.`,\n });\n }\n const problem = subsystemNameProblem(spot.name, \"subsystem directory name\");\n if (problem !== null) {\n // Walked anyway, mirroring how an illegal service id stays enumerated\n // (`idProblem`): the directory exists and hiding its subtree would shrink\n // the fleet over a naming mistake.\n ctx.tree.findings.push({\n severity: \"error\",\n code: \"subsystem.name-invalid\",\n subject: spot.name,\n message: `${at.rel}/ — ${problem} Rename the directory; its services stay enumerated meanwhile.`,\n });\n }\n ctx.tree.subsystems.push({\n name: spot.name,\n path: [...spot.chain, spot.name],\n dir: spot.dir,\n meta,\n });\n claimName(spot, ctx);\n await descendInto(spot, at.dirs, ctx);\n}\n\n/**\n * Walk the children of a group directory (symlink-cycle guarded), returning\n * the services newly recorded beneath it — the ONE spelling of descent, so\n * the three descending branches agree about the guard and the chain.\n */\nasync function descendInto(spot: Spot, dirs: string[], ctx: WalkContext): Promise<WalkedService[]> {\n const before = ctx.tree.services.length;\n // The guard (`./fs.ts`'s `markDescended`) protects SUBTREES, not entries: a\n // directory reachable under two names is classified twice — both names\n // exist and hiding the second would be the silent shrink this module\n // refuses — but its children are enumerated once, so a symlink cycle\n // terminates instead of recursing forever.\n if (markDescended(spot.dir, ctx.visited)) {\n for (const child of dirs) {\n await visitDir({ dir: join(spot.dir, child), name: child, chain: [...spot.chain, spot.name] }, ctx);\n }\n }\n return ctx.tree.services.slice(before);\n}\n\n/**\n * The refusal branch — a group directory nothing marks. The walk STILL\n * descends, so the services beneath stay in the enumeration and the finding\n * can name them: the fleet must never be reported smaller than it is.\n */\nasync function visitUnmarked(spot: Spot, at: { rel: string; dirs: string[] }, ctx: WalkContext): Promise<void> {\n const stranded = await descendInto(spot, at.dirs, ctx);\n ctx.tree.findings.push({\n severity: \"error\",\n code: \"subsystem.unmarked\",\n subject: at.rel,\n message:\n `${at.rel}/ is neither a subsystem (no ${SUBSYSTEM_MARKER}) nor a service (no service artifact), ` +\n `but ${stranded.length} service(s) sit beneath it` +\n (stranded.length > 0 ? `: ${stranded.map((s) => s.id).join(\", \")}. ` : `. `) +\n `Without the marker this directory would be read as a service and everything under it would vanish from the fleet — ` +\n `the shape an ordinary merge produces when one branch deletes an emptied subsystem's marker while another moves a service in. ` +\n `Restore ${at.rel}/${SUBSYSTEM_MARKER} (an empty file is a valid marker), or move the directories out.`,\n ...(stranded.length > 0 ? { details: stranded.map(serviceTreePath) } : {}),\n });\n}\n\nfunction claimName(spot: Spot, ctx: WalkContext): void {\n const rel = [\"services\", ...spot.chain, spot.name].join(\"/\");\n ctx.names.set(spot.name, [...(ctx.names.get(spot.name) ?? []), rel]);\n}\n\n/**\n * One flat namespace: every subsystem name and service id, unique across the\n * whole tree at any depth, never colliding with each other. The identity\n * decision demands it — a service id is its leaf directory name ALONE, so two\n * leaves spelling one name are one identity claimed twice, wherever they sit.\n * One finding per name, naming every claimant, so the fix is a choice rather\n * than a scavenger hunt.\n */\nfunction namespaceFindings(ctx: WalkContext): void {\n for (const [name, dirs] of [...ctx.names].sort(([a], [b]) => (a < b ? -1 : 1))) {\n if (dirs.length < 2) continue;\n ctx.tree.findings.push({\n severity: \"error\",\n code: \"subsystem.name-collision\",\n subject: name,\n message:\n `'${name}' is claimed by ${dirs.length} directories in the services/ tree: ${dirs.join(\", \")} — ` +\n `service ids and subsystem names share one flat namespace, unique at any depth, ` +\n `because a service's identity is its leaf directory name alone and placement never disambiguates it. ` +\n `Rename all but one.`,\n details: dirs,\n });\n }\n}\n"]}
@@ -23,24 +23,127 @@
23
23
  * reports @Before/@After hook results in per-element `before[]`/`after[]`
24
24
  * arrays (a teardown assertion fails there while every step stays `passed`),
25
25
  * and behave carries an element-level `status` that a hook failure flips.
26
+ * cucumber-js puts its hooks among the `steps[]` instead, as entries marked
27
+ * `hidden` with the keyword `Before`/`After`, and they are read as hooks
28
+ * there too — the number of real steps is contract now, because a run is
29
+ * held to the step count of the scenario it claims to be (`runnerAnswers`).
26
30
  * Only those fields are contract: unknown fields, tagless elements
27
31
  * (backgrounds, hand-written scenarios) and stray entries are skipped without
28
32
  * comment. What is NOT tolerated is a file that is not that array at all: a
29
33
  * report loam cannot recognize must refuse rather than quietly answer every
30
34
  * claim "not found".
31
35
  */
32
- import { DIGEST_TAG_RE, scenarioDigestTag } from "./gherkin.js";
33
- import { isRecord } from "./records.js";
36
+ import { DIGEST_TAG_RE, scenarioDigestTag } from "./gherkin/stamp.js";
37
+ import { isRecord } from "./kernel/records.js";
34
38
  /**
35
39
  * Read a parsed cucumber JSON document down to its digest-tagged scenarios.
36
40
  * `reportName` is how the caller spelled the file, for the refusal message.
37
41
  */
42
+ /** The marker key that makes a JSON document loam's own scenario shape, and the version this loam reads. */
43
+ export const SCENARIO_REPORT_MARKER = "loamScenarioReport";
44
+ export const SCENARIO_REPORT_VERSION = 1;
45
+ /**
46
+ * Is this document loam's own scenario-report shape rather than a cucumber one?
47
+ *
48
+ * Marker-only, deliberately: the caller must be able to choose a READER before
49
+ * either has validated anything, so that a malformed `loamScenarioReport` file
50
+ * refuses as a malformed report of ITS kind rather than as "not a cucumber
51
+ * array". A file that claims the shape and then fails it must never fall
52
+ * through to the other parser and be told it is the wrong sort of document.
53
+ */
54
+ export function isScenarioReport(doc) {
55
+ return isRecord(doc) && doc[SCENARIO_REPORT_MARKER] !== undefined;
56
+ }
57
+ /**
58
+ * `{"loamScenarioReport": 1, "results": [{"digest": "…", "status": "passed"}]}`
59
+ * — the runner-neutral answer sheet for `scenario.tested` claims.
60
+ *
61
+ * WHY THIS EXISTS. `loam gherkin` stamps every generated scenario
62
+ * `@loam-digest-<16hex>`, and until now only cucumber's JSON carried that tag
63
+ * back. A fleet on JUnit, pytest, Playwright, Vitest or a house runner could
64
+ * therefore never reach `verified` — not because its evidence was weaker, but
65
+ * because of a file format. The example fleet's own shipped record is the proof
66
+ * of the cost: every claim in it is `answered_by: agent`, so the product's
67
+ * showcase demonstrates only the lesser verdict.
68
+ *
69
+ * THE STANDARD OF PROOF IS UNCHANGED, and that is the whole argument. The
70
+ * contract was never the JSON dialect: it is the digest — content-derived, so
71
+ * rewording a `Given` breaks the match — plus a status that says a real run
72
+ * reported it green. Both halves are here. An answer from this file is
73
+ * `answered_by: runner` exactly as a cucumber one is, because it is the same
74
+ * claim answered to the same standard by the same identity.
75
+ *
76
+ * It also adds no forgeability. loam cannot prove any JSON came from executing
77
+ * a commit — SCHEMA says so, and the record stores the file's sha256 and mtime
78
+ * precisely because that is all it can honestly claim. A hand-written cucumber
79
+ * array was always exactly as easy to write as this is.
80
+ *
81
+ * The strict/tolerant split mirrors `verify/evidence/contract.ts` for its
82
+ * reason: a cucumber report is another tool's file full of entries loam has no
83
+ * business judging, while this shape exists for one purpose, so a malformed
84
+ * entry is a malformed report rather than scenery to skip. `status` must be
85
+ * exactly `passed` or `failed`; `skipped`, `pending` and vendor spellings are
86
+ * refused rather than guessed at, because guessing is how a not-run scenario
87
+ * becomes a confirmation.
88
+ */
89
+ export function readScenarioReport(doc, reportName) {
90
+ if (!isRecord(doc)) {
91
+ return { ok: false, message: `${reportName} is not a JSON object.` };
92
+ }
93
+ const version = doc[SCENARIO_REPORT_MARKER];
94
+ if (version !== SCENARIO_REPORT_VERSION) {
95
+ return {
96
+ ok: false,
97
+ message: `${reportName} declares \`${SCENARIO_REPORT_MARKER}: ${JSON.stringify(version)}\`, and this loam reads ` +
98
+ `version ${SCENARIO_REPORT_VERSION}. A report loam cannot read is refused rather than answered in part.`,
99
+ };
100
+ }
101
+ const results = doc["results"];
102
+ if (!Array.isArray(results)) {
103
+ return {
104
+ ok: false,
105
+ message: `${reportName} has no \`results\` array — the shape is {"${SCENARIO_REPORT_MARKER}": 1, "results": [{"digest": "…", "status": "passed"}]}.`,
106
+ };
107
+ }
108
+ const scenarios = [];
109
+ for (const [i, entry] of results.entries()) {
110
+ const at = `${reportName} results[${i}]`;
111
+ if (!isRecord(entry))
112
+ return { ok: false, message: `${at} is not an object.` };
113
+ const digest = str(entry["digest"]);
114
+ if (digest === undefined || !/^[0-9a-f]{16}$/.test(digest)) {
115
+ return {
116
+ ok: false,
117
+ message: `${at} has no \`digest\` of 16 lowercase hex characters — that is the \`@loam-digest-…\` tag \`loam gherkin\` stamped on the scenario.`,
118
+ };
119
+ }
120
+ const status = str(entry["status"]);
121
+ if (status !== "passed" && status !== "failed") {
122
+ return {
123
+ ok: false,
124
+ message: `${at} has \`status: ${JSON.stringify(entry["status"])}\`; this shape accepts only "passed" or "failed". ` +
125
+ "A scenario that did not run has no place in an answer sheet — omit it, and its claim stays unanswered rather than becoming a confirmation.",
126
+ };
127
+ }
128
+ scenarios.push({
129
+ // The runner's own name for the test, when it gave one — this is where a
130
+ // reader goes to see the run, and it is the only free text here.
131
+ where: str(entry["test"]) ?? `(${SCENARIO_REPORT_MARKER} entry ${i})`,
132
+ digests: [digest],
133
+ steps: [status],
134
+ stepwise: false,
135
+ hooks: [],
136
+ });
137
+ }
138
+ return { ok: true, scenarios };
139
+ }
38
140
  export function readCucumberReport(doc, reportName) {
39
141
  if (!Array.isArray(doc)) {
40
142
  return {
41
143
  ok: false,
42
144
  message: `${reportName} is not a cucumber JSON report — expected the top-level array of features ` +
43
- "that `cucumber-js --format json` (or cucumber-jvm, behave, SpecFlow) emits.",
145
+ "that `cucumber-js --format json` (or cucumber-jvm, behave, SpecFlow) emits. " +
146
+ `A runner with no cucumber formatter answers through loam's own shape instead: {"${SCENARIO_REPORT_MARKER}": 1, "results": [{"digest": "…", "status": "passed"}]}.`,
44
147
  };
45
148
  }
46
149
  const scenarios = [];
@@ -68,17 +171,24 @@ export function readCucumberReport(doc, reportName) {
68
171
  // scenario, another tool's output. Invisible here, deliberately.
69
172
  if (digests.length === 0)
70
173
  continue;
71
- const resultStatuses = (raw) => {
72
- if (!Array.isArray(raw))
73
- return [];
74
- return raw.map((s) => {
75
- const status = isRecord(s) && isRecord(s["result"]) ? str(s["result"]["status"]) : undefined;
76
- return (status ?? "unknown").toLowerCase();
77
- });
174
+ const statusOf = (s) => {
175
+ const status = isRecord(s) && isRecord(s["result"]) ? str(s["result"]["status"]) : undefined;
176
+ return (status ?? "unknown").toLowerCase();
78
177
  };
79
- const steps = resultStatuses(el["steps"]);
178
+ const resultStatuses = (raw) => (Array.isArray(raw) ? raw.map(statusOf) : []);
179
+ // cucumber-js reports its Before/After hooks INSIDE `steps`, as entries
180
+ // marked `hidden` with the keyword `Before`/`After`; they are hooks, not
181
+ // steps of the scenario, and counting them would make every hooked run
182
+ // look like a different scenario from the one stamped.
183
+ const listed = Array.isArray(el["steps"]) ? el["steps"] : [];
184
+ const isHook = (s) => isRecord(s) && (s["hidden"] === true || /^(before|after)$/i.test(str(s["keyword"])?.trim() ?? ""));
185
+ const steps = listed.filter((s) => !isHook(s)).map(statusOf);
80
186
  // cucumber-jvm's @Before/@After hooks: separate arrays, same result shape.
81
- const hooks = [...resultStatuses(el["before"]), ...resultStatuses(el["after"])];
187
+ const hooks = [
188
+ ...resultStatuses(el["before"]),
189
+ ...listed.filter(isHook).map(statusOf),
190
+ ...resultStatuses(el["after"]),
191
+ ];
82
192
  // behave's element-level status — a hook failure flips it while the
83
193
  // steps that already ran keep "passed".
84
194
  const status = str(el["status"])?.toLowerCase();
@@ -86,6 +196,7 @@ export function readCucumberReport(doc, reportName) {
86
196
  where: `${featureName} › ${str(el["name"]) ?? "(unnamed scenario)"}`,
87
197
  digests,
88
198
  steps,
199
+ stepwise: true,
89
200
  hooks,
90
201
  ...(status === undefined ? {} : { status }),
91
202
  });
@@ -139,6 +250,14 @@ export function contestedDigests(claims) {
139
250
  * occurrence wins as failure, a skipped-only run is "skipped" not green, and
140
251
  * no match at all is "not found in report". A digest two services share is
141
252
  * refused before any of that: see {@link contestedDigests}.
253
+ *
254
+ * And a cucumber occurrence must have run as many steps as the stamped
255
+ * scenario has (`Claim.steps`). The digest is only a tag, and a tag is text:
256
+ * a one-step stub named "a step" carrying the right digest confirmed
257
+ * five-step scenarios, because nothing compared what ran with what was
258
+ * stamped. The count is the check every dialect can be held to; loam's own
259
+ * runner-neutral shape carries no steps to count, so its entries are held to
260
+ * their status alone, as that shape has always promised.
142
261
  */
143
262
  export function runnerAnswers(claims, scenarios, reportName) {
144
263
  const contested = contestedDigests(claims);
@@ -153,13 +272,16 @@ export function runnerAnswers(claims, scenarios, reportName) {
153
272
  const tag = c.digest === undefined ? "a digest tag" : scenarioDigestTag(c.digest);
154
273
  return answer(c.id, "unconfirmed", [], `not found in report — no scenario in ${reportName} carries ${tag}`);
155
274
  }
156
- const failing = runs.filter((r) => !passed(r));
275
+ const failing = runs.filter((r) => !passed(r) || !sameShape(r, c.steps));
157
276
  if (failing.length === 0) {
158
277
  return answer(c.id, "confirmed", runs.map((r) => `${reportName}: ${r.where}`));
159
278
  }
160
279
  const first = failing[0];
161
280
  const rerun = runs.length > 1 ? ` — ${failing.length} of ${runs.length} matching runs failed` : "";
162
- return answer(c.id, "unconfirmed", [], `${reason(first)} (${reportName}: ${first.where})${rerun}`);
281
+ const why = passed(first)
282
+ ? `ran ${first.steps.length} step(s) where the stamped scenario has ${c.steps} — the report's scenario is not the one \`loam gherkin\` stamped with this digest`
283
+ : reason(first);
284
+ return answer(c.id, "unconfirmed", [], `${why} (${reportName}: ${first.where})${rerun}`);
163
285
  });
164
286
  }
165
287
  function answer(id, verdict, evidence, note) {
@@ -179,6 +301,16 @@ function passed(r) {
179
301
  r.hooks.every((h) => h === "passed") &&
180
302
  (r.status === undefined || r.status === "passed"));
181
303
  }
304
+ /**
305
+ * Did this run execute the scenario the claim stamped — as far as the report
306
+ * can say? A cucumber run must have run exactly the stamped number of steps.
307
+ * An entry with no step structure (loam's own shape), and a claim carrying no
308
+ * count (only `scenario.tested` claims carry one, and only they carry a digest
309
+ * to match), are held to their status alone.
310
+ */
311
+ function sameShape(r, expected) {
312
+ return !r.stepwise || expected === undefined || r.steps.length === expected;
313
+ }
182
314
  /** Why a run did not pass, naming the step, hook or element status that says so. */
183
315
  function reason(r) {
184
316
  if (r.steps.length === 0)