@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
@@ -1,807 +0,0 @@
1
- /**
2
- * The done-check: did the code that was built match the feature that was
3
- * designed?
4
- *
5
- * The original plan was to extract C4 from the built code and diff it against
6
- * the delta. There is no such extractor and there will not be one — nothing
7
- * deterministic reads a service and says what its architecture MEANS, and two
8
- * generated models of the same code disagree in wording every run, so the diff
9
- * would flap and be switched off inside a week.
10
- *
11
- * What survives of the idea is the part that was always deterministic: the
12
- * QUESTIONS. A feature's own artifacts say exactly what it promised — this
13
- * service will exist, it will expose this operation, that service will call it,
14
- * this scenario will have a test. loam derives that list mechanically from the
15
- * same files `validate` already reads, an agent answers each claim with
16
- * evidence, and `--record` writes the answers down beside the feature.
17
- *
18
- * A scenario claim is answered mechanically wherever it can be: `--results`
19
- * reads a cucumber JSON report and matches it by the digest tag `loam gherkin`
20
- * stamped, and only a green run confirms one (results.ts). Where it cannot —
21
- * a legacy service whose suite is months away, which is the fleet loam exists
22
- * for — `--record` may still take an agent's word for it, and the record marks
23
- * that answer ATTESTED rather than run: `verified` is reserved for a checklist
24
- * whose scenarios a run answered, and `verify.scenario-attested` says so on
25
- * every surface that reads the record.
26
- *
27
- * Two properties make the record worth keeping. The claim ids are a function of
28
- * the claim and of nothing else — so two runs are diffable, reordering the delta
29
- * renames nothing, and rewording a scenario DOES rename its claim, because an
30
- * answer about text nobody wrote must not carry over. And an answer set that
31
- * does not correspond to the current checklist is refused rather than merged:
32
- * an unchecked claim must never be able to masquerade as checked.
33
- *
34
- * loam does not judge the answers. It cannot: it never read the code. It only
35
- * guarantees that every question was asked and that every answer is on the
36
- * record next to the question it answers.
37
- */
38
- import { createHash } from "node:crypto";
39
- import { existsSync } from "node:fs";
40
- import { readFile, writeFile } from "node:fs/promises";
41
- import { join } from "node:path";
42
- import { parse, stringify } from "yaml";
43
- import { elementService, loadFile, serviceOf } from "./likec4.js";
44
- import { operationIds, operations } from "./openapi.js";
45
- import { isRecord } from "./records.js";
46
- import { featurePaths, featureSpecPaths, featureSpecServices, servicePaths } from "./repo.js";
47
- import { parseRequirements } from "./spec.js";
48
- /**
49
- * What a claim is about. The order is the order the checklist comes back in,
50
- * and it reads as the story of the feature: the service exists, it exposes its
51
- * operations, the calls into it are wired, the behaviour is tested.
52
- */
53
- export const CLAIM_KINDS = ["service.exists", "api.exposes", "c4.calls", "scenario.tested"];
54
- /**
55
- * How much of the sha256 goes into an id, and into a digest — the checklist's,
56
- * and a scenario claim's runner-matching one, which is deliberately the same
57
- * 16 hex `loam gherkin` stamps (its GHERKIN_DIGEST_LENGTH): the tag in a
58
- * cucumber report and the digest on a claim must be the same string.
59
- */
60
- const ID_LENGTH = 8;
61
- const DIGEST_LENGTH = 16;
62
- /** C4 kinds that model people. A person is never a service. (Mirrors validate.ts.) */
63
- const ACTOR_KINDS = new Set(["person", "actor", "user"]);
64
- /**
65
- * Derive the checklist from a feature's own artifacts. No code is read here and
66
- * none should be: the whole design rests on the questions being computed from
67
- * documents that do not change between runs.
68
- */
69
- export async function featureChecklist(docsDir, featureDir, featureId) {
70
- const seen = new Map();
71
- const claim = (kind, subject, parts, text) => ({
72
- id: claimId(featureId, kind, parts, seen),
73
- kind,
74
- subject,
75
- claim: text,
76
- });
77
- const exists = [];
78
- const exposes = [];
79
- const calls = [];
80
- const scenarios = [];
81
- // Architecture — what the delta promised the fleet would look like.
82
- const deltaPath = featurePaths(featureDir).delta;
83
- if (existsSync(deltaPath)) {
84
- const res = await loadFile(deltaPath);
85
- // A delta nobody can parse promises nothing checkable. `validate` already
86
- // reports it; inventing claims out of a broken document would only add noise.
87
- if (res.errors.length === 0) {
88
- const elements = res.elements;
89
- for (const e of elements) {
90
- if (!e.tags.includes(featureId))
91
- continue;
92
- // A dotted id is a container INSIDE a service, and an actor is nobody's
93
- // repository. Neither is a service that has to exist.
94
- if (e.id.includes(".") || ACTOR_KINDS.has(e.kind.toLowerCase()))
95
- continue;
96
- const svc = elementService(e);
97
- exists.push(claim("service.exists", svc, [svc], `service '${svc}' exists`));
98
- }
99
- for (const r of res.relationships) {
100
- // Untagged edges are context for the diagram; an edge with no operation
101
- // names nothing specific enough to look for in the code.
102
- if (!r.tags.includes(featureId) || r.op === undefined)
103
- continue;
104
- const from = serviceOf(elements, r.source);
105
- const to = serviceOf(elements, r.target);
106
- calls.push(claim("c4.calls", from, [from, to, r.op], `${from} calls '${r.op}' on ${to}`));
107
- }
108
- }
109
- }
110
- for (const svc of await featureSpecServices(featureDir)) {
111
- const paths = featureSpecPaths(featureDir, svc);
112
- // Contract — only what is NEW. A delta's openapi.yaml is a whole document,
113
- // not a patch, so authors restate the living API inside it; asking whether a
114
- // service still exposes what it already exposed is noise.
115
- const featOps = (await operations(paths.openapi))
116
- .filter((operation) => !operation.remove)
117
- .map((operation) => operation.id);
118
- if (featOps.length > 0) {
119
- const living = new Set(await operationIds(servicePaths(docsDir, svc).openapi));
120
- for (const op of featOps) {
121
- if (living.has(op))
122
- continue;
123
- exposes.push(claim("api.exposes", svc, [svc, op], `${svc} exposes operationId '${op}'`));
124
- }
125
- }
126
- // Behaviour — the scenarios of the requirements this feature CHANGES. A BASE
127
- // requirement is the living state quoted inside the delta, and a REMOVED one
128
- // is being retired: neither is work anybody has to have done.
129
- if (existsSync(paths.spec)) {
130
- for (const r of parseRequirements(await readFile(paths.spec, "utf8"))) {
131
- if (r.kind === "BASE" || r.kind === "REMOVED")
132
- continue;
133
- for (const s of r.scenarios) {
134
- const body = scenarioBodyHash(svc, s.lines);
135
- scenarios.push({
136
- ...claim("scenario.tested", svc, [svc, r.id ?? r.name, s.name, body.slice(0, ID_LENGTH)], `scenario '${s.name}' of requirement '${r.name}' (${svc}) is covered by a test`),
137
- digest: body.slice(0, DIGEST_LENGTH),
138
- });
139
- }
140
- }
141
- }
142
- // The architecture spec axis, same walk: an arch scenario is a promise like
143
- // any other — the outbox test nobody was going to write IS the point of the
144
- // axis. The source file rides in the id tuple AND in the body hash itself
145
- // (two axes are two namespaces: identically-worded scenarios must stay two
146
- // questions, and the axis-salted digest is what keeps a business-only test
147
- // run from answering the arch claim) and in the claim text, so the
148
- // answering agent knows it is being asked for an integration/ops test, not
149
- // an acceptance test.
150
- if (existsSync(paths.archSpec)) {
151
- for (const r of parseRequirements(await readFile(paths.archSpec, "utf8"))) {
152
- if (r.kind === "BASE" || r.kind === "REMOVED")
153
- continue;
154
- for (const s of r.scenarios) {
155
- const body = scenarioBodyHash(svc, s.lines, "arch");
156
- scenarios.push({
157
- ...claim("scenario.tested", svc, [svc, "arch.spec.md", r.id ?? r.name, s.name, body.slice(0, ID_LENGTH)], `scenario '${s.name}' of arch requirement '${r.name}' (${svc}, arch.spec.md) is covered by a test`),
158
- digest: body.slice(0, DIGEST_LENGTH),
159
- });
160
- }
161
- }
162
- }
163
- }
164
- const claims = [...exists, ...exposes, ...calls, ...scenarios];
165
- return { feature: featureId, claims, digest: checklistDigest(claims) };
166
- }
167
- /**
168
- * A claim's identity: a hash of what it says, and nothing about how it was
169
- * produced.
170
- *
171
- * The feature id is part of it so an answers file for one feature can never
172
- * validate against another. Two claims that really are identical (the same
173
- * scenario name twice under one requirement) are distinguished by occurrence, in
174
- * document order — they are still two questions, and answering one must not
175
- * answer the other.
176
- *
177
- * The hash is short because the claim text sits next to it everywhere it is
178
- * shown; it identifies a question, it does not authenticate one.
179
- */
180
- function claimId(featureId, kind, parts, seen) {
181
- // NUL-joined so no claim's own text can spell another claim's tuple by
182
- // containing the separator: ['a b','c'] and ['a','b c'] stay two questions.
183
- const tuple = [featureId, kind, ...parts].join("\u0000");
184
- const n = (seen.get(tuple) ?? 0) + 1;
185
- seen.set(tuple, n);
186
- const canonical = n === 1 ? tuple : `${tuple}\u0000#${n}`;
187
- return `${kind}-${createHash("sha256").update(canonical).digest("hex").slice(0, ID_LENGTH)}`;
188
- }
189
- /**
190
- * The full sha256 of a scenario's body — its lines joined and edge-trimmed,
191
- * exactly as `serializeRequirements` frames them. The BODY, not the title,
192
- * because rewriting the Given/When/Then under an unchanged heading is new text
193
- * nobody answered for, and the promise — rewording a scenario renames its
194
- * claim — has to hold for the words that actually specify the behaviour.
195
- *
196
- * ONE recipe with three consumers, deliberately in one place:
197
- * `scenario.tested` claim ids fold in its first {@link ID_LENGTH} hex
198
- * characters, a claim's `digest` and the `@loam-digest-<16hex>` tag `loam
199
- * gherkin` stamps both take its first {@link DIGEST_LENGTH} — so the claim,
200
- * the stamp and the report `--results` reads can never disagree about what a
201
- * scenario says.
202
- *
203
- * The identity is (SERVICE, AXIS, body), and both salts are there for the same
204
- * reason: a digest that spans two namespaces lets one green run answer a
205
- * question nobody ran a test for.
206
- *
207
- * - The AXIS salt keeps `spec.md` and `arch.spec.md` apart. Without it a green
208
- * BUSINESS run answered the arch claim too — an integration test nobody wrote
209
- * read as run.
210
- * - The SERVICE salt keeps two repositories apart. "the service returns 404 for
211
- * an unknown id" is worded the same way in nine services of a real fleet;
212
- * unsalted, all nine shared one digest, `loam gherkin` stamped one tag into
213
- * nine repositories, and one repository's green run confirmed the other
214
- * eight's claims — across suites that never ran each other's tests.
215
- *
216
- * The service salt is what makes that case CORRECT rather than merely refused:
217
- * `contestedDigests` could only decline to answer a shared digest, which left a
218
- * fleet with ordinary repeated wording holding claims nothing could ever
219
- * answer.
220
- *
221
- * Both salts renamed every claim id and every stamped tag on the day they
222
- * landed, and both readings are legible rather than silent: an existing
223
- * `verification.yaml` answers a checklist digest that is no longer derived and
224
- * reports STALE, and an existing generated `.feature` carries digests the
225
- * living spec no longer computes and reports `gherkin.stale` beside the
226
- * `gherkin.missing` for the new ones. One `loam gherkin` and one re-record
227
- * clear both.
228
- */
229
- export function scenarioBodyHash(service, lines, axis = "business") {
230
- // NUL-separated like claimId's tuples, and for its reason: no body can spell
231
- // the salt in front of it, so the namespaces stay disjoint. Spelled as an
232
- // escape and never as a raw NUL in the literal — a raw one makes this file
233
- // read as `data` to `file(1)` and invisible to `grep`.
234
- const body = lines.join("\n").trim();
235
- const onAxis = axis === "arch" ? `arch.spec.md\u0000${body}` : body;
236
- return createHash("sha256").update(`${service}\u0000${onAxis}`).digest("hex");
237
- }
238
- /**
239
- * A digest of the claim id SET — sorted, so reordering the artifacts does not
240
- * make a record look stale. It changes when a claim is added, removed or
241
- * reworded, which is exactly when an answer set stops describing the feature.
242
- */
243
- function checklistDigest(claims) {
244
- const ids = claims.map((c) => c.id).sort();
245
- return createHash("sha256").update(ids.join("\n")).digest("hex").slice(0, DIGEST_LENGTH);
246
- }
247
- /* ------------------------------------------------------------------ */
248
- /* The answers */
249
- /* ------------------------------------------------------------------ */
250
- /**
251
- * Two verdicts, deliberately. Anything an agent cannot show evidence for is
252
- * unconfirmed — a third value for "not applicable" would absorb every claim
253
- * nobody wanted to answer.
254
- */
255
- export const VERDICTS = ["confirmed", "unconfirmed"];
256
- /**
257
- * Who answered a claim: the `runner` (a cucumber report's digest-tagged
258
- * scenarios, matched mechanically by `--results`) or an `agent` (somebody's
259
- * word about the code, taken back by `--record`). On the record so a reviewer
260
- * can tell a green run from an assertion.
261
- */
262
- export const ANSWERED_BY = ["runner", "agent"];
263
- /**
264
- * Accept an answer set only if it answers THIS checklist: every claim once, no
265
- * claim twice, nothing extra, and no "confirmed" that shows nothing.
266
- *
267
- * The refusals are the point of the command. If a stale or partial answer file
268
- * could be recorded, `verification.yaml` would say a claim was checked when
269
- * nobody ever asked it — and a record that can lie is worse than no record,
270
- * because it looks like evidence.
271
- *
272
- * `runnerOwned` is the composition rule under `--results`: ids the test runner
273
- * answers, which an answers file must therefore not touch. An entry naming one
274
- * refuses with its own diagnosis — the id IS on the feature's checklist, so
275
- * calling it unknown would send the caller hunting a staleness that is not
276
- * there.
277
- *
278
- * `context` is what turns the last line from a circle into an instruction. In a
279
- * fleet the commonest way to "miss" a claim is that it is not yours: the
280
- * checklist spans ten repositories and this one can only answer its own. Told
281
- * only to "answer the claims it lists", an agent in the payment-service repo
282
- * re-runs verify, sees the same checkout-web claims it cannot speak for, and
283
- * either loops or invents evidence. So when every unanswered claim belongs to
284
- * another service, say THAT, and name the command that records them.
285
- */
286
- export function checkAnswers(claims, raw, runnerOwned, context) {
287
- const refuse = (code, message) => ({ ok: false, code, message });
288
- const list = Array.isArray(raw)
289
- ? raw
290
- : isRecord(raw) && Array.isArray(raw["answers"])
291
- ? raw["answers"]
292
- : null;
293
- if (list === null) {
294
- return refuse("answers-unreadable", "Expected a JSON array of answers, or an object with an `answers` array: " +
295
- `[{ "id": "...", "verdict": "confirmed", "evidence": ["file:line"] }]`);
296
- }
297
- const answers = [];
298
- for (const [i, entry] of list.entries()) {
299
- const where = `answer ${i + 1}`;
300
- if (!isRecord(entry))
301
- return refuse("answers-unreadable", `${where} is not an object`);
302
- const id = entry["id"];
303
- if (typeof id !== "string" || id.length === 0) {
304
- return refuse("answers-unreadable", `${where} has no claim id`);
305
- }
306
- const verdict = entry["verdict"];
307
- if (typeof verdict !== "string" || !VERDICTS.includes(verdict)) {
308
- return refuse("answers-unreadable", `${where} ('${id}') has verdict ${JSON.stringify(verdict)} — expected one of ${VERDICTS.join(", ")}`);
309
- }
310
- const note = typeof entry["note"] === "string" ? entry["note"].trim() : "";
311
- answers.push({
312
- id,
313
- verdict: verdict,
314
- evidence: stringList(entry["evidence"]),
315
- ...(note.length > 0 ? { note } : {}),
316
- answered_by: "agent",
317
- });
318
- }
319
- const byId = new Map();
320
- const twice = [];
321
- for (const a of answers) {
322
- if (byId.has(a.id))
323
- twice.push(a.id);
324
- else
325
- byId.set(a.id, a);
326
- }
327
- const known = new Set(claims.map((c) => c.id));
328
- const strayIds = [...new Set(answers.map((a) => a.id).filter((id) => !known.has(id)))];
329
- const runnerHit = strayIds.filter((id) => runnerOwned?.has(id) === true);
330
- const unknown = strayIds.filter((id) => runnerOwned?.has(id) !== true);
331
- const missingClaims = claims.filter((c) => !byId.has(c.id));
332
- const missing = missingClaims.map((c) => c.id);
333
- if (runnerHit.length + unknown.length + missing.length + twice.length > 0) {
334
- const parts = [
335
- runnerHit.length > 0
336
- ? `${runnerHit.length} answer(s) name scenario claim(s) the test runner owns under --results: ${runnerHit.join(", ")} — the report answers those; take them out of the answers file`
337
- : "",
338
- unknown.length > 0 ? `${unknown.length} answer(s) name a claim that is not on the checklist: ${unknown.join(", ")}` : "",
339
- missing.length > 0 ? `${missing.length} claim(s) have no answer: ${missing.join(", ")}` : "",
340
- twice.length > 0 ? `${twice.length} claim(s) answered more than once: ${[...new Set(twice)].join(", ")}` : "",
341
- ].filter((s) => s.length > 0);
342
- return refuse("answers-mismatch", `These answers do not match the checklist — ${parts.join("; ")}. ` +
343
- missingAdvice(missingClaims, claims.filter((c) => byId.has(c.id)), context));
344
- }
345
- const unevidenced = claims
346
- .map((c) => byId.get(c.id))
347
- .filter((a) => a.verdict === "confirmed" && a.evidence.length === 0)
348
- .map((a) => a.id);
349
- if (unevidenced.length > 0) {
350
- return refuse("answers-unevidenced", `${unevidenced.length} claim(s) are confirmed with no evidence: ${unevidenced.join(", ")}. A confirmation with nothing behind it is an assertion — give a file:line, or answer 'unconfirmed'.`);
351
- }
352
- // Checklist order, not the order they were written in: the record reads in the
353
- // order the questions were asked, whatever the agent did.
354
- return { ok: true, answers: claims.map((c) => byId.get(c.id)) };
355
- }
356
- /**
357
- * The last sentence of an `answers-mismatch`. "Re-run and answer the claims it
358
- * lists" is sound advice only when the caller CAN answer them. In a fleet the
359
- * checklist is federated — a feature's claims are filed under the service whose
360
- * code answers them — so the honest diagnosis for a repo that answered
361
- * everything it owns is "the rest is not yours", together with the form that
362
- * records the rest. Anything else sends the caller round the same loop.
363
- */
364
- function missingAdvice(missing, answered, context) {
365
- const generic = "Re-run `loam verify` and answer the claims it lists.";
366
- if (context === undefined || missing.length === 0 || answered.length === 0)
367
- return generic;
368
- // The signature of "I answered mine and the rest is not mine": the services
369
- // that own the unanswered claims and the services that own the answered ones
370
- // do not overlap. A single-service checklist with one claim forgotten fails
371
- // this test and keeps the generic advice, which is the right advice there —
372
- // that claim really is the caller's to answer.
373
- const owners = [...new Set(missing.map((c) => c.subject))].sort();
374
- const covered = new Set(answered.map((c) => c.subject));
375
- if (owners.some((s) => covered.has(s)))
376
- return generic;
377
- const form = `\`loam verify ${context.feature} --record answers.json --service <svc>\``;
378
- const mine = context.service;
379
- return mine === undefined
380
- ? `Those claims are owned by ${owners.join(", ")} — each service attests its own from its own repository (${form}); ` +
381
- "this all-at-once form has to answer the whole checklist in one file."
382
- : `Every unanswered claim belongs to a different service (${owners.join(", ")}) and this repository can only attest '${mine}' — ` +
383
- `run ${form} in each of those repositories instead.`;
384
- }
385
- function stringList(v) {
386
- if (typeof v === "string")
387
- return v.trim().length > 0 ? [v.trim()] : [];
388
- if (!Array.isArray(v))
389
- return [];
390
- return v.map((x) => String(x).trim()).filter((s) => s.length > 0);
391
- }
392
- /**
393
- * The confirmed `scenario.tested` claims that no test run answered.
394
- *
395
- * A scenario claim's whole premise is that a run answers it — its digest IS the
396
- * tag `loam gherkin` stamps, and `--results` matches the two mechanically. An
397
- * agent may still answer one, because a legacy service has no runnable suite
398
- * for months and that fleet is who loam is for; but the answer is somebody's
399
- * word about a test, and it must not read as the run. A record written before
400
- * `--results` existed carries no `answered_by` at all: unknown counts as agent
401
- * here, because the alternative is to credit a run nobody can point at.
402
- */
403
- export function attestedClaims(claims) {
404
- return claims
405
- .filter((c) => c.kind === "scenario.tested" && c.verdict === "confirmed" && c.answered_by !== "runner")
406
- .map((c) => c.id);
407
- }
408
- /**
409
- * `unanswered` is the count the answers themselves cannot show: a federated
410
- * record holds only what somebody answered, and the claims still owed to other
411
- * repositories exist on the checklist, not in `claims[]`. Read views that carry
412
- * an `unanswered` status inside the list pass 0 and are counted in place.
413
- */
414
- export function tallyAnswers(claims, unanswered = 0) {
415
- const of = (verdict) => claims.filter((c) => c.verdict === verdict).length;
416
- return {
417
- claims: claims.length + unanswered,
418
- confirmed: of("confirmed"),
419
- unconfirmed: of("unconfirmed"),
420
- unanswered: of("unanswered") + unanswered,
421
- attested: attestedClaims(claims).length,
422
- };
423
- }
424
- /**
425
- * The record's own answers, recounted. Never `v.summary`: the summary is what
426
- * whoever wrote the file said the answers add up to, and every reader that
427
- * believed it reported a record full of unconfirmed claims as fully confirmed.
428
- * `readVerificationState` refuses a record whose summary contradicts this, so a
429
- * caller holding a Verification may use either — and should use this one.
430
- */
431
- export function tallyRecord(v) {
432
- return tallyAnswers(v.claims, v.summary.unanswered ?? 0);
433
- }
434
- /**
435
- * Three states, because two were a lie. `verified` is the strong claim — every
436
- * question answered, every answer confirmed, and every scenario answered by a
437
- * digest-matched green run. `attested` is the same completeness resting, for at
438
- * least one scenario, on an agent's word. `unverified` is everything else:
439
- * nothing recorded, a record gone stale, a claim unanswered or unconfirmed, or
440
- * a checklist that asks nothing at all.
441
- */
442
- export const VERIFICATION_VERDICTS = ["verified", "attested", "unverified"];
443
- export function verificationVerdict(t, stale = false) {
444
- if (stale || t.claims === 0 || t.confirmed !== t.claims)
445
- return "unverified";
446
- return t.attested > 0 ? "attested" : "verified";
447
- }
448
- /**
449
- * The one notice `verify`, `list` and `status` all show: this record's scenario
450
- * claims were confirmed without a run.
451
- *
452
- * It is a warning and it gates nothing — verify has never gated, and a service
453
- * with no suite yet has to be able to ship. What it must never do is read the
454
- * same as a green run.
455
- */
456
- export function attestedNotice(claims, feature) {
457
- const ids = attestedClaims(claims);
458
- if (ids.length === 0)
459
- return null;
460
- return {
461
- code: "verify.scenario-attested",
462
- severity: "warn",
463
- message: `${ids.length} scenario claim(s) are confirmed on an agent's word, not on a test run: ${ids.join(", ")}. ` +
464
- `Answer them mechanically once the suite runs: \`loam verify ${feature} --results <cucumber.json>\`.`,
465
- claims: ids,
466
- };
467
- }
468
- /**
469
- * Where the record lives: inside the feature, so `archive` carries it into
470
- * `features/archive/` with everything else and a reviewer finds it next to the
471
- * delta it is about. YAML rather than frontmatter or JSON — it is data, it has
472
- * to survive without loam, and one claim per block is a diff a person can read.
473
- */
474
- export function verificationPath(featureDir) {
475
- return join(featureDir, "verification.yaml");
476
- }
477
- export function buildVerification(checklist, answers, today, report) {
478
- const byId = new Map(answers.map((a) => [a.id, a]));
479
- const claims = checklist.claims.map((c) => {
480
- // Callers hand in an answer per claim — `runnerAnswers` is total over the
481
- // checklist, and both other callers map the checklist to build theirs. The
482
- // branch is here because the alternative to a diagnosis is a `TypeError` on
483
- // `a.verdict`, which cli.ts reports as `internal` with a stack about a
484
- // property of `undefined` and no word about which claim went missing.
485
- const a = byId.get(c.id);
486
- if (a === undefined)
487
- throw new Error(`buildVerification: no answer for claim ${c.id}`);
488
- return {
489
- id: c.id,
490
- kind: c.kind,
491
- claim: c.claim,
492
- verdict: a.verdict,
493
- answered_by: a.answered_by,
494
- evidence: a.evidence,
495
- ...(a.note === undefined ? {} : { note: a.note }),
496
- };
497
- });
498
- const confirmed = claims.filter((c) => c.verdict === "confirmed").length;
499
- return {
500
- feature: checklist.feature,
501
- recorded: today,
502
- checklist: checklist.digest,
503
- summary: { claims: claims.length, confirmed, unconfirmed: claims.length - confirmed },
504
- claims,
505
- ...(report === undefined ? {} : { report }),
506
- };
507
- }
508
- /**
509
- * Replace one service's contribution while retaining current contributions
510
- * from other repositories. Claim ids removed from the live checklist are
511
- * pruned from both the answers and their attestations, so a changed feature can
512
- * never keep a green answer to a question it no longer asks.
513
- */
514
- export function buildFederatedVerification(checklist, service, answers, previous, recorded, commit, report) {
515
- const currentById = new Map(checklist.claims.map((claim) => [claim.id, claim]));
516
- const localIds = new Set(checklist.claims.filter((claim) => claim.subject === service).map((claim) => claim.id));
517
- // An old all-at-once record remains readable, but its answers have no commit
518
- // attestation and therefore cannot silently become somebody else's
519
- // federated contribution. The first schema-2 write starts a clean federation.
520
- const previouslyAttested = new Set((previous?.attestations ?? []).flatMap((a) => a.claims));
521
- const retained = (previous?.schema === 2 ? previous.claims : []).filter((claim) => {
522
- const current = currentById.get(claim.id);
523
- return current !== undefined && current.subject !== service && previouslyAttested.has(claim.id);
524
- });
525
- const local = answers.map((answer) => {
526
- // Same contract as `buildVerification`: an answer is built from the live
527
- // checklist, so it always names a current claim. Off-checklist answers do
528
- // NOT belong here — `discarded` means "an answer the PREVIOUS record held",
529
- // and routing an incoming stray into it would change what the printed
530
- // notice tells an operator. A caller that reaches this gets told which
531
- // answer it was rather than a `TypeError` on `claim.kind`.
532
- const claim = currentById.get(answer.id);
533
- if (claim === undefined) {
534
- throw new Error(`buildFederatedVerification: answer ${answer.id} names no current claim`);
535
- }
536
- return {
537
- id: claim.id,
538
- kind: claim.kind,
539
- subject: claim.subject,
540
- claim: claim.claim,
541
- verdict: answer.verdict,
542
- answered_by: answer.answered_by,
543
- evidence: answer.evidence,
544
- ...(answer.note === undefined ? {} : { note: answer.note }),
545
- };
546
- });
547
- const byId = new Map([...retained, ...local].map((claim) => [claim.id, claim]));
548
- const claims = checklist.claims.flatMap((claim) => {
549
- const answer = byId.get(claim.id);
550
- if (answer === undefined)
551
- return [];
552
- // Normalize retained legacy entries to the current question text and add
553
- // the subject schema 2 needs for future independent replacement.
554
- return [{ ...answer, kind: claim.kind, subject: claim.subject, claim: claim.claim }];
555
- });
556
- const retainedAttestations = (previous?.attestations ?? []).flatMap((attestation) => {
557
- if (attestation.service === service)
558
- return [];
559
- const ids = attestation.claims.filter((id) => currentById.get(id)?.subject === attestation.service && byId.has(id));
560
- return ids.length === 0 ? [] : [{ ...attestation, claims: ids }];
561
- });
562
- const attestations = [
563
- ...retainedAttestations,
564
- {
565
- service,
566
- commit,
567
- recorded,
568
- claims: checklist.claims.filter((c) => localIds.has(c.id)).map((c) => c.id),
569
- // Filed with the attestation, not the record: the report is one
570
- // repository's run, and it is pruned or retained with that repository's
571
- // answers rather than outliving them.
572
- ...(report === undefined ? {} : { report }),
573
- },
574
- ].sort((a, b) => a.service.localeCompare(b.service));
575
- const confirmed = claims.filter((claim) => claim.verdict === "confirmed").length;
576
- const unconfirmed = claims.length - confirmed;
577
- const unanswered = checklist.claims.length - claims.length;
578
- // Everything the old record answered that the new one does not. The caller
579
- // prints it; nothing here decides it is acceptable.
580
- const discarded = (previous?.claims ?? [])
581
- .filter((claim) => !byId.has(claim.id))
582
- .map((claim) => ({
583
- id: claim.id,
584
- claim: claim.claim,
585
- ...(claim.subject === undefined ? {} : { subject: claim.subject }),
586
- reason: currentById.has(claim.id) ? "unattested" : "off-checklist",
587
- }));
588
- return {
589
- verification: {
590
- schema: 2,
591
- feature: checklist.feature,
592
- recorded,
593
- checklist: checklist.digest,
594
- summary: { claims: checklist.claims.length, confirmed, unconfirmed, unanswered },
595
- claims,
596
- attestations,
597
- },
598
- discarded,
599
- };
600
- }
601
- /**
602
- * The record as a file. The header explains what the reader is looking at,
603
- * because the whole point is that this is legible to someone who has never run
604
- * loam — including the part loam cannot vouch for.
605
- */
606
- export function renderVerification(v) {
607
- const header = [
608
- `# Verification record for ${v.feature} — written by \`loam verify ${v.feature}\` (--results / --record).`,
609
- "#",
610
- "# Every claim below was derived mechanically from this feature's own artifacts:",
611
- "# delta.likec4, specs/<svc>/spec.md, specs/<svc>/arch.spec.md and specs/<svc>/",
612
- "# openapi.yaml. Each verdict names who answered it: `answered_by: runner` means a",
613
- "# cucumber JSON report's digest-tagged scenarios answered it mechanically;",
614
- "# `answered_by: agent` means somebody's word about the code, which loam did not",
615
- "# check. Nothing gates on either.",
616
- "#",
617
- "# A `scenario.tested` claim confirmed by an agent is ATTESTED, not run: loam",
618
- "# reports it as `verify.scenario-attested` and the feature does not count as",
619
- "# verified until a report answers it. `report:` records the file a --results run",
620
- "# read — its sha256 and mtime say WHICH file, not that it came from that commit;",
621
- "# no digest can say that.",
622
- "#",
623
- "# `checklist` is a digest of the claim ids. If `loam verify` stops reporting the same",
624
- "# one, the feature changed after this was recorded and these answers are stale.",
625
- ...(v.schema === 2
626
- ? [
627
- "#",
628
- "# Schema 2 is federated: each service entry under `attestations` binds its claim ids",
629
- "# and file:line evidence to that repository's git commit. Missing claims are honestly",
630
- "# unanswered; another service run may add them without rewriting existing attestations.",
631
- ]
632
- : []),
633
- "",
634
- ].join("\n");
635
- // lineWidth 0: never fold a claim onto a second line — these are grepped and diffed.
636
- return header + stringify(v, { lineWidth: 0 });
637
- }
638
- export async function readVerificationState(featureDir) {
639
- const path = verificationPath(featureDir);
640
- if (!existsSync(path))
641
- return { state: "absent" };
642
- let text;
643
- try {
644
- text = await readFile(path, "utf8");
645
- }
646
- catch (err) {
647
- return { state: "unreadable", reason: err instanceof Error ? err.message : String(err) };
648
- }
649
- let doc;
650
- try {
651
- doc = parse(text);
652
- }
653
- catch (err) {
654
- return { state: "unreadable", reason: yamlReason(err) };
655
- }
656
- const verification = asVerification(doc);
657
- if (verification === null) {
658
- return {
659
- state: "unreadable",
660
- reason: "it parses as YAML but does not have a verification record's shape (feature, recorded, checklist, summary and claims)",
661
- };
662
- }
663
- const miscount = summaryDisagreement(verification);
664
- if (miscount === null)
665
- return { state: "ok", verification };
666
- return {
667
- state: "unreadable",
668
- // Spelled twice on purpose: the field is what a caller branches on, the
669
- // prose is what a terminal prints and what somebody greps for.
670
- code: "verify.record-miscounted",
671
- reason: `verify.record-miscounted: ${miscount}`,
672
- };
673
- }
674
- /**
675
- * Does the record's `summary` add up from its own `claims[]`?
676
- *
677
- * The summary is what wrote the file; the claims are what it answered. Nothing
678
- * ever compared them, so every reader that took the shortcut — verify's frozen
679
- * verdict for a shipped feature, list's column, status's block — reported a
680
- * record full of unconfirmed claims as fully confirmed. Believing either side
681
- * over the other would be a guess about which half was tampered with, so a
682
- * record that contradicts itself is refused like any other file loam cannot
683
- * use. The code is in the reason: it travels wherever the reason is printed.
684
- */
685
- function summaryDisagreement(v) {
686
- const t = tallyAnswers(v.claims);
687
- const unanswered = v.summary.unanswered ?? 0;
688
- const says = [];
689
- if (v.summary.confirmed !== t.confirmed) {
690
- says.push(`says ${v.summary.confirmed} confirmed where claims[] holds ${t.confirmed}`);
691
- }
692
- if (v.summary.unconfirmed !== t.unconfirmed) {
693
- says.push(`says ${v.summary.unconfirmed} unconfirmed where claims[] holds ${t.unconfirmed}`);
694
- }
695
- if (v.summary.claims !== v.claims.length + unanswered) {
696
- says.push(`says ${v.summary.claims} claim(s)${unanswered === 0 ? "" : ` including ${unanswered} unanswered`} where claims[] holds ${v.claims.length}`);
697
- }
698
- return says.length === 0
699
- ? null
700
- : `its summary ${says.join(", ")} — the record contradicts itself, so neither half can be believed`;
701
- }
702
- /** A YAML failure with its line, when the parser located one: that line is the fix. */
703
- function yamlReason(err) {
704
- const message = err instanceof Error ? err.message.split("\n")[0].trim() : String(err);
705
- const pos = err?.linePos;
706
- const line = Array.isArray(pos) ? pos[0]?.line : undefined;
707
- return line === undefined ? `YAML error: ${message}` : `YAML error at line ${line}: ${message}`;
708
- }
709
- /**
710
- * The record beside a feature, or null when there is none loam can use. Kept
711
- * for readers that have nothing to say about the difference (`loam list`'s
712
- * verification column shows one glyph either way); anything that WRITES must
713
- * use {@link readVerificationState} instead, or it overwrites what it could not
714
- * read.
715
- *
716
- * A record whose summary contradicts its own claims is one of the nulls now, so
717
- * no reader can print its counts as fact. Reading it as ABSENT is the safe half
718
- * of the truth and not the whole of it: a reader that can say why should take
719
- * {@link readVerificationState} and its `code`.
720
- */
721
- export async function readVerification(featureDir) {
722
- const read = await readVerificationState(featureDir);
723
- return read.state === "ok" ? read.verification : null;
724
- }
725
- /**
726
- * The shape check `readVerification` stands behind: everything its readers
727
- * dereference (verify's report/frozen views, list's verification column) must
728
- * be present and typed, or the cast would manufacture a Verification that
729
- * crashes them. Deliberately no tighter than the readers need: extra keys pass
730
- * (a human may annotate), `answered_by` stays optional (absent in records that
731
- * predate `--results`) and is any string, like `kind` — the readers only ever
732
- * compare them, and a record written by a newer loam must not read as absent.
733
- */
734
- function asVerification(doc) {
735
- if (!isRecord(doc))
736
- return null;
737
- const summary = doc["summary"];
738
- if (typeof doc["feature"] !== "string" ||
739
- typeof doc["recorded"] !== "string" ||
740
- typeof doc["checklist"] !== "string" ||
741
- !isRecord(summary) ||
742
- !isCount(summary["claims"]) ||
743
- !isCount(summary["confirmed"]) ||
744
- !isCount(summary["unconfirmed"]) ||
745
- (summary["unanswered"] !== undefined && !isCount(summary["unanswered"])) ||
746
- !Array.isArray(doc["claims"])) {
747
- return null;
748
- }
749
- for (const c of doc["claims"]) {
750
- if (!isRecord(c))
751
- return null;
752
- if (typeof c["id"] !== "string" || typeof c["kind"] !== "string" || typeof c["claim"] !== "string")
753
- return null;
754
- if (c["subject"] !== undefined && typeof c["subject"] !== "string")
755
- return null;
756
- if (typeof c["verdict"] !== "string" || !VERDICTS.includes(c["verdict"]))
757
- return null;
758
- // The frozen view iterates evidence per claim — a scalar here would crash it.
759
- if (!Array.isArray(c["evidence"]) || c["evidence"].some((e) => typeof e !== "string"))
760
- return null;
761
- if (c["note"] !== undefined && typeof c["note"] !== "string")
762
- return null;
763
- if (c["answered_by"] !== undefined && typeof c["answered_by"] !== "string")
764
- return null;
765
- }
766
- if (doc["schema"] !== undefined && doc["schema"] !== 2)
767
- return null;
768
- if (!isConsumedReport(doc["report"]))
769
- return null;
770
- if (doc["attestations"] !== undefined) {
771
- if (!Array.isArray(doc["attestations"]))
772
- return null;
773
- for (const a of doc["attestations"]) {
774
- if (!isRecord(a))
775
- return null;
776
- if (typeof a["service"] !== "string" || typeof a["commit"] !== "string" || typeof a["recorded"] !== "string")
777
- return null;
778
- if (!/^[0-9a-f]{40,64}$/i.test(a["commit"]))
779
- return null;
780
- if (!Array.isArray(a["claims"]) || a["claims"].some((id) => typeof id !== "string"))
781
- return null;
782
- if (!isConsumedReport(a["report"]))
783
- return null;
784
- }
785
- }
786
- return doc;
787
- }
788
- /** Absent is fine — most records answer nothing from a report. Present must be whole: it is printed. */
789
- function isConsumedReport(v) {
790
- if (v === undefined)
791
- return true;
792
- return (isRecord(v) &&
793
- typeof v["path"] === "string" &&
794
- typeof v["digest"] === "string" &&
795
- typeof v["mtime"] === "string" &&
796
- isCount(v["scenarios"]));
797
- }
798
- /** A summary count: a finite number. YAML hands back strings for anything quoted. */
799
- function isCount(v) {
800
- return typeof v === "number" && Number.isFinite(v);
801
- }
802
- export async function writeVerification(featureDir, v) {
803
- const path = verificationPath(featureDir);
804
- await writeFile(path, renderVerification(v), "utf8");
805
- return path;
806
- }
807
- //# sourceMappingURL=verify.js.map