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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1256) hide show
  1. package/CHANGELOG.md +5992 -82
  2. package/COMPARISON.md +168 -63
  3. package/CONTRIBUTING.md +121 -0
  4. package/MIGRATING-from-OpenSpec.md +238 -55
  5. package/QUICKSTART.md +302 -0
  6. package/README.md +653 -144
  7. package/ROADMAP.md +1035 -0
  8. package/SCHEMA.md +3916 -263
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +927 -0
  11. package/dist/cli.js +133 -21
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +204 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +309 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +74 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/closing.js +42 -0
  20. package/dist/commands/archive/closing.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
  22. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  23. package/dist/commands/archive/plan/contracts/consumers.js +56 -0
  24. package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
  25. package/dist/commands/archive/plan/contracts/openapi.js +193 -0
  26. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  27. package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
  28. package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
  29. package/dist/commands/archive/plan/document/head.js +151 -0
  30. package/dist/commands/archive/plan/document/head.js.map +1 -0
  31. package/dist/commands/archive/plan/document/links.js +284 -0
  32. package/dist/commands/archive/plan/document/links.js.map +1 -0
  33. package/dist/commands/archive/plan/document/run.js +136 -0
  34. package/dist/commands/archive/plan/document/run.js.map +1 -0
  35. package/dist/commands/archive/plan/gate.js +319 -0
  36. package/dist/commands/archive/plan/gate.js.map +1 -0
  37. package/dist/commands/archive/plan/landscape.js +298 -0
  38. package/dist/commands/archive/plan/landscape.js.map +1 -0
  39. package/dist/commands/archive/plan/model/extending.js +85 -0
  40. package/dist/commands/archive/plan/model/extending.js.map +1 -0
  41. package/dist/commands/archive/plan/refusal.js +106 -0
  42. package/dist/commands/archive/plan/refusal.js.map +1 -0
  43. package/dist/commands/archive/plan/specs.js +318 -0
  44. package/dist/commands/archive/plan/specs.js.map +1 -0
  45. package/dist/commands/archive/plan/state.js +30 -0
  46. package/dist/commands/archive/plan/state.js.map +1 -0
  47. package/dist/commands/archive/run.js +355 -0
  48. package/dist/commands/archive/run.js.map +1 -0
  49. package/dist/commands/archive/shipped.js +49 -0
  50. package/dist/commands/archive/shipped.js.map +1 -0
  51. package/dist/commands/context/context.js +166 -0
  52. package/dist/commands/context/context.js.map +1 -0
  53. package/dist/commands/context/print.js +305 -0
  54. package/dist/commands/context/print.js.map +1 -0
  55. package/dist/commands/delta/delta.js +367 -0
  56. package/dist/commands/delta/delta.js.map +1 -0
  57. package/dist/commands/delta/print.js +221 -0
  58. package/dist/commands/delta/print.js.map +1 -0
  59. package/dist/commands/dependencies.js +6 -8
  60. package/dist/commands/dependencies.js.map +1 -1
  61. package/dist/commands/diff/diff.js +86 -0
  62. package/dist/commands/diff/diff.js.map +1 -0
  63. package/dist/commands/diff/print.js +38 -0
  64. package/dist/commands/diff/print.js.map +1 -0
  65. package/dist/commands/doctor.js +65 -5
  66. package/dist/commands/doctor.js.map +1 -1
  67. package/dist/commands/explain/explain.js +227 -0
  68. package/dist/commands/explain/explain.js.map +1 -0
  69. package/dist/commands/explore.js +39 -28
  70. package/dist/commands/explore.js.map +1 -1
  71. package/dist/commands/gate/gate.js +152 -0
  72. package/dist/commands/gate/gate.js.map +1 -0
  73. package/dist/commands/gate/print.js +66 -0
  74. package/dist/commands/gate/print.js.map +1 -0
  75. package/dist/commands/gherkin/commit.js +105 -0
  76. package/dist/commands/gherkin/commit.js.map +1 -0
  77. package/dist/commands/gherkin/gherkin.js +262 -0
  78. package/dist/commands/gherkin/gherkin.js.map +1 -0
  79. package/dist/commands/gherkin/reconcile.js +146 -0
  80. package/dist/commands/gherkin/reconcile.js.map +1 -0
  81. package/dist/commands/gherkin/render.js +77 -0
  82. package/dist/commands/gherkin/render.js.map +1 -0
  83. package/dist/commands/init/example.js +204 -0
  84. package/dist/commands/init/example.js.map +1 -0
  85. package/dist/commands/init/first-hour.js +72 -0
  86. package/dist/commands/init/first-hour.js.map +1 -0
  87. package/dist/commands/{init.js → init/init.js} +142 -71
  88. package/dist/commands/init/init.js.map +1 -0
  89. package/dist/commands/init/mcp.js +131 -0
  90. package/dist/commands/init/mcp.js.map +1 -0
  91. package/dist/commands/init/options.js +78 -0
  92. package/dist/commands/init/options.js.map +1 -0
  93. package/dist/commands/instructions.js +72 -14
  94. package/dist/commands/instructions.js.map +1 -1
  95. package/dist/commands/list/campaign/campaign.js +63 -0
  96. package/dist/commands/list/campaign/campaign.js.map +1 -0
  97. package/dist/commands/list/campaign/owners.js +65 -0
  98. package/dist/commands/list/campaign/owners.js.map +1 -0
  99. package/dist/commands/list/json.js +155 -0
  100. package/dist/commands/list/json.js.map +1 -0
  101. package/dist/commands/list/list.js +358 -0
  102. package/dist/commands/list/list.js.map +1 -0
  103. package/dist/commands/list/print.js +344 -0
  104. package/dist/commands/list/print.js.map +1 -0
  105. package/dist/commands/list/review.js +120 -0
  106. package/dist/commands/list/review.js.map +1 -0
  107. package/dist/commands/list/suites/suites.js +140 -0
  108. package/dist/commands/list/suites/suites.js.map +1 -0
  109. package/dist/commands/list/views.js +108 -0
  110. package/dist/commands/list/views.js.map +1 -0
  111. package/dist/commands/mcp/dispatch.js +238 -0
  112. package/dist/commands/mcp/dispatch.js.map +1 -0
  113. package/dist/commands/mcp/mcp.js +75 -0
  114. package/dist/commands/mcp/mcp.js.map +1 -0
  115. package/dist/commands/mcp/serve.js +55 -0
  116. package/dist/commands/mcp/serve.js.map +1 -0
  117. package/dist/commands/migrate-openspec/materialize/active.js +175 -0
  118. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  119. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  120. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  121. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  122. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  123. package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
  124. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  125. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  126. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  127. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  128. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  129. package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
  130. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  131. package/dist/commands/migrate-openspec/openspec/error.js +18 -0
  132. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  133. package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
  134. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  135. package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
  136. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  137. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  138. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  139. package/dist/commands/migrate-openspec/print.js +89 -0
  140. package/dist/commands/migrate-openspec/print.js.map +1 -0
  141. package/dist/commands/new/capability-template.js +118 -0
  142. package/dist/commands/new/capability-template.js.map +1 -0
  143. package/dist/commands/new/commit.js +62 -0
  144. package/dist/commands/new/commit.js.map +1 -0
  145. package/dist/commands/new/modifies.js +206 -0
  146. package/dist/commands/new/modifies.js.map +1 -0
  147. package/dist/commands/new/new.js +328 -0
  148. package/dist/commands/new/new.js.map +1 -0
  149. package/dist/commands/new/templates.js +279 -0
  150. package/dist/commands/new/templates.js.map +1 -0
  151. package/dist/commands/open.js +199 -0
  152. package/dist/commands/open.js.map +1 -0
  153. package/dist/commands/policy/format.js +152 -0
  154. package/dist/commands/policy/format.js.map +1 -0
  155. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
  156. package/dist/commands/policy/gate.js.map +1 -0
  157. package/dist/commands/rebase/edit.js +106 -0
  158. package/dist/commands/rebase/edit.js.map +1 -0
  159. package/dist/commands/rebase/living.js +185 -0
  160. package/dist/commands/rebase/living.js.map +1 -0
  161. package/dist/commands/rebase/plan.js +245 -0
  162. package/dist/commands/rebase/plan.js.map +1 -0
  163. package/dist/commands/rebase/rebase.js +300 -0
  164. package/dist/commands/rebase/rebase.js.map +1 -0
  165. package/dist/commands/seed/commit.js +221 -0
  166. package/dist/commands/seed/commit.js.map +1 -0
  167. package/dist/commands/seed/plan.js +278 -0
  168. package/dist/commands/seed/plan.js.map +1 -0
  169. package/dist/commands/seed/seed.js +174 -0
  170. package/dist/commands/seed/seed.js.map +1 -0
  171. package/dist/commands/show/feature.js +182 -0
  172. package/dist/commands/show/feature.js.map +1 -0
  173. package/dist/commands/show/introduced.js +157 -0
  174. package/dist/commands/show/introduced.js.map +1 -0
  175. package/dist/commands/show/marks.js +53 -0
  176. package/dist/commands/show/marks.js.map +1 -0
  177. package/dist/commands/show/service.js +239 -0
  178. package/dist/commands/show/service.js.map +1 -0
  179. package/dist/commands/show/show.js +87 -0
  180. package/dist/commands/show/show.js.map +1 -0
  181. package/dist/commands/status/fleet-next.js +90 -0
  182. package/dist/commands/status/fleet-next.js.map +1 -0
  183. package/dist/commands/status/json.js +47 -0
  184. package/dist/commands/status/json.js.map +1 -0
  185. package/dist/commands/status/print.js +209 -0
  186. package/dist/commands/status/print.js.map +1 -0
  187. package/dist/commands/status/status.js +115 -0
  188. package/dist/commands/status/status.js.map +1 -0
  189. package/dist/commands/steps/steps.js +269 -0
  190. package/dist/commands/steps/steps.js.map +1 -0
  191. package/dist/commands/subsystem/edit.js +192 -0
  192. package/dist/commands/subsystem/edit.js.map +1 -0
  193. package/dist/commands/subsystem/move.js +325 -0
  194. package/dist/commands/subsystem/move.js.map +1 -0
  195. package/dist/commands/subsystem/query.js +113 -0
  196. package/dist/commands/subsystem/query.js.map +1 -0
  197. package/dist/commands/subsystem/subsystem.js +98 -0
  198. package/dist/commands/subsystem/subsystem.js.map +1 -0
  199. package/dist/commands/subsystem/sync.js +318 -0
  200. package/dist/commands/subsystem/sync.js.map +1 -0
  201. package/dist/commands/subsystem/txn/exclude.js +132 -0
  202. package/dist/commands/subsystem/txn/exclude.js.map +1 -0
  203. package/dist/commands/subsystem/txn/links.js +128 -0
  204. package/dist/commands/subsystem/txn/links.js.map +1 -0
  205. package/dist/commands/subsystem/txn/report.js +174 -0
  206. package/dist/commands/subsystem/txn/report.js.map +1 -0
  207. package/dist/commands/subsystem/txn/txn.js +196 -0
  208. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  209. package/dist/commands/subsystem/txn/views.js +249 -0
  210. package/dist/commands/subsystem/txn/views.js.map +1 -0
  211. package/dist/commands/tasks/actions.js +107 -0
  212. package/dist/commands/tasks/actions.js.map +1 -0
  213. package/dist/commands/tasks/render.js +253 -0
  214. package/dist/commands/tasks/render.js.map +1 -0
  215. package/dist/commands/tasks/tasks.js +119 -0
  216. package/dist/commands/tasks/tasks.js.map +1 -0
  217. package/dist/commands/unarchive/manifest.js +176 -0
  218. package/dist/commands/unarchive/manifest.js.map +1 -0
  219. package/dist/commands/unarchive/restore.js +254 -0
  220. package/dist/commands/unarchive/restore.js.map +1 -0
  221. package/dist/commands/unarchive/unarchive.js +59 -0
  222. package/dist/commands/unarchive/unarchive.js.map +1 -0
  223. package/dist/commands/validate/arch-coverage.js +245 -0
  224. package/dist/commands/validate/arch-coverage.js.map +1 -0
  225. package/dist/commands/validate/checks/fleet-shape.js +204 -0
  226. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  227. package/dist/commands/validate/checks/health-deps.js +58 -0
  228. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  229. package/dist/commands/validate/checks/introduced.js +102 -0
  230. package/dist/commands/validate/checks/introduced.js.map +1 -0
  231. package/dist/commands/validate/checks/requirements.js +264 -0
  232. package/dist/commands/validate/checks/requirements.js.map +1 -0
  233. package/dist/commands/validate/checks/sources.js +85 -0
  234. package/dist/commands/validate/checks/sources.js.map +1 -0
  235. package/dist/commands/validate/coverage/covers-after.js +105 -0
  236. package/dist/commands/validate/coverage/covers-after.js.map +1 -0
  237. package/dist/commands/validate/feature.js +222 -0
  238. package/dist/commands/validate/feature.js.map +1 -0
  239. package/dist/commands/validate/fleet/census.js +93 -0
  240. package/dist/commands/validate/fleet/census.js.map +1 -0
  241. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  242. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  243. package/dist/commands/validate/fleet/landscape.js +371 -0
  244. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  245. package/dist/commands/validate/fleet/load.js +118 -0
  246. package/dist/commands/validate/fleet/load.js.map +1 -0
  247. package/dist/commands/validate/fleet/map/attest.js +98 -0
  248. package/dist/commands/validate/fleet/map/attest.js.map +1 -0
  249. package/dist/commands/validate/fleet/map/bindings.js +107 -0
  250. package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
  251. package/dist/commands/validate/fleet/map/consumers.js +244 -0
  252. package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
  253. package/dist/commands/validate/fleet/map/isolation.js +116 -0
  254. package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
  255. package/dist/commands/validate/fleet/map/usecases.js +54 -0
  256. package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
  257. package/dist/commands/validate/fleet/obligations.js +266 -0
  258. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  259. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  260. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  261. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  262. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  263. package/dist/commands/validate/fleet/scorecard/print.js +71 -0
  264. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  265. package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
  266. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  267. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  268. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  269. package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
  270. package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
  271. package/dist/commands/validate/fleet/views/ids.js +75 -0
  272. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  273. package/dist/commands/validate/fleet/views/projects.js +278 -0
  274. package/dist/commands/validate/fleet/views/projects.js.map +1 -0
  275. package/dist/commands/validate/fleet/views/root-documents.js +83 -0
  276. package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
  277. package/dist/commands/validate/fleet/views/stale.js +52 -0
  278. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  279. package/dist/commands/validate/links/corpus.js +89 -0
  280. package/dist/commands/validate/links/corpus.js.map +1 -0
  281. package/dist/commands/validate/links/glossary.js +75 -0
  282. package/dist/commands/validate/links/glossary.js.map +1 -0
  283. package/dist/commands/validate/render/repeats.js +63 -0
  284. package/dist/commands/validate/render/repeats.js.map +1 -0
  285. package/dist/commands/validate/render/rollups.js +115 -0
  286. package/dist/commands/validate/render/rollups.js.map +1 -0
  287. package/dist/commands/validate/render/text.js +199 -0
  288. package/dist/commands/validate/render/text.js.map +1 -0
  289. package/dist/commands/validate/report.js +145 -0
  290. package/dist/commands/validate/report.js.map +1 -0
  291. package/dist/commands/validate/scope.js +113 -0
  292. package/dist/commands/validate/scope.js.map +1 -0
  293. package/dist/commands/validate/service/api.js +252 -0
  294. package/dist/commands/validate/service/api.js.map +1 -0
  295. package/dist/commands/validate/service/contracts/generated.js +134 -0
  296. package/dist/commands/validate/service/contracts/generated.js.map +1 -0
  297. package/dist/commands/validate/service/events/events.js +241 -0
  298. package/dist/commands/validate/service/events/events.js.map +1 -0
  299. package/dist/commands/validate/service/events/message-producers.js +77 -0
  300. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  301. package/dist/commands/validate/service/evidence-pins.js +177 -0
  302. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  303. package/dist/commands/validate/service/model/diverged.js +226 -0
  304. package/dist/commands/validate/service/model/diverged.js.map +1 -0
  305. package/dist/commands/validate/service/model/grade.js +163 -0
  306. package/dist/commands/validate/service/model/grade.js.map +1 -0
  307. package/dist/commands/validate/service/service.js +310 -0
  308. package/dist/commands/validate/service/service.js.map +1 -0
  309. package/dist/commands/validate/service/specs.js +279 -0
  310. package/dist/commands/validate/service/specs.js.map +1 -0
  311. package/dist/commands/validate/service/spine.js +148 -0
  312. package/dist/commands/validate/service/spine.js.map +1 -0
  313. package/dist/commands/validate/service/usecases/tags.js +113 -0
  314. package/dist/commands/validate/service/usecases/tags.js.map +1 -0
  315. package/dist/commands/validate/service/usecases/usecases.js +209 -0
  316. package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
  317. package/dist/commands/validate/validate.js +363 -0
  318. package/dist/commands/validate/validate.js.map +1 -0
  319. package/dist/commands/verify/cross/diff.js +178 -0
  320. package/dist/commands/verify/cross/diff.js.map +1 -0
  321. package/dist/commands/verify/evidence/contract.js +32 -0
  322. package/dist/commands/verify/evidence/contract.js.map +1 -0
  323. package/dist/commands/verify/evidence/pins.js +52 -0
  324. package/dist/commands/verify/evidence/pins.js.map +1 -0
  325. package/dist/commands/verify/evidence/read.js +81 -0
  326. package/dist/commands/verify/evidence/read.js.map +1 -0
  327. package/dist/commands/verify/frozen.js +263 -0
  328. package/dist/commands/verify/frozen.js.map +1 -0
  329. package/dist/commands/verify/record.js +278 -0
  330. package/dist/commands/verify/record.js.map +1 -0
  331. package/dist/commands/verify/report.js +206 -0
  332. package/dist/commands/verify/report.js.map +1 -0
  333. package/dist/commands/verify/results.js +328 -0
  334. package/dist/commands/verify/results.js.map +1 -0
  335. package/dist/commands/verify/verify.js +220 -0
  336. package/dist/commands/verify/verify.js.map +1 -0
  337. package/dist/commands/vouch/contract.js +11 -0
  338. package/dist/commands/vouch/contract.js.map +1 -0
  339. package/dist/commands/vouch/pack/contract.js +2 -0
  340. package/dist/commands/vouch/pack/contract.js.map +1 -0
  341. package/dist/commands/vouch/pack/pack.js +266 -0
  342. package/dist/commands/vouch/pack/pack.js.map +1 -0
  343. package/dist/commands/vouch/pack/print.js +266 -0
  344. package/dist/commands/vouch/pack/print.js.map +1 -0
  345. package/dist/commands/vouch/pack/sections.js +141 -0
  346. package/dist/commands/vouch/pack/sections.js.map +1 -0
  347. package/dist/commands/vouch/prompt/confirm.js +46 -0
  348. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  349. package/dist/commands/vouch/report.js +101 -0
  350. package/dist/commands/vouch/report.js.map +1 -0
  351. package/dist/commands/vouch/run.js +230 -0
  352. package/dist/commands/vouch/run.js.map +1 -0
  353. package/dist/commands/vouch/sample/plan.js +111 -0
  354. package/dist/commands/vouch/sample/plan.js.map +1 -0
  355. package/dist/commands/vouch/sample/print.js +109 -0
  356. package/dist/commands/vouch/sample/print.js.map +1 -0
  357. package/dist/commands/vouch/vet/verify.js +155 -0
  358. package/dist/commands/vouch/vet/verify.js.map +1 -0
  359. package/dist/commands/vouch/vouch.js +169 -0
  360. package/dist/commands/vouch/vouch.js.map +1 -0
  361. package/dist/core/agent/agents-md/command-map.js +299 -0
  362. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  363. package/dist/core/agent/agents-md/map/explain.js +46 -0
  364. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  365. package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
  366. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  367. package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
  368. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  369. package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
  370. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  371. package/dist/core/agent/agents-md/map/mcp.js +44 -0
  372. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  373. package/dist/core/agent/agents-md/map/status.js +78 -0
  374. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  375. package/dist/core/agent/agents-md/map/subsystem.js +104 -0
  376. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  377. package/dist/core/agent/agents-md/map/usecases.js +138 -0
  378. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  379. package/dist/core/agent/agents-md/refusals.js +273 -0
  380. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  381. package/dist/core/agent/agents-md.js +203 -0
  382. package/dist/core/agent/agents-md.js.map +1 -0
  383. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
  384. package/dist/core/agent/agents-stamp.js.map +1 -0
  385. package/dist/core/agent/contract.js +2 -0
  386. package/dist/core/agent/contract.js.map +1 -0
  387. package/dist/core/agent/protocol.js +193 -0
  388. package/dist/core/agent/protocol.js.map +1 -0
  389. package/dist/core/agent/scaffold.js +254 -0
  390. package/dist/core/agent/scaffold.js.map +1 -0
  391. package/dist/core/agent/support/report.js +144 -0
  392. package/dist/core/agent/support/report.js.map +1 -0
  393. package/dist/core/agent/tools/dialects.js +151 -0
  394. package/dist/core/agent/tools/dialects.js.map +1 -0
  395. package/dist/core/agent/tools/registry.js +193 -0
  396. package/dist/core/agent/tools/registry.js.map +1 -0
  397. package/dist/core/agent/workflows/adopt.js +280 -0
  398. package/dist/core/agent/workflows/adopt.js.map +1 -0
  399. package/dist/core/agent/workflows/check.js +373 -0
  400. package/dist/core/agent/workflows/check.js.map +1 -0
  401. package/dist/core/agent/workflows/closing.js +323 -0
  402. package/dist/core/agent/workflows/closing.js.map +1 -0
  403. package/dist/core/agent/workflows/feature.js +220 -0
  404. package/dist/core/agent/workflows/feature.js.map +1 -0
  405. package/dist/core/agent/workflows/implement.js +188 -0
  406. package/dist/core/agent/workflows/implement.js.map +1 -0
  407. package/dist/core/agent/workflows/reference/authoring.js +311 -0
  408. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  409. package/dist/core/agent/workflows/reference/codes.js +67 -0
  410. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  411. package/dist/core/agent/workflows/reference/done-check.js +210 -0
  412. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  413. package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
  414. package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
  415. package/dist/core/agent/workflows/reference/reference.js +19 -0
  416. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  417. package/dist/core/agent/workflows/reference/spine.js +338 -0
  418. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  419. package/dist/core/asyncapi/baseline/plan.js +43 -0
  420. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  421. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  422. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  423. package/dist/core/asyncapi/depth.js +164 -0
  424. package/dist/core/asyncapi/depth.js.map +1 -0
  425. package/dist/core/asyncapi/digest.js +146 -0
  426. package/dist/core/asyncapi/digest.js.map +1 -0
  427. package/dist/core/asyncapi/merge/components.js +92 -0
  428. package/dist/core/asyncapi/merge/components.js.map +1 -0
  429. package/dist/core/asyncapi/merge/error.js +38 -0
  430. package/dist/core/asyncapi/merge/error.js.map +1 -0
  431. package/dist/core/asyncapi/merge/markers.js +290 -0
  432. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  433. package/dist/core/asyncapi/merge/merge.js +195 -0
  434. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  435. package/dist/core/asyncapi/merge/pin.js +83 -0
  436. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  437. package/dist/core/asyncapi/model.js +11 -0
  438. package/dist/core/asyncapi/model.js.map +1 -0
  439. package/dist/core/asyncapi/producers.js +50 -0
  440. package/dist/core/asyncapi/producers.js.map +1 -0
  441. package/dist/core/asyncapi/read.js +263 -0
  442. package/dist/core/asyncapi/read.js.map +1 -0
  443. package/dist/core/brief/brief.js +285 -0
  444. package/dist/core/brief/brief.js.map +1 -0
  445. package/dist/core/brief/checks.js +385 -0
  446. package/dist/core/brief/checks.js.map +1 -0
  447. package/dist/core/brief/landscape.js +273 -0
  448. package/dist/core/brief/landscape.js.map +1 -0
  449. package/dist/core/brief/map/extend.js +84 -0
  450. package/dist/core/brief/map/extend.js.map +1 -0
  451. package/dist/core/brief/map/owed.js +266 -0
  452. package/dist/core/brief/map/owed.js.map +1 -0
  453. package/dist/core/brief/targets.js +304 -0
  454. package/dist/core/brief/targets.js.map +1 -0
  455. package/dist/core/brief/unchecked.js +58 -0
  456. package/dist/core/brief/unchecked.js.map +1 -0
  457. package/dist/core/c4/arch.js +190 -0
  458. package/dist/core/c4/arch.js.map +1 -0
  459. package/dist/core/c4/direction/direction.js +114 -0
  460. package/dist/core/c4/direction/direction.js.map +1 -0
  461. package/dist/core/c4/likec4.js +243 -0
  462. package/dist/core/c4/likec4.js.map +1 -0
  463. package/dist/core/c4/locate/unlocated.js +150 -0
  464. package/dist/core/c4/locate/unlocated.js.map +1 -0
  465. package/dist/core/c4/parsed/deployment.js +160 -0
  466. package/dist/core/c4/parsed/deployment.js.map +1 -0
  467. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  468. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  469. package/dist/core/c4/parsed/specification.js +78 -0
  470. package/dist/core/c4/parsed/specification.js.map +1 -0
  471. package/dist/core/c4/parsed/values.js +110 -0
  472. package/dist/core/c4/parsed/values.js.map +1 -0
  473. package/dist/core/c4/parsed/view-ids.js +113 -0
  474. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  475. package/dist/core/c4/prefetch/fleet.js +134 -0
  476. package/dist/core/c4/prefetch/fleet.js.map +1 -0
  477. package/dist/core/c4/project/architecture.js +161 -0
  478. package/dist/core/c4/project/architecture.js.map +1 -0
  479. package/dist/core/c4/project/batch.js +140 -0
  480. package/dist/core/c4/project/batch.js.map +1 -0
  481. package/dist/core/c4/project/documents.js +89 -0
  482. package/dist/core/c4/project/documents.js.map +1 -0
  483. package/dist/core/c4/project/load.js +219 -0
  484. package/dist/core/c4/project/load.js.map +1 -0
  485. package/dist/core/c4/project/staged.js +277 -0
  486. package/dist/core/c4/project/staged.js.map +1 -0
  487. package/dist/core/c4/resolve/attested.js +0 -0
  488. package/dist/core/c4/resolve/attested.js.map +1 -0
  489. package/dist/core/c4/resolve/external.js +51 -0
  490. package/dist/core/c4/resolve/external.js.map +1 -0
  491. package/dist/core/c4/resolve/service.js +174 -0
  492. package/dist/core/c4/resolve/service.js.map +1 -0
  493. package/dist/core/c4/resolve/steps.js +290 -0
  494. package/dist/core/c4/resolve/steps.js.map +1 -0
  495. package/dist/core/c4/resolve/systems.js +154 -0
  496. package/dist/core/c4/resolve/systems.js.map +1 -0
  497. package/dist/core/c4/root-project/exclude.js +352 -0
  498. package/dist/core/c4/root-project/exclude.js.map +1 -0
  499. package/dist/core/c4/seed/fleet-file.js +201 -0
  500. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  501. package/dist/core/c4/seed/items.js +91 -0
  502. package/dist/core/c4/seed/items.js.map +1 -0
  503. package/dist/core/c4/seed/stamp.js +48 -0
  504. package/dist/core/c4/seed/stamp.js.map +1 -0
  505. package/dist/core/c4/seed/template.js +173 -0
  506. package/dist/core/c4/seed/template.js.map +1 -0
  507. package/dist/core/c4/service-model/created/models.js +96 -0
  508. package/dist/core/c4/service-model/created/models.js.map +1 -0
  509. package/dist/core/c4/service-model/documents.js +47 -0
  510. package/dist/core/c4/service-model/documents.js.map +1 -0
  511. package/dist/core/c4/service-model/fleet/extending.js +82 -0
  512. package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
  513. package/dist/core/c4/service-model/load.js +165 -0
  514. package/dist/core/c4/service-model/load.js.map +1 -0
  515. package/dist/core/c4/service-model/renderer.js +128 -0
  516. package/dist/core/c4/service-model/renderer.js.map +1 -0
  517. package/dist/core/c4/service-model/shape.js +106 -0
  518. package/dist/core/c4/service-model/shape.js.map +1 -0
  519. package/dist/core/c4/service-model/slice.js +188 -0
  520. package/dist/core/c4/service-model/slice.js.map +1 -0
  521. package/dist/core/c4/source-mask.js +369 -0
  522. package/dist/core/c4/source-mask.js.map +1 -0
  523. package/dist/core/c4/source-scan.js +308 -0
  524. package/dist/core/c4/source-scan.js.map +1 -0
  525. package/dist/core/c4/splice/authored-source.js +167 -0
  526. package/dist/core/c4/splice/authored-source.js.map +1 -0
  527. package/dist/core/c4/splice/contract.js +30 -0
  528. package/dist/core/c4/splice/contract.js.map +1 -0
  529. package/dist/core/c4/splice/delta-blocks.js +126 -0
  530. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  531. package/dist/core/c4/splice/identity/declared.js +87 -0
  532. package/dist/core/c4/splice/identity/declared.js.map +1 -0
  533. package/dist/core/c4/splice/identity/edges.js +73 -0
  534. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  535. package/dist/core/c4/splice/identity/existing.js +80 -0
  536. package/dist/core/c4/splice/identity/existing.js.map +1 -0
  537. package/dist/core/c4/splice/identity/interior.js +80 -0
  538. package/dist/core/c4/splice/identity/interior.js.map +1 -0
  539. package/dist/core/c4/splice/identity/owner.js +50 -0
  540. package/dist/core/c4/splice/identity/owner.js.map +1 -0
  541. package/dist/core/c4/splice/landscape-merge.js +337 -0
  542. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  543. package/dist/core/c4/splice/model/merge.js +151 -0
  544. package/dist/core/c4/splice/model/merge.js.map +1 -0
  545. package/dist/core/c4/splice/placement.js +298 -0
  546. package/dist/core/c4/splice/placement.js.map +1 -0
  547. package/dist/core/c4/splice/text/spot.js +131 -0
  548. package/dist/core/c4/splice/text/spot.js.map +1 -0
  549. package/dist/core/c4/workspace.js +166 -0
  550. package/dist/core/c4/workspace.js.map +1 -0
  551. package/dist/core/capabilities/authoring/notes.js +141 -0
  552. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  553. package/dist/core/capabilities/capabilities.js +124 -0
  554. package/dist/core/capabilities/capabilities.js.map +1 -0
  555. package/dist/core/capabilities/delta/doc.js +47 -0
  556. package/dist/core/capabilities/delta/doc.js.map +1 -0
  557. package/dist/core/capabilities/delta/overlay.js +129 -0
  558. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  559. package/dist/core/capabilities/delta/summary.js +57 -0
  560. package/dist/core/capabilities/delta/summary.js.map +1 -0
  561. package/dist/core/capabilities/delta/tree.js +43 -0
  562. package/dist/core/capabilities/delta/tree.js.map +1 -0
  563. package/dist/core/capabilities/delta/uncovered.js +222 -0
  564. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  565. package/dist/core/capabilities/findings.js +338 -0
  566. package/dist/core/capabilities/findings.js.map +1 -0
  567. package/dist/core/capabilities/realizes/findings.js +174 -0
  568. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  569. package/dist/core/capabilities/realizes/join.js +123 -0
  570. package/dist/core/capabilities/realizes/join.js.map +1 -0
  571. package/dist/core/capabilities/rollup.js +205 -0
  572. package/dist/core/capabilities/rollup.js.map +1 -0
  573. package/dist/core/capabilities/tree.js +104 -0
  574. package/dist/core/capabilities/tree.js.map +1 -0
  575. package/dist/core/capabilities/usecase-join.js +267 -0
  576. package/dist/core/capabilities/usecase-join.js.map +1 -0
  577. package/dist/core/coherence/authoring/scaffold.js +185 -0
  578. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  579. package/dist/core/coherence/authoring/sentinels.js +75 -0
  580. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  581. package/dist/core/coherence/calls/called.js +52 -0
  582. package/dist/core/coherence/calls/called.js.map +1 -0
  583. package/dist/core/coherence/coherence.js +332 -0
  584. package/dist/core/coherence/coherence.js.map +1 -0
  585. package/dist/core/coherence/consumed/operations.js +70 -0
  586. package/dist/core/coherence/consumed/operations.js.map +1 -0
  587. package/dist/core/coherence/consumed/refusal.js +38 -0
  588. package/dist/core/coherence/consumed/refusal.js.map +1 -0
  589. package/dist/core/coherence/covers/health.js +85 -0
  590. package/dist/core/coherence/covers/health.js.map +1 -0
  591. package/dist/core/coherence/declared.js +295 -0
  592. package/dist/core/coherence/declared.js.map +1 -0
  593. package/dist/core/coherence/events/declared.js +191 -0
  594. package/dist/core/coherence/events/declared.js.map +1 -0
  595. package/dist/core/coherence/events/events.js +335 -0
  596. package/dist/core/coherence/events/events.js.map +1 -0
  597. package/dist/core/coherence/events/grades.js +189 -0
  598. package/dist/core/coherence/events/grades.js.map +1 -0
  599. package/dist/core/coherence/events/lookups.js +63 -0
  600. package/dist/core/coherence/events/lookups.js.map +1 -0
  601. package/dist/core/coherence/events/produced.js +100 -0
  602. package/dist/core/coherence/events/produced.js.map +1 -0
  603. package/dist/core/coherence/living.js +198 -0
  604. package/dist/core/coherence/living.js.map +1 -0
  605. package/dist/core/coherence/lookups.js +95 -0
  606. package/dist/core/coherence/lookups.js.map +1 -0
  607. package/dist/core/coherence/pending.js +39 -0
  608. package/dist/core/coherence/pending.js.map +1 -0
  609. package/dist/core/coherence/retired/archived.js +285 -0
  610. package/dist/core/coherence/retired/archived.js.map +1 -0
  611. package/dist/core/coherence/retired/event-pair.js +62 -0
  612. package/dist/core/coherence/retired/event-pair.js.map +1 -0
  613. package/dist/core/coherence/retired/merged.js +79 -0
  614. package/dist/core/coherence/retired/merged.js.map +1 -0
  615. package/dist/core/coherence/retired/retirement.js +49 -0
  616. package/dist/core/coherence/retired/retirement.js.map +1 -0
  617. package/dist/core/coherence/retired/revival/arrivals.js +131 -0
  618. package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
  619. package/dist/core/coherence/retired/revival/revived.js +297 -0
  620. package/dist/core/coherence/retired/revival/revived.js.map +1 -0
  621. package/dist/core/conflict-markers.js +60 -0
  622. package/dist/core/conflict-markers.js.map +1 -0
  623. package/dist/core/consumers/after.js +113 -0
  624. package/dist/core/consumers/after.js.map +1 -0
  625. package/dist/core/consumers/consumers.js +296 -0
  626. package/dist/core/consumers/consumers.js.map +1 -0
  627. package/dist/core/consumers/current.js +211 -0
  628. package/dist/core/consumers/current.js.map +1 -0
  629. package/dist/core/consumers/scan.js +46 -0
  630. package/dist/core/consumers/scan.js.map +1 -0
  631. package/dist/core/consumers/state.js +27 -0
  632. package/dist/core/consumers/state.js.map +1 -0
  633. package/dist/core/delta/claims.js +73 -0
  634. package/dist/core/delta/claims.js.map +1 -0
  635. package/dist/core/delta/delta.js +341 -0
  636. package/dist/core/delta/delta.js.map +1 -0
  637. package/dist/core/delta/document.js +177 -0
  638. package/dist/core/delta/document.js.map +1 -0
  639. package/dist/core/delta/scope.js +48 -0
  640. package/dist/core/delta/scope.js.map +1 -0
  641. package/dist/core/delta/select.js +237 -0
  642. package/dist/core/delta/select.js.map +1 -0
  643. package/dist/core/dependencies/dependencies.js +141 -0
  644. package/dist/core/dependencies/dependencies.js.map +1 -0
  645. package/dist/core/dependencies/facts.js +165 -0
  646. package/dist/core/dependencies/facts.js.map +1 -0
  647. package/dist/core/dependencies/fanin.js +88 -0
  648. package/dist/core/dependencies/fanin.js.map +1 -0
  649. package/dist/core/dependencies/graph.js +106 -0
  650. package/dist/core/dependencies/graph.js.map +1 -0
  651. package/dist/core/deployment/delta.js +191 -0
  652. package/dist/core/deployment/delta.js.map +1 -0
  653. package/dist/core/deployment/objects.js +145 -0
  654. package/dist/core/deployment/objects.js.map +1 -0
  655. package/dist/core/diff/base-git.js +230 -0
  656. package/dist/core/diff/base-git.js.map +1 -0
  657. package/dist/core/diff/base-state.js +237 -0
  658. package/dist/core/diff/base-state.js.map +1 -0
  659. package/dist/core/diff/joins.js +136 -0
  660. package/dist/core/diff/joins.js.map +1 -0
  661. package/dist/core/diff/scope/changed-paths.js +204 -0
  662. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  663. package/dist/core/diff/scope/edges.js +82 -0
  664. package/dist/core/diff/scope/edges.js.map +1 -0
  665. package/dist/core/diff/semantic.js +312 -0
  666. package/dist/core/diff/semantic.js.map +1 -0
  667. package/dist/core/docs.js +37 -85
  668. package/dist/core/docs.js.map +1 -1
  669. package/dist/core/doctor/agents.js +238 -0
  670. package/dist/core/doctor/agents.js.map +1 -0
  671. package/dist/core/doctor/config.js +139 -0
  672. package/dist/core/doctor/config.js.map +1 -0
  673. package/dist/core/doctor/doctor.js +355 -0
  674. package/dist/core/doctor/doctor.js.map +1 -0
  675. package/dist/core/doctor/report.js +13 -0
  676. package/dist/core/doctor/report.js.map +1 -0
  677. package/dist/core/doctor/reports/scan.js +242 -0
  678. package/dist/core/doctor/reports/scan.js.map +1 -0
  679. package/dist/core/doctor/residue.js +110 -0
  680. package/dist/core/doctor/residue.js.map +1 -0
  681. package/dist/core/document/apply.js +224 -0
  682. package/dist/core/document/apply.js.map +1 -0
  683. package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
  684. package/dist/core/document/frontmatter.js.map +1 -0
  685. package/dist/core/document/grammar/directives.js +143 -0
  686. package/dist/core/document/grammar/directives.js.map +1 -0
  687. package/dist/core/document/parse.js +286 -0
  688. package/dist/core/document/parse.js.map +1 -0
  689. package/dist/core/document/scenarios.js +238 -0
  690. package/dist/core/document/scenarios.js.map +1 -0
  691. package/dist/core/document/spec.js +234 -0
  692. package/dist/core/document/spec.js.map +1 -0
  693. package/dist/core/{config.js → envelope/config.js} +89 -18
  694. package/dist/core/envelope/config.js.map +1 -0
  695. package/dist/core/envelope/json.js +209 -0
  696. package/dist/core/envelope/json.js.map +1 -0
  697. package/dist/core/{version.js → envelope/version.js} +3 -3
  698. package/dist/core/envelope/version.js.map +1 -0
  699. package/dist/core/explain/families.js +180 -0
  700. package/dist/core/explain/families.js.map +1 -0
  701. package/dist/core/explain/fix-tables.js +178 -0
  702. package/dist/core/explain/fix-tables.js.map +1 -0
  703. package/dist/core/explain/lookup.js +194 -0
  704. package/dist/core/explain/lookup.js.map +1 -0
  705. package/dist/core/explain/refusals.js +49 -0
  706. package/dist/core/explain/refusals.js.map +1 -0
  707. package/dist/core/explain/terms/documents.js +227 -0
  708. package/dist/core/explain/terms/documents.js.map +1 -0
  709. package/dist/core/explain/terms/done-check.js +144 -0
  710. package/dist/core/explain/terms/done-check.js.map +1 -0
  711. package/dist/core/explain/terms/entry.js +14 -0
  712. package/dist/core/explain/terms/entry.js.map +1 -0
  713. package/dist/core/explain/terms/stages.js +71 -0
  714. package/dist/core/explain/terms/stages.js.map +1 -0
  715. package/dist/core/explain/terms/tasks.js +97 -0
  716. package/dist/core/explain/terms/tasks.js.map +1 -0
  717. package/dist/core/explain/terms.js +103 -0
  718. package/dist/core/explain/terms.js.map +1 -0
  719. package/dist/core/explore/describe.js +105 -0
  720. package/dist/core/explore/describe.js.map +1 -0
  721. package/dist/core/explore/explore.js +204 -0
  722. package/dist/core/explore/explore.js.map +1 -0
  723. package/dist/core/fleet-context.js +174 -146
  724. package/dist/core/fleet-context.js.map +1 -1
  725. package/dist/core/gate/checks.js +208 -0
  726. package/dist/core/gate/checks.js.map +1 -0
  727. package/dist/core/gate/partners.js +246 -0
  728. package/dist/core/gate/partners.js.map +1 -0
  729. package/dist/core/gate/report.js +47 -0
  730. package/dist/core/gate/report.js.map +1 -0
  731. package/dist/core/gate/verification.js +176 -0
  732. package/dist/core/gate/verification.js.map +1 -0
  733. package/dist/core/gherkin/digest.js +60 -0
  734. package/dist/core/gherkin/digest.js.map +1 -0
  735. package/dist/core/gherkin/emit.js +177 -0
  736. package/dist/core/gherkin/emit.js.map +1 -0
  737. package/dist/core/gherkin/read.js +76 -0
  738. package/dist/core/gherkin/read.js.map +1 -0
  739. package/dist/core/gherkin/stale.js +210 -0
  740. package/dist/core/gherkin/stale.js.map +1 -0
  741. package/dist/core/gherkin/stamp.js +77 -0
  742. package/dist/core/gherkin/stamp.js.map +1 -0
  743. package/dist/core/gherkin/steps/catalogue.js +154 -0
  744. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  745. package/dist/core/gherkin/steps/inventory.js +98 -0
  746. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  747. package/dist/core/gherkin/steps/phrase.js +72 -0
  748. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  749. package/dist/core/glossary/delta.js +109 -0
  750. package/dist/core/glossary/delta.js.map +1 -0
  751. package/dist/core/glossary/tree.js +73 -0
  752. package/dist/core/glossary/tree.js.map +1 -0
  753. package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
  754. package/dist/core/kernel/concurrency.js.map +1 -0
  755. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  756. package/dist/core/kernel/document-bytes.js.map +1 -0
  757. package/dist/core/kernel/fences.js +42 -0
  758. package/dist/core/kernel/fences.js.map +1 -0
  759. package/dist/core/kernel/ids/capability.js +72 -0
  760. package/dist/core/kernel/ids/capability.js.map +1 -0
  761. package/dist/core/kernel/ids/dirs.js +33 -0
  762. package/dist/core/kernel/ids/dirs.js.map +1 -0
  763. package/dist/core/kernel/ids/feature.js +75 -0
  764. package/dist/core/kernel/ids/feature.js.map +1 -0
  765. package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
  766. package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
  767. package/dist/core/kernel/ids/service.js +156 -0
  768. package/dist/core/kernel/ids/service.js.map +1 -0
  769. package/dist/core/kernel/ids/subsystem.js +63 -0
  770. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  771. package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
  772. package/dist/core/kernel/path-safety.js.map +1 -0
  773. package/dist/core/{records.js → kernel/records.js} +11 -0
  774. package/dist/core/kernel/records.js.map +1 -0
  775. package/dist/core/links/backlinks.js +66 -0
  776. package/dist/core/links/backlinks.js.map +1 -0
  777. package/dist/core/links/case.js +74 -0
  778. package/dist/core/links/case.js.map +1 -0
  779. package/dist/core/links/corpus.js +118 -0
  780. package/dist/core/links/corpus.js.map +1 -0
  781. package/dist/core/links/findings.js +110 -0
  782. package/dist/core/links/findings.js.map +1 -0
  783. package/dist/core/links/parse.js +265 -0
  784. package/dist/core/links/parse.js.map +1 -0
  785. package/dist/core/mcp/argv.js +212 -0
  786. package/dist/core/mcp/argv.js.map +1 -0
  787. package/dist/core/mcp/author-tools.js +73 -0
  788. package/dist/core/mcp/author-tools.js.map +1 -0
  789. package/dist/core/mcp/framing.js +46 -0
  790. package/dist/core/mcp/framing.js.map +1 -0
  791. package/dist/core/mcp/protocol.js +280 -0
  792. package/dist/core/mcp/protocol.js.map +1 -0
  793. package/dist/core/mcp/tools.js +324 -0
  794. package/dist/core/mcp/tools.js.map +1 -0
  795. package/dist/core/obligations/obligations.js +106 -0
  796. package/dist/core/obligations/obligations.js.map +1 -0
  797. package/dist/core/openapi/baseline/gate.js +207 -0
  798. package/dist/core/openapi/baseline/gate.js.map +1 -0
  799. package/dist/core/openapi/baseline/plan.js +142 -0
  800. package/dist/core/openapi/baseline/plan.js.map +1 -0
  801. package/dist/core/openapi/baseline/record.js +174 -0
  802. package/dist/core/openapi/baseline/record.js.map +1 -0
  803. package/dist/core/openapi/contract-text.js +33 -0
  804. package/dist/core/openapi/contract-text.js.map +1 -0
  805. package/dist/core/openapi/contract-tree.js +301 -0
  806. package/dist/core/openapi/contract-tree.js.map +1 -0
  807. package/dist/core/openapi/depth.js +136 -0
  808. package/dist/core/openapi/depth.js.map +1 -0
  809. package/dist/core/openapi/digest.js +239 -0
  810. package/dist/core/openapi/digest.js.map +1 -0
  811. package/dist/core/{openapi.js → openapi/doc.js} +54 -108
  812. package/dist/core/openapi/doc.js.map +1 -0
  813. package/dist/core/openapi/merge/components.js +199 -0
  814. package/dist/core/openapi/merge/components.js.map +1 -0
  815. package/dist/core/openapi/merge/error.js +16 -0
  816. package/dist/core/openapi/merge/error.js.map +1 -0
  817. package/dist/core/openapi/merge/markers.js +204 -0
  818. package/dist/core/openapi/merge/markers.js.map +1 -0
  819. package/dist/core/openapi/merge/merge.js +232 -0
  820. package/dist/core/openapi/merge/merge.js.map +1 -0
  821. package/dist/core/openapi/merge/pin.js +110 -0
  822. package/dist/core/openapi/merge/pin.js.map +1 -0
  823. package/dist/core/openspec/decide/capabilities.js +244 -0
  824. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  825. package/dist/core/openspec/decide/dispositions.js +63 -0
  826. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  827. package/dist/core/openspec/decide/renames.js +179 -0
  828. package/dist/core/openspec/decide/renames.js.map +1 -0
  829. package/dist/core/openspec/decide/verdict.js +84 -0
  830. package/dist/core/openspec/decide/verdict.js.map +1 -0
  831. package/dist/core/openspec/inventory.js +220 -0
  832. package/dist/core/openspec/inventory.js.map +1 -0
  833. package/dist/core/openspec/model/mapping.js +78 -0
  834. package/dist/core/openspec/model/mapping.js.map +1 -0
  835. package/dist/core/openspec/model/model.js +70 -0
  836. package/dist/core/openspec/model/model.js.map +1 -0
  837. package/dist/core/openspec/scan/changes.js +241 -0
  838. package/dist/core/openspec/scan/changes.js.map +1 -0
  839. package/dist/core/openspec/scan/config.js +191 -0
  840. package/dist/core/openspec/scan/config.js.map +1 -0
  841. package/dist/core/openspec/scan/shape.js +304 -0
  842. package/dist/core/openspec/scan/shape.js.map +1 -0
  843. package/dist/core/openspec/scan/walk.js +116 -0
  844. package/dist/core/openspec/scan/walk.js.map +1 -0
  845. package/dist/core/openspec/scan/workspace.js +71 -0
  846. package/dist/core/openspec/scan/workspace.js.map +1 -0
  847. package/dist/core/owners/codeowners.js +141 -0
  848. package/dist/core/owners/codeowners.js.map +1 -0
  849. package/dist/core/pack/features.js +120 -0
  850. package/dist/core/pack/features.js.map +1 -0
  851. package/dist/core/pack/joins.js +112 -0
  852. package/dist/core/pack/joins.js.map +1 -0
  853. package/dist/core/pack/living.js +157 -0
  854. package/dist/core/pack/living.js.map +1 -0
  855. package/dist/core/pack/pack.js +120 -0
  856. package/dist/core/pack/pack.js.map +1 -0
  857. package/dist/core/permissions/permissions.js +87 -0
  858. package/dist/core/permissions/permissions.js.map +1 -0
  859. package/dist/core/projection/api.js +84 -0
  860. package/dist/core/projection/api.js.map +1 -0
  861. package/dist/core/projection/arch-slice.js +63 -0
  862. package/dist/core/projection/arch-slice.js.map +1 -0
  863. package/dist/core/projection/events.js +34 -0
  864. package/dist/core/projection/events.js.map +1 -0
  865. package/dist/core/projection/introduced.js +14 -0
  866. package/dist/core/projection/introduced.js.map +1 -0
  867. package/dist/core/provenance/findings.js +244 -0
  868. package/dist/core/provenance/findings.js.map +1 -0
  869. package/dist/core/provenance/git.js +201 -0
  870. package/dist/core/provenance/git.js.map +1 -0
  871. package/dist/core/provenance/gitq/moves.js +139 -0
  872. package/dist/core/provenance/gitq/moves.js.map +1 -0
  873. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  874. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  875. package/dist/core/provenance/sample/scope.js +238 -0
  876. package/dist/core/provenance/sample/scope.js.map +1 -0
  877. package/dist/core/provenance/sample/sections.js +61 -0
  878. package/dist/core/provenance/sample/sections.js.map +1 -0
  879. package/dist/core/provenance/sources.js +280 -0
  880. package/dist/core/provenance/sources.js.map +1 -0
  881. package/dist/core/provenance/stamp.js +220 -0
  882. package/dist/core/provenance/stamp.js.map +1 -0
  883. package/dist/core/provenance/walk.js +157 -0
  884. package/dist/core/provenance/walk.js.map +1 -0
  885. package/dist/core/repo/authored/paths.js +210 -0
  886. package/dist/core/repo/authored/paths.js.map +1 -0
  887. package/dist/core/repo/entries.js +126 -0
  888. package/dist/core/repo/entries.js.map +1 -0
  889. package/dist/core/repo/paths.js +322 -0
  890. package/dist/core/repo/paths.js.map +1 -0
  891. package/dist/core/repo/repo.js +308 -0
  892. package/dist/core/repo/repo.js.map +1 -0
  893. package/dist/core/repo/service-target.js +153 -0
  894. package/dist/core/repo/service-target.js.map +1 -0
  895. package/dist/core/repo/state.js +58 -0
  896. package/dist/core/repo/state.js.map +1 -0
  897. package/dist/core/repo/tree/find.js +61 -0
  898. package/dist/core/repo/tree/find.js.map +1 -0
  899. package/dist/core/repo/tree/fs.js +90 -0
  900. package/dist/core/repo/tree/fs.js.map +1 -0
  901. package/dist/core/repo/tree/marker.js +61 -0
  902. package/dist/core/repo/tree/marker.js.map +1 -0
  903. package/dist/core/repo/tree/render/body.js +258 -0
  904. package/dist/core/repo/tree/render/body.js.map +1 -0
  905. package/dist/core/repo/tree/render/projects.js +182 -0
  906. package/dist/core/repo/tree/render/projects.js.map +1 -0
  907. package/dist/core/repo/tree/render/service/header.js +125 -0
  908. package/dist/core/repo/tree/render/service/header.js.map +1 -0
  909. package/dist/core/repo/tree/render/service/peers.js +28 -0
  910. package/dist/core/repo/tree/render/service/peers.js.map +1 -0
  911. package/dist/core/repo/tree/render/service/view-id.js +67 -0
  912. package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
  913. package/dist/core/repo/tree/render/service/views.js +78 -0
  914. package/dist/core/repo/tree/render/service/views.js.map +1 -0
  915. package/dist/core/repo/tree/render/stale.js +42 -0
  916. package/dist/core/repo/tree/render/stale.js.map +1 -0
  917. package/dist/core/repo/tree/render/text.js +84 -0
  918. package/dist/core/repo/tree/render/text.js.map +1 -0
  919. package/dist/core/repo/tree/render/views.js +293 -0
  920. package/dist/core/repo/tree/render/views.js.map +1 -0
  921. package/dist/core/repo/tree/walk.js +255 -0
  922. package/dist/core/repo/tree/walk.js.map +1 -0
  923. package/dist/core/results.js +146 -14
  924. package/dist/core/results.js.map +1 -1
  925. package/dist/core/scaffold/landscape.js +239 -0
  926. package/dist/core/scaffold/landscape.js.map +1 -0
  927. package/dist/core/scaffold/legacy.js +271 -0
  928. package/dist/core/scaffold/legacy.js.map +1 -0
  929. package/dist/core/scaffold/readme.js +84 -0
  930. package/dist/core/scaffold/readme.js.map +1 -0
  931. package/dist/core/staging/commit.js +252 -0
  932. package/dist/core/staging/commit.js.map +1 -0
  933. package/dist/core/staging/interrupted.js +96 -0
  934. package/dist/core/staging/interrupted.js.map +1 -0
  935. package/dist/core/staging/lock.js +268 -0
  936. package/dist/core/staging/lock.js.map +1 -0
  937. package/dist/core/staging/recovery/finding.js +35 -0
  938. package/dist/core/staging/recovery/finding.js.map +1 -0
  939. package/dist/core/staging/recovery/intent.js +95 -0
  940. package/dist/core/staging/recovery/intent.js.map +1 -0
  941. package/dist/core/staging/recovery/recover.js +204 -0
  942. package/dist/core/staging/recovery/recover.js.map +1 -0
  943. package/dist/core/staging/recovery/residue.js +62 -0
  944. package/dist/core/staging/recovery/residue.js.map +1 -0
  945. package/dist/core/staging/snapshot/manifest.js +188 -0
  946. package/dist/core/staging/snapshot/manifest.js.map +1 -0
  947. package/dist/core/staging/snapshot/snapshot.js +196 -0
  948. package/dist/core/staging/snapshot/snapshot.js.map +1 -0
  949. package/dist/core/staging/txn/forward.js +181 -0
  950. package/dist/core/staging/txn/forward.js.map +1 -0
  951. package/dist/core/staging/txn/journal.js +139 -0
  952. package/dist/core/staging/txn/journal.js.map +1 -0
  953. package/dist/core/staging/txn/transaction.js +75 -0
  954. package/dist/core/staging/txn/transaction.js.map +1 -0
  955. package/dist/core/staging/writes.js +113 -0
  956. package/dist/core/staging/writes.js.map +1 -0
  957. package/dist/core/status/actions/execution.js +60 -0
  958. package/dist/core/status/actions/execution.js.map +1 -0
  959. package/dist/core/status/contracts.js +126 -0
  960. package/dist/core/status/contracts.js.map +1 -0
  961. package/dist/core/status/feature/artifacts.js +196 -0
  962. package/dist/core/status/feature/artifacts.js.map +1 -0
  963. package/dist/core/status/feature/feature.js +214 -0
  964. package/dist/core/status/feature/feature.js.map +1 -0
  965. package/dist/core/status/feature/next.js +163 -0
  966. package/dist/core/status/feature/next.js.map +1 -0
  967. package/dist/core/status/feature/state.js +21 -0
  968. package/dist/core/status/feature/state.js.map +1 -0
  969. package/dist/core/status/feature/words.js +96 -0
  970. package/dist/core/status/feature/words.js.map +1 -0
  971. package/dist/core/status/fleet/fleet.js +216 -0
  972. package/dist/core/status/fleet/fleet.js.map +1 -0
  973. package/dist/core/status/fleet/next.js +302 -0
  974. package/dist/core/status/fleet/next.js.map +1 -0
  975. package/dist/core/status/interrupted.js +97 -0
  976. package/dist/core/status/interrupted.js.map +1 -0
  977. package/dist/core/status/report.js +31 -0
  978. package/dist/core/status/report.js.map +1 -0
  979. package/dist/core/status/scan.js +41 -0
  980. package/dist/core/status/scan.js.map +1 -0
  981. package/dist/core/status/verification.js +216 -0
  982. package/dist/core/status/verification.js.map +1 -0
  983. package/dist/core/tasks/packet.js +199 -0
  984. package/dist/core/tasks/packet.js.map +1 -0
  985. package/dist/core/tasks/record.js +43 -0
  986. package/dist/core/tasks/record.js.map +1 -0
  987. package/dist/core/tasks/sources.js +181 -0
  988. package/dist/core/tasks/sources.js.map +1 -0
  989. package/dist/core/tasks/stamps.js +76 -0
  990. package/dist/core/tasks/stamps.js.map +1 -0
  991. package/dist/core/tasks/unit.js +0 -0
  992. package/dist/core/tasks/unit.js.map +1 -0
  993. package/dist/core/usecases/capability.js +166 -0
  994. package/dist/core/usecases/capability.js.map +1 -0
  995. package/dist/core/usecases/delta/claims.js +140 -0
  996. package/dist/core/usecases/delta/claims.js.map +1 -0
  997. package/dist/core/usecases/delta/flows.js +101 -0
  998. package/dist/core/usecases/delta/flows.js.map +1 -0
  999. package/dist/core/usecases/delta/modified.js +315 -0
  1000. package/dist/core/usecases/delta/modified.js.map +1 -0
  1001. package/dist/core/usecases/delta/overlay.js +76 -0
  1002. package/dist/core/usecases/delta/overlay.js.map +1 -0
  1003. package/dist/core/usecases/fleet.js +296 -0
  1004. package/dist/core/usecases/fleet.js.map +1 -0
  1005. package/dist/core/usecases/grade/capability-tag.js +93 -0
  1006. package/dist/core/usecases/grade/capability-tag.js.map +1 -0
  1007. package/dist/core/usecases/grade/feature.js +88 -0
  1008. package/dist/core/usecases/grade/feature.js.map +1 -0
  1009. package/dist/core/usecases/grade/requirement-tag.js +94 -0
  1010. package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
  1011. package/dist/core/usecases/grade/steps.js +266 -0
  1012. package/dist/core/usecases/grade/steps.js.map +1 -0
  1013. package/dist/core/usecases/grade/usecases.js +112 -0
  1014. package/dist/core/usecases/grade/usecases.js.map +1 -0
  1015. package/dist/core/usecases/operations.js +123 -0
  1016. package/dist/core/usecases/operations.js.map +1 -0
  1017. package/dist/core/usecases/place.js +44 -0
  1018. package/dist/core/usecases/place.js.map +1 -0
  1019. package/dist/core/usecases/service/exclude.js +119 -0
  1020. package/dist/core/usecases/service/exclude.js.map +1 -0
  1021. package/dist/core/usecases/service/flows.js +164 -0
  1022. package/dist/core/usecases/service/flows.js.map +1 -0
  1023. package/dist/core/usecases/suites/participants.js +83 -0
  1024. package/dist/core/usecases/suites/participants.js.map +1 -0
  1025. package/dist/core/usecases/suites/suites.js +45 -0
  1026. package/dist/core/usecases/suites/suites.js.map +1 -0
  1027. package/dist/core/usecases/touch.js +101 -0
  1028. package/dist/core/usecases/touch.js.map +1 -0
  1029. package/dist/core/verify/answers.js +180 -0
  1030. package/dist/core/verify/answers.js.map +1 -0
  1031. package/dist/core/verify/build.js +170 -0
  1032. package/dist/core/verify/build.js.map +1 -0
  1033. package/dist/core/verify/checklist.js +259 -0
  1034. package/dist/core/verify/checklist.js.map +1 -0
  1035. package/dist/core/verify/claims/identity.js +61 -0
  1036. package/dist/core/verify/claims/identity.js.map +1 -0
  1037. package/dist/core/verify/cross/diff.js +97 -0
  1038. package/dist/core/verify/cross/diff.js.map +1 -0
  1039. package/dist/core/verify/evidence/contract.js +169 -0
  1040. package/dist/core/verify/evidence/contract.js.map +1 -0
  1041. package/dist/core/verify/location.js +67 -0
  1042. package/dist/core/verify/location.js.map +1 -0
  1043. package/dist/core/verify/pins/lint.js +158 -0
  1044. package/dist/core/verify/pins/lint.js.map +1 -0
  1045. package/dist/core/verify/pins/pin.js +95 -0
  1046. package/dist/core/verify/pins/pin.js.map +1 -0
  1047. package/dist/core/verify/read/file.js +224 -0
  1048. package/dist/core/verify/read/file.js.map +1 -0
  1049. package/dist/core/verify/read/shape.js +169 -0
  1050. package/dist/core/verify/read/shape.js.map +1 -0
  1051. package/dist/core/verify/read/union.js +105 -0
  1052. package/dist/core/verify/read/union.js.map +1 -0
  1053. package/dist/core/verify/record.js +165 -0
  1054. package/dist/core/verify/record.js.map +1 -0
  1055. package/dist/core/verify/store/commit.js +99 -0
  1056. package/dist/core/verify/store/commit.js.map +1 -0
  1057. package/dist/core/verify/store/render.js +61 -0
  1058. package/dist/core/verify/store/render.js.map +1 -0
  1059. package/dist/core/vocabulary/health.js +91 -0
  1060. package/dist/core/vocabulary/health.js.map +1 -0
  1061. package/dist/core/vocabulary/issue.js +59 -0
  1062. package/dist/core/vocabulary/issue.js.map +1 -0
  1063. package/dist/core/vocabulary/maturity.js +216 -0
  1064. package/dist/core/vocabulary/maturity.js.map +1 -0
  1065. package/dist/core/vocabulary/report.js +90 -0
  1066. package/dist/core/vocabulary/report.js.map +1 -0
  1067. package/dist/core/vocabulary/steps.js +266 -0
  1068. package/dist/core/vocabulary/steps.js.map +1 -0
  1069. package/dist/core/workspace/discover.js +239 -0
  1070. package/dist/core/workspace/discover.js.map +1 -0
  1071. package/dist/core/workspace/render.js +52 -0
  1072. package/dist/core/workspace/render.js.map +1 -0
  1073. package/examples/README.md +232 -0
  1074. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  1075. package/examples/docs/architecture/capabilities.yaml +31 -0
  1076. package/examples/docs/architecture/landscape.likec4 +336 -0
  1077. package/examples/docs/architecture/obligations.yaml +23 -0
  1078. package/examples/docs/architecture/permissions.yaml +50 -0
  1079. package/examples/docs/architecture/services.likec4 +70 -0
  1080. package/examples/docs/architecture/subsystems.likec4 +18 -0
  1081. package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
  1082. package/examples/docs/capabilities/checkout/spec.md +55 -0
  1083. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  1084. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  1085. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  1086. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  1087. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  1088. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  1089. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
  1090. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  1091. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  1092. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  1093. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  1094. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  1095. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
  1096. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  1097. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  1098. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  1099. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  1100. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  1101. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  1102. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  1103. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  1104. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  1105. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  1106. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
  1107. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  1108. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  1109. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  1110. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  1111. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  1112. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  1113. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  1114. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  1115. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  1116. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  1117. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  1118. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  1119. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  1120. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  1121. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  1122. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  1123. package/examples/docs/glossary/order.md +15 -0
  1124. package/examples/docs/glossary/payments/authorization.md +14 -0
  1125. package/examples/docs/likec4.config.json +8 -0
  1126. package/examples/docs/loam.json +3 -0
  1127. package/examples/docs/services/checkout-web/model.likec4 +92 -0
  1128. package/examples/docs/services/checkout-web/spec.md +91 -0
  1129. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  1130. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  1131. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  1132. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  1133. package/examples/docs/services/order-service/arch.spec.md +134 -0
  1134. package/examples/docs/services/order-service/asyncapi.yaml +109 -0
  1135. package/examples/docs/services/order-service/health.yaml +57 -0
  1136. package/examples/docs/services/order-service/model.likec4 +126 -0
  1137. package/examples/docs/services/order-service/openapi.yaml +257 -0
  1138. package/examples/docs/services/order-service/runbook.md +62 -0
  1139. package/examples/docs/services/order-service/spec.md +134 -0
  1140. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  1141. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  1142. package/examples/docs/services/payment-service/arch.spec.md +76 -0
  1143. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  1144. package/examples/docs/services/payment-service/health.yaml +39 -0
  1145. package/examples/docs/services/payment-service/model.likec4 +68 -0
  1146. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  1147. package/examples/docs/services/payment-service/runbook.md +37 -0
  1148. package/examples/docs/services/payment-service/spec.md +88 -0
  1149. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  1150. package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
  1151. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  1152. package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
  1153. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  1154. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  1155. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  1156. package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
  1157. package/examples/docs/services/platform/notification-service/health.yaml +40 -0
  1158. package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
  1159. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  1160. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  1161. package/examples/docs/services/platform/subsystem.yaml +2 -0
  1162. package/examples/fleet.yaml +57 -0
  1163. package/package.json +19 -6
  1164. package/dist/commands/adopt.js +0 -240
  1165. package/dist/commands/adopt.js.map +0 -1
  1166. package/dist/commands/archive.js +0 -1313
  1167. package/dist/commands/archive.js.map +0 -1
  1168. package/dist/commands/delta.js +0 -388
  1169. package/dist/commands/delta.js.map +0 -1
  1170. package/dist/commands/docs-repo-gate.js.map +0 -1
  1171. package/dist/commands/format.js +0 -17
  1172. package/dist/commands/format.js.map +0 -1
  1173. package/dist/commands/gherkin.js +0 -309
  1174. package/dist/commands/gherkin.js.map +0 -1
  1175. package/dist/commands/init.js.map +0 -1
  1176. package/dist/commands/list.js +0 -295
  1177. package/dist/commands/list.js.map +0 -1
  1178. package/dist/commands/migrate-openspec.js +0 -950
  1179. package/dist/commands/migrate-openspec.js.map +0 -1
  1180. package/dist/commands/new.js +0 -413
  1181. package/dist/commands/new.js.map +0 -1
  1182. package/dist/commands/rebase.js +0 -356
  1183. package/dist/commands/rebase.js.map +0 -1
  1184. package/dist/commands/show.js +0 -320
  1185. package/dist/commands/show.js.map +0 -1
  1186. package/dist/commands/status.js +0 -262
  1187. package/dist/commands/status.js.map +0 -1
  1188. package/dist/commands/unarchive.js +0 -317
  1189. package/dist/commands/unarchive.js.map +0 -1
  1190. package/dist/commands/validate.js +0 -1773
  1191. package/dist/commands/validate.js.map +0 -1
  1192. package/dist/commands/verify.js +0 -775
  1193. package/dist/commands/verify.js.map +0 -1
  1194. package/dist/commands/vouch.js +0 -421
  1195. package/dist/commands/vouch.js.map +0 -1
  1196. package/dist/core/agent.js +0 -2173
  1197. package/dist/core/agent.js.map +0 -1
  1198. package/dist/core/agents-stamp.js.map +0 -1
  1199. package/dist/core/arch.js +0 -130
  1200. package/dist/core/arch.js.map +0 -1
  1201. package/dist/core/asyncapi.js +0 -253
  1202. package/dist/core/asyncapi.js.map +0 -1
  1203. package/dist/core/brief.js +0 -755
  1204. package/dist/core/brief.js.map +0 -1
  1205. package/dist/core/coherence.js +0 -577
  1206. package/dist/core/coherence.js.map +0 -1
  1207. package/dist/core/concurrency.js.map +0 -1
  1208. package/dist/core/config.js.map +0 -1
  1209. package/dist/core/delta.js +0 -476
  1210. package/dist/core/delta.js.map +0 -1
  1211. package/dist/core/dependencies.js +0 -356
  1212. package/dist/core/dependencies.js.map +0 -1
  1213. package/dist/core/doctor.js +0 -596
  1214. package/dist/core/doctor.js.map +0 -1
  1215. package/dist/core/document-bytes.js.map +0 -1
  1216. package/dist/core/explore.js +0 -225
  1217. package/dist/core/explore.js.map +0 -1
  1218. package/dist/core/frontmatter.js.map +0 -1
  1219. package/dist/core/gherkin.js +0 -463
  1220. package/dist/core/gherkin.js.map +0 -1
  1221. package/dist/core/health.js +0 -67
  1222. package/dist/core/health.js.map +0 -1
  1223. package/dist/core/ids.js +0 -122
  1224. package/dist/core/ids.js.map +0 -1
  1225. package/dist/core/issue.js +0 -9
  1226. package/dist/core/issue.js.map +0 -1
  1227. package/dist/core/json.js +0 -74
  1228. package/dist/core/json.js.map +0 -1
  1229. package/dist/core/likec4.js +0 -489
  1230. package/dist/core/likec4.js.map +0 -1
  1231. package/dist/core/maturity.js +0 -66
  1232. package/dist/core/maturity.js.map +0 -1
  1233. package/dist/core/openapi-merge.js +0 -552
  1234. package/dist/core/openapi-merge.js.map +0 -1
  1235. package/dist/core/openapi.js.map +0 -1
  1236. package/dist/core/openspec-inventory.js +0 -1440
  1237. package/dist/core/openspec-inventory.js.map +0 -1
  1238. package/dist/core/path-safety.js.map +0 -1
  1239. package/dist/core/provenance.js +0 -787
  1240. package/dist/core/provenance.js.map +0 -1
  1241. package/dist/core/records.js.map +0 -1
  1242. package/dist/core/repo.js +0 -438
  1243. package/dist/core/repo.js.map +0 -1
  1244. package/dist/core/report.js +0 -47
  1245. package/dist/core/report.js.map +0 -1
  1246. package/dist/core/spec.js +0 -505
  1247. package/dist/core/spec.js.map +0 -1
  1248. package/dist/core/staging.js +0 -890
  1249. package/dist/core/staging.js.map +0 -1
  1250. package/dist/core/status.js +0 -1132
  1251. package/dist/core/status.js.map +0 -1
  1252. package/dist/core/steps.js +0 -72
  1253. package/dist/core/steps.js.map +0 -1
  1254. package/dist/core/verify.js +0 -807
  1255. package/dist/core/verify.js.map +0 -1
  1256. package/dist/core/version.js.map +0 -1
@@ -0,0 +1,278 @@
1
+ /**
2
+ * Writing the answers down.
3
+ *
4
+ * The one command in loam that takes somebody's word for something, so every
5
+ * refusal here is about whose word is on the file. The legacy all-at-once form
6
+ * run over a federated record does not merge and does not migrate — it would
7
+ * erase every other service's commit-bound attestation, invisibly, because what
8
+ * replaces it is a well-formed and plausible record.
9
+ */
10
+ import { readFile } from "node:fs/promises";
11
+ import { resolve } from "node:path";
12
+ import { emitJson, fail, repoPath } from "../../core/envelope/json.js";
13
+ import { today } from "../../core/provenance/stamp.js";
14
+ import { runnerAnswers } from "../../core/results.js";
15
+ import { checkAnswers } from "../../core/verify/answers.js";
16
+ import { buildServiceRecord, buildVerification } from "../../core/verify/build.js";
17
+ import {} from "../../core/verify/checklist.js";
18
+ import { contractAnswers } from "../../core/verify/evidence/contract.js";
19
+ import {} from "../../core/verify/read/file.js";
20
+ import { assembleRecord } from "../../core/verify/read/union.js";
21
+ import { commitVerification } from "../../core/verify/store/commit.js";
22
+ import { tallyRecord, verificationVerdict, } from "../../core/verify/record.js";
23
+ import { recordLocation, serviceRecordPath, verificationPath } from "../../core/verify/location.js";
24
+ import { plural, sayDiscarded, sayRecovered } from "../policy/format.js";
25
+ import { readContractResults } from "./evidence/contract.js";
26
+ import { claimTokens, pinAnswers } from "./evidence/pins.js";
27
+ import { readResults, repositoryCommit, validateLocalEvidence, validateServiceEvidence } from "./results.js";
28
+ import { contestedNotices, contestedOperationNotices, contractReportLine, forkedChecklistNotices, noticesFor, reportLine, } from "./frozen.js";
29
+ import {} from "./report.js";
30
+ export async function record(target, checklist, attestor, opts) {
31
+ const { docsDir, featureDir, json } = target;
32
+ const { service, repoDir, previous } = attestor;
33
+ // The legacy all-at-once form answers the WHOLE checklist on one repository's
34
+ // word and writes a schema-1 record — no attestations, no commits. Run over a
35
+ // federated record it does not merge and it does not migrate: over a one-file
36
+ // federated record it would erase every other service's commit-bound
37
+ // attestation, invisibly, because what replaces it is a well-formed,
38
+ // plausible record; beside a `verification/` directory it would write a file
39
+ // whose answers can never count (no attestation binds them) while reporting
40
+ // them as recorded. Either way it refuses, and names the repositories whose
41
+ // word is on the record.
42
+ const attested = previous?.verification.schema === 2 ? (previous.verification.attestations ?? []) : [];
43
+ if (service === undefined && attested.length > 0) {
44
+ const services = [...new Set(attested.map((a) => a.service))].sort();
45
+ return fail(json, "record-federated", `${repoPath(docsDir, recordLocation(featureDir))} is a federated record: ${plural(services.length, "service")} (${services.join(", ")}) have attested claims against their own git commits. ` +
46
+ "Recording without --service would put one unattested answer set over all of it. " +
47
+ `Record this service's claims from its own repo instead: \`loam verify ${checklist.feature} --record answers.json --service <svc>\`.`);
48
+ }
49
+ const scopedClaims = service === undefined ? checklist.claims : checklist.claims.filter((claim) => claim.subject === service);
50
+ if (service !== undefined && scopedClaims.length === 0) {
51
+ return fail(json, "unknown-service", `The current ${checklist.feature} checklist has no claims owned by service '${service}'.`);
52
+ }
53
+ // The mechanical halves: with --results, every scenario.tested claim is the
54
+ // cucumber report's to answer — matched by digest, confirmed only by a green
55
+ // run — and with --contract-results, every api.exposes claim is the contract
56
+ // report's, matched by operationId under the same ownership discipline. A
57
+ // partial suite leaves its unexercised claims unconfirmed rather than
58
+ // agent-attestable in the same run: silence must not read as checked, and
59
+ // the escape is a --record run without the flag.
60
+ const runnerClaims = opts.results === undefined ? [] : scopedClaims.filter((c) => c.kind === "scenario.tested");
61
+ const contractClaims = opts.contractResults === undefined ? [] : scopedClaims.filter((c) => c.kind === "api.exposes");
62
+ const agentClaims = scopedClaims.filter((c) => (opts.results === undefined || c.kind !== "scenario.tested") &&
63
+ (opts.contractResults === undefined || c.kind !== "api.exposes"));
64
+ let fromRunner = [];
65
+ let fromContract = [];
66
+ const reports = {};
67
+ if (opts.results !== undefined) {
68
+ // A federated record attests for THIS repository, so its report has to be a
69
+ // file inside it — see evidence/read.ts.
70
+ const read = await readResults(opts.results, service === undefined ? undefined : repoDir);
71
+ if (!read.ok)
72
+ return fail(json, read.code, read.message);
73
+ reports.results = read.report;
74
+ fromRunner = runnerAnswers(runnerClaims, read.scenarios, read.report.path);
75
+ }
76
+ if (opts.contractResults !== undefined) {
77
+ // Same resolution rules as the cucumber report, same refusal code: the two
78
+ // pins make the same promise about the same repository.
79
+ const read = await readContractResults(opts.contractResults, service === undefined ? undefined : repoDir);
80
+ if (!read.ok)
81
+ return fail(json, read.code, read.message);
82
+ reports.contract = read.report;
83
+ fromContract = contractAnswers(contractClaims, read.runs, read.report.path);
84
+ }
85
+ // The agent's half — exactly what no report owns. A mechanical flag alone is
86
+ // legal only when the reports own the whole checklist: anything left over
87
+ // refuses with the ids, the same discipline as a claim with no answer.
88
+ let raw = [];
89
+ if (opts.record !== undefined) {
90
+ try {
91
+ // The one path that stays cwd-relative, and deliberately: the answer set
92
+ // is a file the caller just wrote and hands to the command, not part of
93
+ // the repository being attested. Nothing on the record points at it.
94
+ raw = JSON.parse(await readFile(resolve(process.cwd(), opts.record), "utf8"));
95
+ }
96
+ catch (err) {
97
+ return fail(json, "answers-unreadable", `Cannot read ${opts.record}: ${err instanceof Error ? err.message : String(err)}`);
98
+ }
99
+ }
100
+ else if (agentClaims.length > 0 && (opts.results !== undefined || opts.contractResults !== undefined)) {
101
+ const owns = [
102
+ ...(opts.results === undefined ? [] : ["--results answers only the scenario.tested claims"]),
103
+ ...(opts.contractResults === undefined ? [] : ["--contract-results answers only the api.exposes claims"]),
104
+ ].join(" and ");
105
+ return fail(json, "answers-mismatch", `${owns}; ${agentClaims.length} claim(s) have no answer: ` +
106
+ `${agentClaims.map((c) => c.id).join(", ")}. Record them with --record <answers.json> alongside.`);
107
+ }
108
+ const checked = checkAnswers(agentClaims, raw, opts.results === undefined && opts.contractResults === undefined
109
+ ? undefined
110
+ : new Set([...runnerClaims, ...contractClaims].map((c) => c.id)), { feature: checklist.feature, ...(service === undefined ? {} : { service }) });
111
+ if (!checked.ok)
112
+ return fail(json, checked.code, checked.message);
113
+ let serviceCommit;
114
+ let answers = [...fromRunner, ...fromContract, ...checked.answers];
115
+ let pinNotice = null;
116
+ if (service !== undefined) {
117
+ const commit = await repositoryCommit(repoDir);
118
+ if (!commit.ok)
119
+ return fail(json, "repository-unavailable", commit.message);
120
+ serviceCommit = commit.commit;
121
+ // All halves, one validator. The runner's evidence used to skip it
122
+ // entirely: `--results` minted confirmations whose evidence strings nothing
123
+ // ever checked, in the one mode that promises every answer is bound to this
124
+ // repository at this commit. The same pass stamps each agent citation's
125
+ // evidence pin and scans its blob for the claim's token (evidence/pins.ts).
126
+ const evidence = await validateServiceEvidence(answers, { repoDir, commit: serviceCommit }, reports, claimTokens(scopedClaims));
127
+ if (!evidence.ok)
128
+ return fail(json, "answers-unevidenced", evidence.message);
129
+ ({ answers, notice: pinNotice } = pinAnswers(answers, evidence, serviceCommit));
130
+ }
131
+ else {
132
+ // The all-at-once form binds to no commit, but a citation still has to be
133
+ // a line that exists — see `validateLocalEvidence`. Resolved against the
134
+ // repository loam.json was found in, which is the one place a reviewer
135
+ // reading this record can go and look.
136
+ const evidence = await validateLocalEvidence(answers, repoDir);
137
+ if (!evidence.ok) {
138
+ return fail(json, "answers-unevidenced", `${evidence.message} The all-at-once form resolves every citation inside this repository; ` +
139
+ "evidence that lives in a service's own repository is recorded from there, with `--service`.");
140
+ }
141
+ }
142
+ const recorded = today(new Date());
143
+ // What goes on disk and what the record reads as afterwards are two
144
+ // different objects now. The all-at-once form IS its file. A service's write
145
+ // is one file among several, so the verdict it prints is the union of the
146
+ // files as they will stand once the commit lands — added up by the very
147
+ // function the next read will use, so this run cannot print a verdict the
148
+ // following `loam verify` disagrees with.
149
+ let verification;
150
+ let writes;
151
+ let discarded = [];
152
+ if (service === undefined) {
153
+ verification = buildVerification(checklist, answers, recorded, reports);
154
+ // The legacy all-at-once form keeps the one file, deliberately. It answers
155
+ // the whole checklist from one place on one word, with no commit and no
156
+ // service, so there is no second writer for it to collide with and no
157
+ // service to name a file after — and every record it ever wrote, the
158
+ // example fleet's included, stays byte-for-byte what it is. The moment a
159
+ // service attests, the refusal above keeps it off the record for good.
160
+ writes = [{ path: verificationPath(featureDir), record: verification, preImage: previous?.files.legacy?.raw ?? null }];
161
+ }
162
+ else {
163
+ // The docs side of the pin, and it is ASKED FOR rather than required: a
164
+ // docs repo is not obliged to be a git checkout, and the attestation simply
165
+ // carries no `docsCommit` when git cannot answer. Failing the record over
166
+ // it would refuse a working fleet for a field that is optional by design.
167
+ const docsHead = await repositoryCommit(docsDir);
168
+ const files = previous?.files ?? { legacy: null, services: new Map() };
169
+ const own = files.services.get(service) ?? null;
170
+ const built = buildServiceRecord(checklist, {
171
+ service,
172
+ recorded,
173
+ commit: serviceCommit,
174
+ reports,
175
+ ...(docsHead.ok ? { docsCommit: docsHead.commit } : {}),
176
+ }, answers, { legacy: files.legacy?.verification ?? null, own: own?.verification ?? null, filed: new Set(files.services.keys()) });
177
+ discarded = built.discarded;
178
+ // This service's own file FIRST — see `commitVerification` for why the
179
+ // order is what a kill between the two renames leaves standing.
180
+ writes = [
181
+ { path: serviceRecordPath(featureDir, service), record: built.record, preImage: own?.raw ?? null },
182
+ ...(built.dropLegacy && files.legacy !== null
183
+ ? [{ path: files.legacy.path, record: null, preImage: files.legacy.raw }]
184
+ : []),
185
+ ];
186
+ const after = new Map([...files.services].map(([svc, file]) => [svc, file.verification]));
187
+ after.set(service, built.record);
188
+ // Added up against THIS checklist — the one the answers just written
189
+ // answer. Left to pick by date, a same-day file with a later service id
190
+ // that answered an older checklist won the tie, and this run printed a
191
+ // tally its own answers were not in (`core/verify/read/union.ts`).
192
+ verification = assembleRecord(built.dropLegacy ? null : (files.legacy?.verification ?? null), [...after.keys()].sort().map((svc) => after.get(svc)), checklist.digest);
193
+ }
194
+ // Staged, compared against the locked read's bytes, swapped in by one
195
+ // rename per file — see core/verify/store/commit.ts for what each refusal
196
+ // means.
197
+ const committed = await commitVerification(writes, docsDir);
198
+ if (!committed.ok)
199
+ return fail(json, committed.code, committed.message);
200
+ const path = writes[0].path;
201
+ const unconfirmed = verification.claims.filter((c) => c.verdict === "unconfirmed");
202
+ // The same judgment read mode makes (see report): the record just written IS
203
+ // the current checklist's answer, so `stale` is false by construction and the
204
+ // remaining question is whether every claim was confirmed — and, now, by
205
+ // whom. Counted from the claims, not from the summary this same call wrote.
206
+ // Without these fields an agent that recorded all-confirmed answers would
207
+ // have to re-run verify just to learn the state it created.
208
+ const tally = tallyRecord(verification);
209
+ const verdict = verificationVerdict(tally);
210
+ const verified = verdict === "verified";
211
+ const notices = [
212
+ ...noticesFor(verification.claims, verification.feature),
213
+ // The read view's notice, on the write that makes it true: a service
214
+ // whose file answered another version of the checklist is named here,
215
+ // because its answers are exactly the ones this tally leaves out.
216
+ ...forkedChecklistNotices(verification, checklist.digest),
217
+ ...contestedNotices(runnerClaims),
218
+ ...contestedOperationNotices(contractClaims),
219
+ ...(pinNotice === null ? [] : [pinNotice]),
220
+ ];
221
+ if (json) {
222
+ emitJson({
223
+ command: "verify",
224
+ feature: verification.feature,
225
+ path: repoPath(docsDir, path),
226
+ ...(target.recovered == null ? {} : { recovered: target.recovered }),
227
+ digest: verification.checklist,
228
+ verified,
229
+ verdict,
230
+ attested: tally.attested,
231
+ recorded: verification.recorded,
232
+ summary: verification.summary,
233
+ ...(verification.attestations === undefined ? {} : { attestations: verification.attestations }),
234
+ ...(reports.results === undefined ? {} : { report: reports.results }),
235
+ ...(reports.contract === undefined ? {} : { contractReport: reports.contract }),
236
+ unconfirmed: unconfirmed.map((c) => ({ id: c.id, claim: c.claim, ...(c.note === undefined ? {} : { note: c.note }) })),
237
+ ...(discarded.length === 0 ? {} : { discarded }),
238
+ ...(notices.length === 0 ? {} : { notices }),
239
+ });
240
+ return;
241
+ }
242
+ if (target.recovered != null)
243
+ console.log(`${sayRecovered(target.recovered)}\n`);
244
+ console.log(`${verification.feature} verification recorded — ${repoPath(docsDir, path)}\n`);
245
+ console.log(` ${tally.confirmed} of ${plural(tally.claims, "claim")} confirmed with evidence.`);
246
+ if (reports.results !== undefined) {
247
+ console.log(` ${plural(fromRunner.length, "scenario claim")} answered by the test runner (${opts.results}).`);
248
+ console.log(` Report read: ${reportLine(reports.results)}.`);
249
+ }
250
+ if (reports.contract !== undefined) {
251
+ console.log(` ${plural(fromContract.length, "api.exposes claim")} answered by the contract test run (${opts.contractResults}).`);
252
+ console.log(` Contract report read: ${contractReportLine(reports.contract)}.`);
253
+ }
254
+ if (opts.record !== undefined && (reports.results !== undefined || reports.contract !== undefined)) {
255
+ console.log(` ${plural(checked.answers.length, "claim")} answered by ${opts.record}.`);
256
+ }
257
+ if (service !== undefined) {
258
+ const attestation = verification.attestations?.find((item) => item.service === service);
259
+ if (attestation !== undefined) {
260
+ console.log(` ${service} attested at git commit ${attestation.commit}.`);
261
+ }
262
+ }
263
+ for (const c of unconfirmed) {
264
+ console.log(` ✗ ${c.claim}${c.note === undefined ? "" : ` — ${c.note}`}`);
265
+ }
266
+ sayDiscarded(discarded, repoPath(docsDir, recordLocation(featureDir)), verification.feature);
267
+ console.log("");
268
+ for (const notice of notices)
269
+ console.log(` ⚠ ${notice.code}: ${notice.message}`);
270
+ console.log(tally.unanswered > 0
271
+ ? ` Partial federation — ${plural(tally.unanswered, "claim")} remain unanswered for their owning service repositories.`
272
+ : verdict === "attested"
273
+ ? " Recorded as attested, not verified: the record travels into features/archive/ saying so."
274
+ : unconfirmed.length === 0
275
+ ? " The record travels with the feature into features/archive/."
276
+ : " Recorded as it stands. Nothing gates on this — it is what a reviewer reads later, so leave it true.");
277
+ }
278
+ //# sourceMappingURL=record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.js","sourceRoot":"","sources":["../../../src/commands/verify/record.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Writing the answers down.\n *\n * The one command in loam that takes somebody's word for something, so every\n * refusal here is about whose word is on the file. The legacy all-at-once form\n * run over a federated record does not merge and does not migrate — it would\n * erase every other service's commit-bound attestation, invisibly, because what\n * replaces it is a well-formed and plausible record.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { emitJson, fail, repoPath } from \"../../core/envelope/json.js\";\nimport { today } from \"../../core/provenance/stamp.js\";\nimport { runnerAnswers } from \"../../core/results.js\";\nimport { checkAnswers, type Answer } from \"../../core/verify/answers.js\";\nimport { buildServiceRecord, buildVerification, type DiscardedAnswer } from \"../../core/verify/build.js\";\nimport { type Checklist } from \"../../core/verify/checklist.js\";\nimport { contractAnswers } from \"../../core/verify/evidence/contract.js\";\nimport { type RecordFiles } from \"../../core/verify/read/file.js\";\nimport { assembleRecord } from \"../../core/verify/read/union.js\";\nimport { commitVerification, type RecordWrite } from \"../../core/verify/store/commit.js\";\nimport {\n tallyRecord,\n type ConsumedReports,\n type Verification,\n type VerifyNotice,\n verificationVerdict,\n} from \"../../core/verify/record.js\";\nimport { recordLocation, serviceRecordPath, verificationPath } from \"../../core/verify/location.js\";\nimport type { PathableService } from \"../../core/kernel/ids/service.js\";\nimport { plural, sayDiscarded, sayRecovered } from \"../policy/format.js\";\nimport { readContractResults } from \"./evidence/contract.js\";\nimport { claimTokens, pinAnswers } from \"./evidence/pins.js\";\nimport { readResults, repositoryCommit, validateLocalEvidence, validateServiceEvidence } from \"./results.js\";\nimport {\n contestedNotices,\n contestedOperationNotices,\n contractReportLine,\n forkedChecklistNotices,\n noticesFor,\n reportLine,\n} from \"./frozen.js\";\nimport { type VerifyTarget } from \"./report.js\";\n\n/** The flags `loam verify --record` reads. */\nexport interface VerifyOptions {\n record?: string;\n results?: string;\n contractResults?: string;\n /** `--diff-answers a.json b.json` — the read-only cross-examination lens\n * (./cross/diff.ts): both files validate against the current checklist and\n * nothing is written. verify.ts refuses recording combinations and arity ≠ 2. */\n diffAnswers?: string[];\n service?: string;\n json?: boolean;\n}\n\n/**\n * The repository whose word this record is taking, for which service, and over\n * which existing record.\n *\n * `previous` belongs here rather than beside it: every refusal in this function\n * is about whether THIS attestor may write over what that record already says,\n * so the two are never asked about separately.\n */\nexport interface Attestor {\n /**\n * Undefined in the legacy all-at-once form, which answers for every service.\n * Branded because it becomes a file name (`verification/<svc>.yaml`): the\n * caller hands in loam.json's own validated id, never the raw flag.\n */\n service: PathableService | undefined;\n /**\n * The repository an attestation is ABOUT: the commit it names, the tree its\n * evidence must resolve inside, and where a `--results` report has to live.\n * It is threaded rather than read in `record` because it comes from\n * `config.root`, and a `process.cwd()` in that function was the whole bug —\n * from a subdirectory, \"this repo\" quietly became that subdirectory.\n */\n repoDir: string;\n /**\n * The existing record as ONE read — the union the refusals consult and the\n * files it was added up from, each with the exact bytes it was parsed from —\n * or null when there was no record. One field rather than a `Verification`\n * beside a set of `Buffer`s because they are meaningless apart: a pre-image\n * from any other read would let the commit vouch for a document the merge\n * never saw, and as separate fields that inconsistent pair is representable\n * and compiles.\n */\n previous: { verification: Verification; files: RecordFiles } | null;\n}\n\nexport async function record(\n target: VerifyTarget,\n checklist: Checklist,\n attestor: Attestor,\n opts: VerifyOptions,\n): Promise<void> {\n const { docsDir, featureDir, json } = target;\n const { service, repoDir, previous } = attestor;\n // The legacy all-at-once form answers the WHOLE checklist on one repository's\n // word and writes a schema-1 record — no attestations, no commits. Run over a\n // federated record it does not merge and it does not migrate: over a one-file\n // federated record it would erase every other service's commit-bound\n // attestation, invisibly, because what replaces it is a well-formed,\n // plausible record; beside a `verification/` directory it would write a file\n // whose answers can never count (no attestation binds them) while reporting\n // them as recorded. Either way it refuses, and names the repositories whose\n // word is on the record.\n const attested = previous?.verification.schema === 2 ? (previous.verification.attestations ?? []) : [];\n if (service === undefined && attested.length > 0) {\n const services = [...new Set(attested.map((a) => a.service))].sort();\n return fail(\n json,\n \"record-federated\",\n `${repoPath(docsDir, recordLocation(featureDir))} is a federated record: ${plural(services.length, \"service\")} (${services.join(\", \")}) have attested claims against their own git commits. ` +\n \"Recording without --service would put one unattested answer set over all of it. \" +\n `Record this service's claims from its own repo instead: \\`loam verify ${checklist.feature} --record answers.json --service <svc>\\`.`,\n );\n }\n\n const scopedClaims =\n service === undefined ? checklist.claims : checklist.claims.filter((claim) => claim.subject === service);\n if (service !== undefined && scopedClaims.length === 0) {\n return fail(\n json,\n \"unknown-service\",\n `The current ${checklist.feature} checklist has no claims owned by service '${service}'.`,\n );\n }\n\n // The mechanical halves: with --results, every scenario.tested claim is the\n // cucumber report's to answer — matched by digest, confirmed only by a green\n // run — and with --contract-results, every api.exposes claim is the contract\n // report's, matched by operationId under the same ownership discipline. A\n // partial suite leaves its unexercised claims unconfirmed rather than\n // agent-attestable in the same run: silence must not read as checked, and\n // the escape is a --record run without the flag.\n const runnerClaims =\n opts.results === undefined ? [] : scopedClaims.filter((c) => c.kind === \"scenario.tested\");\n const contractClaims =\n opts.contractResults === undefined ? [] : scopedClaims.filter((c) => c.kind === \"api.exposes\");\n const agentClaims = scopedClaims.filter(\n (c) =>\n (opts.results === undefined || c.kind !== \"scenario.tested\") &&\n (opts.contractResults === undefined || c.kind !== \"api.exposes\"),\n );\n\n let fromRunner: Answer[] = [];\n let fromContract: Answer[] = [];\n const reports: ConsumedReports = {};\n if (opts.results !== undefined) {\n // A federated record attests for THIS repository, so its report has to be a\n // file inside it — see evidence/read.ts.\n const read = await readResults(opts.results, service === undefined ? undefined : repoDir);\n if (!read.ok) return fail(json, read.code, read.message);\n reports.results = read.report;\n fromRunner = runnerAnswers(runnerClaims, read.scenarios, read.report.path);\n }\n if (opts.contractResults !== undefined) {\n // Same resolution rules as the cucumber report, same refusal code: the two\n // pins make the same promise about the same repository.\n const read = await readContractResults(opts.contractResults, service === undefined ? undefined : repoDir);\n if (!read.ok) return fail(json, read.code, read.message);\n reports.contract = read.report;\n fromContract = contractAnswers(contractClaims, read.runs, read.report.path);\n }\n\n // The agent's half — exactly what no report owns. A mechanical flag alone is\n // legal only when the reports own the whole checklist: anything left over\n // refuses with the ids, the same discipline as a claim with no answer.\n let raw: unknown = [];\n if (opts.record !== undefined) {\n try {\n // The one path that stays cwd-relative, and deliberately: the answer set\n // is a file the caller just wrote and hands to the command, not part of\n // the repository being attested. Nothing on the record points at it.\n raw = JSON.parse(await readFile(resolve(process.cwd(), opts.record), \"utf8\"));\n } catch (err) {\n return fail(\n json,\n \"answers-unreadable\",\n `Cannot read ${opts.record}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n } else if (agentClaims.length > 0 && (opts.results !== undefined || opts.contractResults !== undefined)) {\n const owns = [\n ...(opts.results === undefined ? [] : [\"--results answers only the scenario.tested claims\"]),\n ...(opts.contractResults === undefined ? [] : [\"--contract-results answers only the api.exposes claims\"]),\n ].join(\" and \");\n return fail(\n json,\n \"answers-mismatch\",\n `${owns}; ${agentClaims.length} claim(s) have no answer: ` +\n `${agentClaims.map((c) => c.id).join(\", \")}. Record them with --record <answers.json> alongside.`,\n );\n }\n\n const checked = checkAnswers(\n agentClaims,\n raw,\n opts.results === undefined && opts.contractResults === undefined\n ? undefined\n : new Set([...runnerClaims, ...contractClaims].map((c) => c.id)),\n { feature: checklist.feature, ...(service === undefined ? {} : { service }) },\n );\n if (!checked.ok) return fail(json, checked.code, checked.message);\n\n let serviceCommit: string | undefined;\n let answers = [...fromRunner, ...fromContract, ...checked.answers];\n let pinNotice: VerifyNotice | null = null;\n if (service !== undefined) {\n const commit = await repositoryCommit(repoDir);\n if (!commit.ok) return fail(json, \"repository-unavailable\", commit.message);\n serviceCommit = commit.commit;\n // All halves, one validator. The runner's evidence used to skip it\n // entirely: `--results` minted confirmations whose evidence strings nothing\n // ever checked, in the one mode that promises every answer is bound to this\n // repository at this commit. The same pass stamps each agent citation's\n // evidence pin and scans its blob for the claim's token (evidence/pins.ts).\n const evidence = await validateServiceEvidence(answers, { repoDir, commit: serviceCommit }, reports, claimTokens(scopedClaims));\n if (!evidence.ok) return fail(json, \"answers-unevidenced\", evidence.message);\n ({ answers, notice: pinNotice } = pinAnswers(answers, evidence, serviceCommit));\n } else {\n // The all-at-once form binds to no commit, but a citation still has to be\n // a line that exists — see `validateLocalEvidence`. Resolved against the\n // repository loam.json was found in, which is the one place a reviewer\n // reading this record can go and look.\n const evidence = await validateLocalEvidence(answers, repoDir);\n if (!evidence.ok) {\n return fail(\n json,\n \"answers-unevidenced\",\n `${evidence.message} The all-at-once form resolves every citation inside this repository; ` +\n \"evidence that lives in a service's own repository is recorded from there, with `--service`.\",\n );\n }\n }\n\n const recorded = today(new Date());\n // What goes on disk and what the record reads as afterwards are two\n // different objects now. The all-at-once form IS its file. A service's write\n // is one file among several, so the verdict it prints is the union of the\n // files as they will stand once the commit lands — added up by the very\n // function the next read will use, so this run cannot print a verdict the\n // following `loam verify` disagrees with.\n let verification: Verification;\n let writes: RecordWrite[];\n let discarded: DiscardedAnswer[] = [];\n if (service === undefined) {\n verification = buildVerification(checklist, answers, recorded, reports);\n // The legacy all-at-once form keeps the one file, deliberately. It answers\n // the whole checklist from one place on one word, with no commit and no\n // service, so there is no second writer for it to collide with and no\n // service to name a file after — and every record it ever wrote, the\n // example fleet's included, stays byte-for-byte what it is. The moment a\n // service attests, the refusal above keeps it off the record for good.\n writes = [{ path: verificationPath(featureDir), record: verification, preImage: previous?.files.legacy?.raw ?? null }];\n } else {\n // The docs side of the pin, and it is ASKED FOR rather than required: a\n // docs repo is not obliged to be a git checkout, and the attestation simply\n // carries no `docsCommit` when git cannot answer. Failing the record over\n // it would refuse a working fleet for a field that is optional by design.\n const docsHead = await repositoryCommit(docsDir);\n const files = previous?.files ?? { legacy: null, services: new Map() };\n const own = files.services.get(service) ?? null;\n const built = buildServiceRecord(\n checklist,\n {\n service,\n recorded,\n commit: serviceCommit!,\n reports,\n ...(docsHead.ok ? { docsCommit: docsHead.commit } : {}),\n },\n answers,\n { legacy: files.legacy?.verification ?? null, own: own?.verification ?? null, filed: new Set(files.services.keys()) },\n );\n discarded = built.discarded;\n // This service's own file FIRST — see `commitVerification` for why the\n // order is what a kill between the two renames leaves standing.\n writes = [\n { path: serviceRecordPath(featureDir, service), record: built.record, preImage: own?.raw ?? null },\n ...(built.dropLegacy && files.legacy !== null\n ? [{ path: files.legacy.path, record: null, preImage: files.legacy.raw }]\n : []),\n ];\n const after = new Map([...files.services].map(([svc, file]) => [svc, file.verification]));\n after.set(service, built.record);\n // Added up against THIS checklist — the one the answers just written\n // answer. Left to pick by date, a same-day file with a later service id\n // that answered an older checklist won the tie, and this run printed a\n // tally its own answers were not in (`core/verify/read/union.ts`).\n verification = assembleRecord(\n built.dropLegacy ? null : (files.legacy?.verification ?? null),\n [...after.keys()].sort().map((svc) => after.get(svc)!),\n checklist.digest,\n )!;\n }\n // Staged, compared against the locked read's bytes, swapped in by one\n // rename per file — see core/verify/store/commit.ts for what each refusal\n // means.\n const committed = await commitVerification(writes, docsDir);\n if (!committed.ok) return fail(json, committed.code, committed.message);\n const path = writes[0]!.path;\n const unconfirmed = verification.claims.filter((c) => c.verdict === \"unconfirmed\");\n\n // The same judgment read mode makes (see report): the record just written IS\n // the current checklist's answer, so `stale` is false by construction and the\n // remaining question is whether every claim was confirmed — and, now, by\n // whom. Counted from the claims, not from the summary this same call wrote.\n // Without these fields an agent that recorded all-confirmed answers would\n // have to re-run verify just to learn the state it created.\n const tally = tallyRecord(verification);\n const verdict = verificationVerdict(tally);\n const verified = verdict === \"verified\";\n const notices = [\n ...noticesFor(verification.claims, verification.feature),\n // The read view's notice, on the write that makes it true: a service\n // whose file answered another version of the checklist is named here,\n // because its answers are exactly the ones this tally leaves out.\n ...forkedChecklistNotices(verification, checklist.digest),\n ...contestedNotices(runnerClaims),\n ...contestedOperationNotices(contractClaims),\n ...(pinNotice === null ? [] : [pinNotice]),\n ];\n\n if (json) {\n emitJson({\n command: \"verify\",\n feature: verification.feature,\n path: repoPath(docsDir, path),\n ...(target.recovered == null ? {} : { recovered: target.recovered }),\n digest: verification.checklist,\n verified,\n verdict,\n attested: tally.attested,\n recorded: verification.recorded,\n summary: verification.summary,\n ...(verification.attestations === undefined ? {} : { attestations: verification.attestations }),\n ...(reports.results === undefined ? {} : { report: reports.results }),\n ...(reports.contract === undefined ? {} : { contractReport: reports.contract }),\n unconfirmed: unconfirmed.map((c) => ({ id: c.id, claim: c.claim, ...(c.note === undefined ? {} : { note: c.note }) })),\n ...(discarded.length === 0 ? {} : { discarded }),\n ...(notices.length === 0 ? {} : { notices }),\n });\n return;\n }\n\n if (target.recovered != null) console.log(`${sayRecovered(target.recovered)}\\n`);\n console.log(`${verification.feature} verification recorded — ${repoPath(docsDir, path)}\\n`);\n console.log(` ${tally.confirmed} of ${plural(tally.claims, \"claim\")} confirmed with evidence.`);\n if (reports.results !== undefined) {\n console.log(` ${plural(fromRunner.length, \"scenario claim\")} answered by the test runner (${opts.results}).`);\n console.log(` Report read: ${reportLine(reports.results)}.`);\n }\n if (reports.contract !== undefined) {\n console.log(` ${plural(fromContract.length, \"api.exposes claim\")} answered by the contract test run (${opts.contractResults}).`);\n console.log(` Contract report read: ${contractReportLine(reports.contract)}.`);\n }\n if (opts.record !== undefined && (reports.results !== undefined || reports.contract !== undefined)) {\n console.log(` ${plural(checked.answers.length, \"claim\")} answered by ${opts.record}.`);\n }\n if (service !== undefined) {\n const attestation = verification.attestations?.find((item) => item.service === service);\n if (attestation !== undefined) {\n console.log(` ${service} attested at git commit ${attestation.commit}.`);\n }\n }\n for (const c of unconfirmed) {\n console.log(` ✗ ${c.claim}${c.note === undefined ? \"\" : ` — ${c.note}`}`);\n }\n\n sayDiscarded(discarded, repoPath(docsDir, recordLocation(featureDir)), verification.feature);\n console.log(\"\");\n for (const notice of notices) console.log(` ⚠ ${notice.code}: ${notice.message}`);\n console.log(\n tally.unanswered > 0\n ? ` Partial federation — ${plural(tally.unanswered, \"claim\")} remain unanswered for their owning service repositories.`\n : verdict === \"attested\"\n ? \" Recorded as attested, not verified: the record travels into features/archive/ saying so.\"\n : unconfirmed.length === 0\n ? \" The record travels with the feature into features/archive/.\"\n : \" Recorded as it stands. Nothing gates on this — it is what a reviewer reads later, so leave it true.\",\n );\n}\n"]}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * The done-check as an answer: every claim, its verdict, and who said so.
3
+ *
4
+ * The per-claim rows are computed once and both surfaces read them — `--json`
5
+ * and the terminal cannot disagree about a count, which is the failure this
6
+ * shape prevents. The federation note is here rather than at the call sites
7
+ * because a federated record answers per SERVICE and a reader looking at one
8
+ * lens has to be told which of the others have not answered yet.
9
+ */
10
+ import { emitJson, repoPath } from "../../core/envelope/json.js";
11
+ import {} from "../../core/staging/interrupted.js";
12
+ import {} from "../../core/verify/answers.js";
13
+ import {} from "../../core/verify/checklist.js";
14
+ import {} from "../../core/verify/pins/pin.js";
15
+ import { countedAnswers, openClaimsNotice, tallyAnswers, verificationVerdict, } from "../../core/verify/record.js";
16
+ import { verificationDir } from "../../core/verify/location.js";
17
+ import { EXPLAIN_FOOTER, plural } from "../policy/format.js";
18
+ import { answeredMark, contestedNotices, contractReportLine, forkedChecklistNotices, MARK, noticesFor, recordedPayload, reportLine, } from "./frozen.js";
19
+ export function statuses(checklist, claims, recorded) {
20
+ const byId = recorded === null ? new Map() : countedAnswers(checklist.claims, recorded);
21
+ return claims.map((c) => {
22
+ const answer = byId.get(c.id);
23
+ return {
24
+ id: c.id,
25
+ kind: c.kind,
26
+ subject: c.subject,
27
+ claim: c.claim,
28
+ verdict: answer?.verdict ?? "unanswered",
29
+ ...(answer?.answered_by === undefined ? {} : { answered_by: answer.answered_by }),
30
+ evidence: answer?.evidence ?? [],
31
+ ...(answer?.note === undefined ? {} : { note: answer.note }),
32
+ ...(answer?.evidence_pins === undefined ? {} : { evidence_pins: answer.evidence_pins }),
33
+ };
34
+ });
35
+ }
36
+ /**
37
+ * The read view.
38
+ *
39
+ * `lens` is `--service`: the same checklist, narrowed to the claims that
40
+ * service's code answers. It exists because in a ten-repo fleet the whole
41
+ * checklist is never one repository's business, and an agent that cannot ask
42
+ * "what do I still owe on FEAT-1?" answers the question by guessing. Narrowing
43
+ * narrows the verdict too — `verified` then means "every claim owned by this
44
+ * service is confirmed", which is why the payload names the service it applied.
45
+ *
46
+ * `bound` is loam.json's `service` — what this repository says it is. It only
47
+ * shapes the footer, and it is the whole of how federation is discoverable:
48
+ * the recording form printed here is the one that will actually work from here.
49
+ */
50
+ export function report(target, checklist, recorded, scope = {}) {
51
+ const { docsDir, featureDir, json } = target;
52
+ const lens = scope.lens;
53
+ const owners = [...new Set(checklist.claims.map((c) => c.subject))].sort();
54
+ const scoped = lens === undefined ? checklist.claims : checklist.claims.filter((c) => c.subject === lens);
55
+ const claims = statuses(checklist, scoped, recorded);
56
+ const tally = tallyAnswers(claims);
57
+ // The payload's `summary` is the tally without its `attested` count, which
58
+ // travels as a key of its own beside it.
59
+ const summary = { claims: tally.claims, confirmed: tally.confirmed, unconfirmed: tally.unconfirmed, unanswered: tally.unanswered };
60
+ // A record that answers a different question set is not an answer to this one,
61
+ // however complete it looks — so staleness disqualifies it as a whole.
62
+ const stale = recorded !== null && recorded.checklist !== checklist.digest;
63
+ const verdict = verificationVerdict(tally, stale);
64
+ // `verified` keeps its name and its type, and loses its old meaning: a
65
+ // scenario claim on an agent's word is answered, not run, so it no longer
66
+ // reads the same as a green suite. `verdict` carries the distinction.
67
+ const verified = verdict === "verified";
68
+ // Contest is derivable from the checklist alone, so the read view says it
69
+ // too: an agent looking at what it owes should learn that a second service
70
+ // answers the same claim BEFORE it runs a suite whose report cannot be
71
+ // attributed. Always from the whole checklist, never the lens — a shared
72
+ // digest is a fact about the feature, and a narrowed view is the one place it
73
+ // would otherwise be invisible.
74
+ // The open-claims honesty line only where a record EXISTS: with none, the
75
+ // surface already says "Not verified", and not-started is not partial.
76
+ const open = recorded === null ? null : openClaimsNotice(tally, checklist.feature);
77
+ const notices = [
78
+ ...noticesFor(claims, checklist.feature),
79
+ ...(open === null ? [] : [open]),
80
+ ...contestedNotices(checklist.claims),
81
+ ...forkedChecklistNotices(recorded, checklist.digest),
82
+ ];
83
+ if (json) {
84
+ emitJson({
85
+ command: "verify",
86
+ feature: checklist.feature,
87
+ path: repoPath(docsDir, featureDir),
88
+ digest: checklist.digest,
89
+ // Named only when narrowed, so a consumer can never mistake a service's
90
+ // verdict for the feature's.
91
+ ...(lens === undefined ? {} : { service: lens, checklistClaims: checklist.claims.length }),
92
+ verified,
93
+ verdict,
94
+ attested: tally.attested,
95
+ summary,
96
+ services: owners,
97
+ recorded: recorded === null ? null : recordedPayload(target, recorded, { stale }),
98
+ claims,
99
+ ...(notices.length === 0 ? {} : { notices }),
100
+ });
101
+ return;
102
+ }
103
+ const scopeNote = lens === undefined ? "" : ` owned by ${lens} (of ${plural(checklist.claims.length, "claim")} on the checklist)`;
104
+ console.log(`${checklist.feature} — ${plural(claims.length, "claim")}${scopeNote} derived from ${repoPath(docsDir, featureDir)}\n`);
105
+ if (claims.length === 0) {
106
+ console.log(lens === undefined
107
+ ? " Nothing to check: this feature's delta, specs and openapi promise nothing yet."
108
+ : ` No claim on this checklist is owned by '${lens}'.${owners.length > 0 ? ` The services that own claims here are ${owners.join(", ")}.` : ""}`);
109
+ return;
110
+ }
111
+ for (const c of claims) {
112
+ console.log(` ${MARK[c.verdict]} ${c.id} [${c.subject}] ${c.claim}${answeredMark(c)}`);
113
+ for (const e of c.evidence)
114
+ console.log(` ${e}`);
115
+ if (c.note !== undefined)
116
+ console.log(` note: ${c.note}`);
117
+ }
118
+ console.log("");
119
+ if (recorded === null) {
120
+ // Both places a record can be, because which one the next record lands in
121
+ // depends on the form that writes it — a service's attestation goes to its
122
+ // own file under verification/, the all-at-once form to verification.yaml.
123
+ console.log(` Not verified — no ${repoPath(docsDir, verificationDir(featureDir))}/ or verification.yaml yet.`);
124
+ }
125
+ else {
126
+ console.log(` Recorded ${recorded.recorded} — ${summary.confirmed} confirmed, ${summary.unconfirmed} unconfirmed, ${summary.unanswered} unanswered.`);
127
+ if (stale) {
128
+ console.log(" STALE: the feature changed after this was recorded. Answer the claims above again.");
129
+ }
130
+ for (const attestation of recorded.attestations ?? []) {
131
+ console.log(` Attested by ${attestation.service} at ${attestation.commit.slice(0, 12)} (${attestation.recorded}, ${plural(attestation.claims.length, "claim")}).`);
132
+ if (attestation.report !== undefined)
133
+ console.log(` from ${reportLine(attestation.report)}`);
134
+ if (attestation.contractReport !== undefined) {
135
+ console.log(` from ${contractReportLine(attestation.contractReport)}`);
136
+ }
137
+ }
138
+ if (recorded.report !== undefined)
139
+ console.log(` Answered from ${reportLine(recorded.report)}.`);
140
+ if (recorded.contractReport !== undefined) {
141
+ console.log(` Contract report read: ${contractReportLine(recorded.contractReport)}.`);
142
+ }
143
+ }
144
+ // The notice's code LEADS the line here, where validate's findings now carry
145
+ // theirs in a trailing `(code)` — and the two shapes are deliberate, not
146
+ // drift. A notice is one line and its code is its subject, so it reads as a
147
+ // label; a finding is one of hundreds in a report whose subject is the
148
+ // message, so its code is an aside. Appending a second copy to satisfy the
149
+ // one-shape instinct would print `⚠ verify.claims-open: … (verify.claims-open)`,
150
+ // and the leading form is also the one the frozen post-archive view prints
151
+ // (frozen.ts) — a live record and a shipped one must not describe the same
152
+ // notice two ways. Either way the code is on screen, which is the whole of
153
+ // what EXPLAIN_FOOTER below needs to be true.
154
+ for (const notice of notices)
155
+ console.log(` ⚠ ${notice.code}: ${notice.message}`);
156
+ // An attested record has answered every question — telling it to "answer each
157
+ // claim" would send an agent round a loop it has already run. The notice
158
+ // above names the one thing left, which is a test run.
159
+ if (verdict === "unverified") {
160
+ console.log("\n Answer each claim, then record the answers:\n");
161
+ console.log(' [{ "id": "<claim id>", "verdict": "confirmed", "evidence": ["src/x.ts:42"] }]');
162
+ console.log(`\n loam verify ${checklist.feature} --record answers.json${recordSuffix(scope, owners)}`);
163
+ for (const line of federationNote(scope, owners))
164
+ console.log(line);
165
+ console.log("\n A claim you cannot show evidence for is `unconfirmed` — say why in `note`.");
166
+ }
167
+ // APPENDED, as format.ts promises — the report's last line, never a wedge
168
+ // between the notices and the recording instructions that follow them. It
169
+ // follows printed notice codes only: claim marks carry no code to look up,
170
+ // and the frozen post-archive view (frozen.ts) stays without it on purpose,
171
+ // because shipped history is not a fix-it surface.
172
+ if (notices.length > 0)
173
+ console.log(`\n${EXPLAIN_FOOTER}`);
174
+ }
175
+ /**
176
+ * The `--service` the printed form should carry. It comes from loam.json, never
177
+ * from the checklist: the only attestation this repository can make is its own,
178
+ * and a hint naming a service that lives somewhere else is a hint that fails.
179
+ */
180
+ export function recordSuffix(scope, owners) {
181
+ if (scope.bound !== undefined)
182
+ return ` --service ${scope.bound}`;
183
+ return owners.length > 1 || scope.lens !== undefined ? " --service <svc>" : "";
184
+ }
185
+ /** Why the form above has a `--service` on it — the one place federation is taught. */
186
+ export function federationNote(scope, owners) {
187
+ if (scope.bound !== undefined) {
188
+ const others = owners.filter((s) => s !== scope.bound);
189
+ return [
190
+ "",
191
+ ` This repository is ${scope.bound}, so it attests only ${scope.bound}'s claims, bound to its git HEAD.`,
192
+ ...(others.length === 0
193
+ ? []
194
+ : [` The claims owned by ${others.join(", ")} are recorded the same way from those repositories.`]),
195
+ ];
196
+ }
197
+ if (owners.length > 1 || scope.lens !== undefined) {
198
+ return [
199
+ "",
200
+ ` This checklist spans ${plural(owners.length, "service")} (${owners.join(", ")}) — each attests its own claims`,
201
+ " from its own repository, where loam.json names that service.",
202
+ ];
203
+ }
204
+ return [];
205
+ }
206
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/commands/verify/report.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAuB,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAmB,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAkB,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAoB,MAAM,+BAA+B,CAAC;AACjE,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,YAAY,EAGZ,mBAAmB,GACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,IAAI,EACJ,UAAU,EACV,eAAe,EACf,UAAU,GACX,MAAM,aAAa,CAAC;AAerB,MAAM,UAAU,QAAQ,CAAC,SAAoB,EAAE,MAA2B,EAAE,QAA6B;IACvG,MAAM,IAAI,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,EAAyB,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/G,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9B,OAAO;YACL,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,YAAY;YACxC,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;YACjF,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,EAAE;YAChC,GAAG,CAAC,MAAM,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5D,GAAG,CAAC,MAAM,EAAE,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC;SACxF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAsBD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,MAAM,CACpB,MAAoB,EACpB,SAAoB,EACpB,QAA6B,EAC7B,KAAK,GAAsC,EAAE;IAE7C,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;IAC7C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACxB,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3E,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;IAC1G,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACnC,2EAA2E;IAC3E,yCAAyC;IACzC,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;IACnI,+EAA+E;IAC/E,uEAAuE;IACvE,MAAM,KAAK,GAAG,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC,MAAM,CAAC;IAC3E,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAClD,uEAAuE;IACvE,0EAA0E;IAC1E,sEAAsE;IACtE,MAAM,QAAQ,GAAG,OAAO,KAAK,UAAU,CAAC;IACxC,0EAA0E;IAC1E,2EAA2E;IAC3E,uEAAuE;IACvE,yEAAyE;IACzE,8EAA8E;IAC9E,gCAAgC;IAChC,0EAA0E;IAC1E,uEAAuE;IACvE,MAAM,IAAI,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACnF,MAAM,OAAO,GAAG;QACd,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC;QACxC,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChC,GAAG,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC;QACrC,GAAG,sBAAsB,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC;KACtD,CAAC;IAEF,IAAI,IAAI,EAAE,CAAC;QACT,QAAQ,CAAC;YACP,OAAO,EAAE,QAAQ;YACjB,OAAO,EAAE,SAAS,CAAC,OAAO;YAC1B,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;YACnC,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,wEAAwE;YACxE,6BAA6B;YAC7B,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YAC1F,QAAQ;YACR,OAAO;YACP,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO;YACP,QAAQ,EAAE,MAAM;YAChB,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC;YACjF,MAAM;YACN,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;SAC7C,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GACb,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,IAAI,QAAQ,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAClH,OAAO,CAAC,GAAG,CACT,GAAG,SAAS,CAAC,OAAO,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,iBAAiB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,CACvH,CAAC;IACF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CACT,IAAI,KAAK,SAAS;YAChB,CAAC,CAAC,kFAAkF;YACpF,CAAC,CAAC,6CAA6C,IAAI,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,0CAA0C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpJ,CAAC;QACF,OAAO;IACT,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1F,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ;YAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,0EAA0E;QAC1E,2EAA2E;QAC3E,2EAA2E;QAC3E,OAAO,CAAC,GAAG,CAAC,uBAAuB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC,6BAA6B,CAAC,CAAC;IAClH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CACT,cAAc,QAAQ,CAAC,QAAQ,MAAM,OAAO,CAAC,SAAS,eAAe,OAAO,CAAC,WAAW,iBAAiB,OAAO,CAAC,UAAU,cAAc,CAC1I,CAAC;QACF,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,GAAG,CAAC,sFAAsF,CAAC,CAAC;QACtG,CAAC;QACD,KAAK,MAAM,WAAW,IAAI,QAAQ,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;YACtD,OAAO,CAAC,GAAG,CACT,iBAAiB,WAAW,CAAC,OAAO,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,WAAW,CAAC,QAAQ,KAAK,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CACvJ,CAAC;YACF,IAAI,WAAW,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,CAAC,GAAG,CAAC,cAAc,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAClG,IAAI,WAAW,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;gBAC7C,OAAO,CAAC,GAAG,CAAC,cAAc,kBAAkB,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClG,IAAI,QAAQ,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,2BAA2B,kBAAkB,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;IACD,6EAA6E;IAC7E,yEAAyE;IACzE,4EAA4E;IAC5E,uEAAuE;IACvE,2EAA2E;IAC3E,iFAAiF;IACjF,2EAA2E;IAC3E,2EAA2E;IAC3E,2EAA2E;IAC3E,8CAA8C;IAC9C,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,OAAO,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACnF,8EAA8E;IAC9E,yEAAyE;IACzE,uDAAuD;IACvD,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,mFAAmF,CAAC,CAAC;QACjG,OAAO,CAAC,GAAG,CAAC,qBAAqB,SAAS,CAAC,OAAO,yBAAyB,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1G,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,gFAAgF,CAAC,CAAC;IAChG,CAAC;IACD,0EAA0E;IAC1E,0EAA0E;IAC1E,2EAA2E;IAC3E,4EAA4E;IAC5E,mDAAmD;IACnD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,cAAc,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwC,EAAE,MAAgB;IACrF,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,cAAc,KAAK,CAAC,KAAK,EAAE,CAAC;IAClE,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;AACjF,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,cAAc,CAAC,KAAwC,EAAE,MAAgB;IACvF,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC;QACvD,OAAO;YACL,EAAE;YACF,wBAAwB,KAAK,CAAC,KAAK,wBAAwB,KAAK,CAAC,KAAK,mCAAmC;YACzG,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;gBACrB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,CAAC,yBAAyB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;SACvG,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClD,OAAO;YACL,EAAE;YACF,0BAA0B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,iCAAiC;YACjH,gEAAgE;SACjE,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC","sourcesContent":["/**\n * The done-check as an answer: every claim, its verdict, and who said so.\n *\n * The per-claim rows are computed once and both surfaces read them — `--json`\n * and the terminal cannot disagree about a count, which is the failure this\n * shape prevents. The federation note is here rather than at the call sites\n * because a federated record answers per SERVICE and a reader looking at one\n * lens has to be told which of the others have not answered yet.\n */\nimport { emitJson, repoPath } from \"../../core/envelope/json.js\";\nimport { type CommitRecovery } from \"../../core/staging/interrupted.js\";\nimport { type AnsweredBy } from \"../../core/verify/answers.js\";\nimport { type Checklist } from \"../../core/verify/checklist.js\";\nimport { type EvidencePin } from \"../../core/verify/pins/pin.js\";\nimport {\n countedAnswers,\n openClaimsNotice,\n tallyAnswers,\n type RecordedClaim,\n type Verification,\n verificationVerdict,\n} from \"../../core/verify/record.js\";\nimport { verificationDir } from \"../../core/verify/location.js\";\nimport { EXPLAIN_FOOTER, plural } from \"../policy/format.js\";\nimport {\n answeredMark,\n contestedNotices,\n contractReportLine,\n forkedChecklistNotices,\n MARK,\n noticesFor,\n recordedPayload,\n reportLine,\n} from \"./frozen.js\";\n\nexport interface ClaimStatus {\n id: string;\n kind: string;\n subject: string;\n claim: string;\n verdict: \"confirmed\" | \"unconfirmed\" | \"unanswered\";\n answered_by?: AnsweredBy;\n evidence: string[];\n note?: string;\n /** The recorded pins, passed through where the record carries them — additive payload key. */\n evidence_pins?: EvidencePin[];\n}\n\nexport function statuses(checklist: Checklist, claims: Checklist[\"claims\"], recorded: Verification | null): ClaimStatus[] {\n const byId = recorded === null ? new Map<string, RecordedClaim>() : countedAnswers(checklist.claims, recorded);\n return claims.map((c) => {\n const answer = byId.get(c.id);\n return {\n id: c.id,\n kind: c.kind,\n subject: c.subject,\n claim: c.claim,\n verdict: answer?.verdict ?? \"unanswered\",\n ...(answer?.answered_by === undefined ? {} : { answered_by: answer.answered_by }),\n evidence: answer?.evidence ?? [],\n ...(answer?.note === undefined ? {} : { note: answer.note }),\n ...(answer?.evidence_pins === undefined ? {} : { evidence_pins: answer.evidence_pins }),\n };\n });\n}\n\n/**\n * Which feature is being reported on, and in what voice.\n *\n * Three of these travelled as loose strings beside two booleans through every\n * reporting path. They are one thing — the target of this run — and a record\n * makes the `--json` flag impossible to transpose with a lens name, which is\n * what the positional form allowed.\n */\nexport interface VerifyTarget {\n docsDir: string;\n featureDir: string;\n json: boolean;\n /**\n * Non-null when the record path first rolled a predecessor's interrupted\n * commit forward under its lock. Only `record` reports it; the read path\n * never recovers, so it never carries one.\n */\n recovered?: CommitRecovery | null;\n}\n\n/**\n * The read view.\n *\n * `lens` is `--service`: the same checklist, narrowed to the claims that\n * service's code answers. It exists because in a ten-repo fleet the whole\n * checklist is never one repository's business, and an agent that cannot ask\n * \"what do I still owe on FEAT-1?\" answers the question by guessing. Narrowing\n * narrows the verdict too — `verified` then means \"every claim owned by this\n * service is confirmed\", which is why the payload names the service it applied.\n *\n * `bound` is loam.json's `service` — what this repository says it is. It only\n * shapes the footer, and it is the whole of how federation is discoverable:\n * the recording form printed here is the one that will actually work from here.\n */\nexport function report(\n target: VerifyTarget,\n checklist: Checklist,\n recorded: Verification | null,\n scope: { lens?: string; bound?: string } = {},\n): void {\n const { docsDir, featureDir, json } = target;\n const lens = scope.lens;\n const owners = [...new Set(checklist.claims.map((c) => c.subject))].sort();\n const scoped = lens === undefined ? checklist.claims : checklist.claims.filter((c) => c.subject === lens);\n const claims = statuses(checklist, scoped, recorded);\n const tally = tallyAnswers(claims);\n // The payload's `summary` is the tally without its `attested` count, which\n // travels as a key of its own beside it.\n const summary = { claims: tally.claims, confirmed: tally.confirmed, unconfirmed: tally.unconfirmed, unanswered: tally.unanswered };\n // A record that answers a different question set is not an answer to this one,\n // however complete it looks — so staleness disqualifies it as a whole.\n const stale = recorded !== null && recorded.checklist !== checklist.digest;\n const verdict = verificationVerdict(tally, stale);\n // `verified` keeps its name and its type, and loses its old meaning: a\n // scenario claim on an agent's word is answered, not run, so it no longer\n // reads the same as a green suite. `verdict` carries the distinction.\n const verified = verdict === \"verified\";\n // Contest is derivable from the checklist alone, so the read view says it\n // too: an agent looking at what it owes should learn that a second service\n // answers the same claim BEFORE it runs a suite whose report cannot be\n // attributed. Always from the whole checklist, never the lens — a shared\n // digest is a fact about the feature, and a narrowed view is the one place it\n // would otherwise be invisible.\n // The open-claims honesty line only where a record EXISTS: with none, the\n // surface already says \"Not verified\", and not-started is not partial.\n const open = recorded === null ? null : openClaimsNotice(tally, checklist.feature);\n const notices = [\n ...noticesFor(claims, checklist.feature),\n ...(open === null ? [] : [open]),\n ...contestedNotices(checklist.claims),\n ...forkedChecklistNotices(recorded, checklist.digest),\n ];\n\n if (json) {\n emitJson({\n command: \"verify\",\n feature: checklist.feature,\n path: repoPath(docsDir, featureDir),\n digest: checklist.digest,\n // Named only when narrowed, so a consumer can never mistake a service's\n // verdict for the feature's.\n ...(lens === undefined ? {} : { service: lens, checklistClaims: checklist.claims.length }),\n verified,\n verdict,\n attested: tally.attested,\n summary,\n services: owners,\n recorded: recorded === null ? null : recordedPayload(target, recorded, { stale }),\n claims,\n ...(notices.length === 0 ? {} : { notices }),\n });\n return;\n }\n\n const scopeNote =\n lens === undefined ? \"\" : ` owned by ${lens} (of ${plural(checklist.claims.length, \"claim\")} on the checklist)`;\n console.log(\n `${checklist.feature} — ${plural(claims.length, \"claim\")}${scopeNote} derived from ${repoPath(docsDir, featureDir)}\\n`,\n );\n if (claims.length === 0) {\n console.log(\n lens === undefined\n ? \" Nothing to check: this feature's delta, specs and openapi promise nothing yet.\"\n : ` No claim on this checklist is owned by '${lens}'.${owners.length > 0 ? ` The services that own claims here are ${owners.join(\", \")}.` : \"\"}`,\n );\n return;\n }\n for (const c of claims) {\n console.log(` ${MARK[c.verdict]} ${c.id} [${c.subject}] ${c.claim}${answeredMark(c)}`);\n for (const e of c.evidence) console.log(` ${e}`);\n if (c.note !== undefined) console.log(` note: ${c.note}`);\n }\n\n console.log(\"\");\n if (recorded === null) {\n // Both places a record can be, because which one the next record lands in\n // depends on the form that writes it — a service's attestation goes to its\n // own file under verification/, the all-at-once form to verification.yaml.\n console.log(` Not verified — no ${repoPath(docsDir, verificationDir(featureDir))}/ or verification.yaml yet.`);\n } else {\n console.log(\n ` Recorded ${recorded.recorded} — ${summary.confirmed} confirmed, ${summary.unconfirmed} unconfirmed, ${summary.unanswered} unanswered.`,\n );\n if (stale) {\n console.log(\" STALE: the feature changed after this was recorded. Answer the claims above again.\");\n }\n for (const attestation of recorded.attestations ?? []) {\n console.log(\n ` Attested by ${attestation.service} at ${attestation.commit.slice(0, 12)} (${attestation.recorded}, ${plural(attestation.claims.length, \"claim\")}).`,\n );\n if (attestation.report !== undefined) console.log(` from ${reportLine(attestation.report)}`);\n if (attestation.contractReport !== undefined) {\n console.log(` from ${contractReportLine(attestation.contractReport)}`);\n }\n }\n if (recorded.report !== undefined) console.log(` Answered from ${reportLine(recorded.report)}.`);\n if (recorded.contractReport !== undefined) {\n console.log(` Contract report read: ${contractReportLine(recorded.contractReport)}.`);\n }\n }\n // The notice's code LEADS the line here, where validate's findings now carry\n // theirs in a trailing `(code)` — and the two shapes are deliberate, not\n // drift. A notice is one line and its code is its subject, so it reads as a\n // label; a finding is one of hundreds in a report whose subject is the\n // message, so its code is an aside. Appending a second copy to satisfy the\n // one-shape instinct would print `⚠ verify.claims-open: … (verify.claims-open)`,\n // and the leading form is also the one the frozen post-archive view prints\n // (frozen.ts) — a live record and a shipped one must not describe the same\n // notice two ways. Either way the code is on screen, which is the whole of\n // what EXPLAIN_FOOTER below needs to be true.\n for (const notice of notices) console.log(` ⚠ ${notice.code}: ${notice.message}`);\n // An attested record has answered every question — telling it to \"answer each\n // claim\" would send an agent round a loop it has already run. The notice\n // above names the one thing left, which is a test run.\n if (verdict === \"unverified\") {\n console.log(\"\\n Answer each claim, then record the answers:\\n\");\n console.log(' [{ \"id\": \"<claim id>\", \"verdict\": \"confirmed\", \"evidence\": [\"src/x.ts:42\"] }]');\n console.log(`\\n loam verify ${checklist.feature} --record answers.json${recordSuffix(scope, owners)}`);\n for (const line of federationNote(scope, owners)) console.log(line);\n console.log(\"\\n A claim you cannot show evidence for is `unconfirmed` — say why in `note`.\");\n }\n // APPENDED, as format.ts promises — the report's last line, never a wedge\n // between the notices and the recording instructions that follow them. It\n // follows printed notice codes only: claim marks carry no code to look up,\n // and the frozen post-archive view (frozen.ts) stays without it on purpose,\n // because shipped history is not a fix-it surface.\n if (notices.length > 0) console.log(`\\n${EXPLAIN_FOOTER}`);\n}\n\n/**\n * The `--service` the printed form should carry. It comes from loam.json, never\n * from the checklist: the only attestation this repository can make is its own,\n * and a hint naming a service that lives somewhere else is a hint that fails.\n */\nexport function recordSuffix(scope: { lens?: string; bound?: string }, owners: string[]): string {\n if (scope.bound !== undefined) return ` --service ${scope.bound}`;\n return owners.length > 1 || scope.lens !== undefined ? \" --service <svc>\" : \"\";\n}\n\n/** Why the form above has a `--service` on it — the one place federation is taught. */\nexport function federationNote(scope: { lens?: string; bound?: string }, owners: string[]): string[] {\n if (scope.bound !== undefined) {\n const others = owners.filter((s) => s !== scope.bound);\n return [\n \"\",\n ` This repository is ${scope.bound}, so it attests only ${scope.bound}'s claims, bound to its git HEAD.`,\n ...(others.length === 0\n ? []\n : [` The claims owned by ${others.join(\", \")} are recorded the same way from those repositories.`]),\n ];\n }\n if (owners.length > 1 || scope.lens !== undefined) {\n return [\n \"\",\n ` This checklist spans ${plural(owners.length, \"service\")} (${owners.join(\", \")}) — each attests its own claims`,\n \" from its own repository, where loam.json names that service.\",\n ];\n }\n return [];\n}\n"]}