@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 @@
1
+ {"version":3,"file":"families.js","sourceRoot":"","sources":["../../../src/core/explain/families.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The family registry: `loam explain`'s content for the four code families no\n * fix table anywhere grades — `doctor.*`, `next.*`, `diff.*` and `gate.*`.\n *\n * WHY THIS IS NOT THE DUPLICATION fix-tables.ts FORBIDS. That module's header\n * argues against a second hand-maintained copy of the /loam-check prose, and\n * the argument is right: the tables ship in the binary, test/codes-drift.test.ts\n * holds every emitted finding code against them, and a registry restating them\n * would be free to trail the bytes `loam instructions loam-check` prints. None\n * of that applies here. These 67 codes have no fix-table row in any workflow\n * body — /loam-check grades DOCUMENTS, and these four families grade a\n * repository's wiring (`doctor`), a recommendation (`next`), a change between\n * two refs (`diff`) and a deploy question (`gate`). There is nothing to trail:\n * this registry is not a second copy, it is the only copy. The precedent is the\n * sibling module refusals.ts, a hand-written map that is the sole source for\n * the `ErrorCode` meanings for exactly the same reason — their prose lives in\n * doc comments, which are erased, so there is no runtime constant to read.\n *\n * What that costs, stated rather than hidden: nothing mechanical proves an\n * entry below still matches the message its emitter prints. Every meaning and\n * every fix here was written FROM the emitter — `doctor` findings carry a `fix`\n * field of their own (core/doctor/), a `next` step carries a `statement` and a\n * literal `command` (core/status/), the `DiffCode` union carries a doc comment\n * per member (core/diff/semantic.ts) — and the wording is theirs, not a\n * paraphrase invented here. Two guards catch the two failures that CAN be\n * caught: test/explain.test.ts asserts no code below is also answered by a fix\n * table (the two sources must never be able to disagree), and\n * test/agent-commands-runnable.test.ts parses every backticked `loam …` in this\n * file against the real program, so a fix naming a command loam does not have —\n * or a flag it does not declare — fails at gate time. A two-token span is a\n * NAME rather than an invocation there and is only checked for the command\n * existing, so a fix that means an invocation must carry its arguments.\n *\n * `severityNote` is the EMITTER's own word, not a fix table's parenthetical:\n * `doctor` grades blocker/warning, `diff` and `gate` grade ok/warn/error, and a\n * `next` step is graded not at all — it is a recommendation, so its note is\n * `step`. Where a code's severity depends on what was found (`doctor.docs-locked`,\n * `gate.partners-unknown`) the note says so in prose, the way the tables' own\n * long notes do (`warn here; error at archive plan time`).\n *\n * `openspec.*` and `mapping.*` — 49 codes — are deliberately NOT here, and the\n * reason is in test/explain.test.ts beside their backlog entries: they are the\n * only codes in the vocabulary whose subject is not a loam document at all.\n */\n\n/**\n * One code's answer. Structurally a `FindingEntry` (lookup.ts) minus `scope`,\n * which the family supplies — declared here rather than imported so this module\n * imports nothing at all and the package's file-level graph stays a tree.\n *\n * Every entry below is written on ONE line, however long that line runs, and\n * that is a deliberate concession to a counted limit rather than a style: 65\n * codes at four lines each is 260 lines of punctuation before a word of prose,\n * which does not fit the 400-line file limit — and src/core/explain/ is at its\n * five-file cap, so there is no second file to put the overflow in. The fields\n * stay named for the same reason a tuple was refused: `severityNote`, `meaning`\n * and `fix` say which column is which without counting commas.\n */\nexport interface FamilyEntry {\n /** The emitter's own severity word, or the prose a conditional one needs. */\n readonly severityNote: string;\n /** What the code is about, in the words the emitter already prints. */\n readonly meaning: string;\n /** What to do — for `next.*`, that the step's own `command` IS the action. */\n readonly fix: string;\n}\n\n/** One family: the invocation that emits it, and its codes. */\ninterface Family {\n /** The scope label, spelled as the fix tables spell theirs — the invocation that grades it. */\n readonly scope: string;\n readonly codes: Readonly<Record<string, FamilyEntry>>;\n}\n\n/**\n * `loam doctor` — the preflight. Every finding here already carries a `fix`\n * field in doctor's own report (core/doctor/doctor.ts, config.ts, agents.ts,\n * residue.ts); these rows say the same thing without a repository in front of\n * them, which is the whole difference between a report and a lookup.\n */\nconst DOCTOR: Family = {\n scope: \"loam doctor\",\n codes: {\n \"doctor.config-missing\": { severityNote: \"blocker\", meaning: \"No loam.json at or above the working directory, so nothing says which docs repo this checkout belongs to — every other command refuses with `no-config` until there is one.\", fix: \"Run `loam init --docs <dir>` in this repository; add `--create` when the docs repo does not exist yet.\" },\n \"doctor.config-invalid\": { severityNote: \"blocker\", meaning: \"A loam.json is there and `parseConfig` — the same loader every command uses — refuses it; the finding carries the parser's own words. doctor deliberately has no second validator: the one it used to carry accepted a config the commands rejected, and reported a healthy repo in which nothing could run.\", fix: \"Repair the file the finding names, or delete it and re-run `loam init`.\" },\n \"doctor.docs-missing\": { severityNote: \"blocker\", meaning: \"`docsDir` resolves to something that is missing or is not a directory — the docs repo was never cloned, or the path is wrong.\", fix: \"Fix `docsDir` in the loam.json the finding names, clone the docs repo to that path, or run `loam init --docs <dir> --create`.\" },\n \"doctor.services-missing\": { severityNote: \"blocker\", meaning: \"`docsDir` is a directory and holds no `services/`, so it is some other directory — most often the service repo itself, after a typo in the pointer.\", fix: \"Point `docsDir` at the shared docs repo, or run `loam init --docs <dir> --create` to scaffold one. Do not scaffold a second source of truth beside the real one.\" },\n \"doctor.docs-absolute\": { severityNote: \"warning\", meaning: \"`docsDir` is stored as an absolute path and loam.json is committed, so the pointer names a directory that exists on exactly one machine: it works for whoever ran `loam init` and for nobody who clones the repo afterwards.\", fix: \"Rewrite `docsDir` as a path relative to the loam.json holding it, such as `../docs`.\" },\n \"doctor.docs-unreadable\": { severityNote: \"warning\", meaning: \"The docs repo exists and this process cannot read it, so every command that reads the fleet will fail or report an empty one.\", fix: \"Grant read access to the directory the finding names — check ownership and mode.\" },\n \"doctor.docs-readonly\": { severityNote: \"warning\", meaning: \"The docs repo is readable and not writable: read-only commands work and the writing ones do not.\", fix: \"Grant write access if you need `loam new`, `loam adopt` or `loam archive`. A read-only checkout is a legitimate state for a reviewer, which is why this is a warning.\" },\n \"doctor.landscape-missing\": { severityNote: \"warning\", meaning: \"architecture/landscape.likec4 is missing, and it is the one artifact every cross-service check reads — nothing about who calls whom can be checked without it.\", fix: \"Create it with one element per service and an edge per call: `loam init --create` writes the empty map, and `loam seed --from fleet.yaml` templates one from stated facts.\" },\n \"doctor.landscape-unreadable\": { severityNote: \"blocker\", meaning: \"The landscape file exists and the read itself failed — permissions or an I/O error, carried verbatim in the message.\", fix: \"Check permissions on the path the finding names.\" },\n \"doctor.landscape-merge-conflict\": { severityNote: \"blocker\", meaning: \"The landscape still contains merge conflict markers, named by line. Checked BEFORE the parser on purpose: both sides of a conflict can be syntactically valid LikeC4, so the file sometimes parses and is still two halves of two different maps.\", fix: \"Resolve the conflict keeping BOTH services' elements and edges — the usual cause is several services adopted into one map in the same week — then re-run `loam doctor`.\" },\n \"doctor.landscape-invalid\": { severityNote: \"blocker\", meaning: \"The landscape exists, carries no conflict markers, and does not parse; the message quotes the first parser error with its line and counts the rest.\", fix: \"Fix the file — every fleet-wide check is blind until it parses.\" },\n \"doctor.likec4-config-missing\": { severityNote: \"warning\", meaning: \"The docs repo has no likec4.config.json, so the tree is not a loadable LikeC4 workspace: every service model and feature delta declares its own `specification` block, and a renderer pointed at the repo root merges them and reports every declaration as a duplicate. No loam check reads this file — the repo is only unrenderable, which is why it is a warning.\", fix: \"Write the project file the finding prints; it scopes the root project to architecture/, so `npx likec4 start` in the docs repo renders the fleet map. Then run `loam subsystem sync`: it writes one create-only likec4.config.json beside every service model, so each model renders from that same root as a project of its own — only a feature delta still renders from its own directory.\" },\n \"doctor.docs-locked\": { severityNote: \"warning while a live process holds it; blocker when its holder is dead or it names none\", meaning: \"A `.loam-lock` is present. Held by a running process it is a fact about right now. Held by a process that no longer exists on this host — or unreadable, so no holder can be named at all — nothing is ever going to release it, and every writing command refuses with `docs-busy` forever.\", fix: \"Wait and re-run while the holder is alive; nothing is read or written while it is held. Delete the lock file the finding names when its holder is dead or unnameable, then run `loam doctor` again for an interrupted commit underneath it.\" },\n \"doctor.commit-unreadable\": { severityNote: \"blocker\", meaning: \"A `.loam-commit` journal is present and cannot be read: a commit was interrupted and the one record of which files it had already written is unreadable.\", fix: \"Hand this to a human — compare the root's files against version control before running any loam command that writes there. Every journaled writer refuses with `commit-interrupted` while it is present.\" },\n \"doctor.commit-interrupted\": { severityNote: \"blocker\", meaning: \"A journaled writer — archive, unarchive, rebase, vouch, new, gherkin, or a recording verify — was killed mid-commit. The message names the host, pid and time, and every file or directory move that may be half-done. This is the surface that used to report a healthy repo over half-merged living docs.\", fix: \"Re-run the command the finding names: it recovers first, under the lock, rolling the staged bytes forward, and refuses rather than guessing if a file has been edited since. An interrupted `loam unarchive` is FINISHED, never undone — the merged text it was replacing is written down nowhere.\" },\n \"doctor.staging-temps\": { severityNote: \"warning\", meaning: \"Orphaned `.loam-*.tmp` scratch files from a killed writer, never linked into place — so nothing reads them and nothing depends on them. A journal's own recorded temps are excluded, because those are the durable copy its roll-forward recovery renames in. Litter, not damage.\", fix: \"The next journaled writer through that root removes its own; delete any that remain. They cost disk and nothing else.\" },\n \"doctor.inventory-unreadable\": { severityNote: \"warning\", meaning: \"The config and the docs repo are both fine and enumerating `services/` or `features/` threw, so doctor's fleet counts — and its verdict on the service binding — are about a fleet nobody could read.\", fix: \"Check that services/ and features/ under the docs repo are readable directories.\" },\n \"doctor.service-unbound\": { severityNote: \"warning\", meaning: \"loam.json declares no `service`, so nothing binds this checkout to one governed boundary and the service-repo checks have nothing to run against — `sources.stale`, a recording `loam verify`, `loam gherkin`. Deliberately not emitted inside the docs repo itself, where having no binding is the correct state rather than a gap.\", fix: \"Run `loam init --docs <dir> --service <id>` here.\" },\n \"doctor.service-unknown\": { severityNote: \"warning\", meaning: \"loam.json names a `service` the fleet has no services/<id>/ for — and the fleet WAS read, so this is a claim about a real inventory rather than one nobody could take. Two states raise it: nobody has adopted that service yet, or an active feature INTRODUCES it — its only documents are that feature's specs/<id>/ until the feature archives. doctor's binding line and `currentService.introducedBy` say which; the message names the feature.\", fix: \"When a feature introduces it there is nothing to adopt — adopting would write services/<id>/ ahead of the merge. Run `loam status <FEAT-id>` for what this repository owes that feature; the warning clears when it archives. Otherwise run `loam adopt --service <id>` to onboard it. Either way, fix `service` in loam.json if it names the wrong service.\" },\n \"doctor.agent-files-missing\": { severityNote: \"warning\", meaning: \"Some of the command and skill files this loam lays down for the repo's recorded tools and profile are not here: the repo was initialized by an older loam, or they were deleted. An out-of-date command set costs entry points, never a refusal, which is why it is a warning.\", fix: \"Re-run `loam init --docs <dir> --tools <ids>` here. It creates absent files, refreshes only pointers whose current bytes still match their recorded digest, preserves every customized file, and keeps this repo's service binding.\" },\n \"doctor.agent-files-stale\": { severityNote: \"warning\", meaning: \"Command or skill files that ARE here differ from the body this binary writes and carry no loam stamp, or one older than this binary, so what they instruct an agent with may describe a loam that no longer exists. A file whose only difference is an older stamp is current and not reported; a customized body under a current stamp is not reported either, because the stamp records that somebody reviewed it. Safe refresh is a separate digest check performed by init.\", fix: \"Re-run `loam init` to refresh a pointer only when its recorded digest still matches. Review a customized file against the current body yourself and update its stamp, or delete it so init can recreate it; your edits always outrank the template.\" },\n },\n};\n\n/**\n * `loam status` — both forms print `next[]`, and each entry carries a `code` to\n * branch on, one sentence, and the literal `command` to run. So the \"what to\n * do\" column is genuinely empty for this whole family: the step IS the action,\n * and each `fix` below names the step's own command rather than inventing a\n * second instruction beside it.\n */\nconst NEXT_STEPS: Family = {\n scope: \"loam status\",\n codes: {\n \"next.adopt-bound\": { severityNote: \"step\", meaning: \"The fleet form's first entry: this repository's loam.json says it is a service the fleet has no services/<id>/ for, so nothing about the boundary you are standing in is written down yet. Ahead of every other service's adoption work, because it is the only step that is about HERE. When a feature in flight INTRODUCES that service, this step is not emitted: there is no code to adopt yet, and that feature's `next.feature` leads instead.\", fix: \"The step IS the action: run its `command`, `loam adopt --service <id> --json`.\" },\n \"next.author-landscape\": { severityNote: \"step\", meaning: \"The first rung of the first-hour ladder, over a fleet with no services and no features: architecture/landscape.likec4 does not exist, or is still the scaffold's untouched map with no service drawn on it.\", fix: \"The step IS the action: run its `command` — `loam init --create` when the file is absent, `loam seed --from fleet.yaml` when it is the untouched scaffold. loam never guesses who calls whom.\" },\n \"next.bind-service\": { severityNote: \"step\", meaning: \"First-hour ladder: no service repository is bound to this fleet yet, so no command can ever run from a service's own checkout.\", fix: \"The step IS the action: run its `command`, `loam init --docs <path-to-this-docs-repo> --service <service-id> --agent-profile service`, from a service's own repo, and commit the loam.json it writes. The service profile leaves loam-feature and loam-ship, which this docs repo keeps, out of the service checkout.\" },\n \"next.adopt-first\": { severityNote: \"step\", meaning: \"First-hour ladder: services/ is empty, so nothing about any service is written down and nothing can be graded against anything.\", fix: \"The step IS the action: run its `command`, `loam adopt --service <service-id> --json`; the brief it prints walks an agent through writing the baseline docs as draft.\" },\n \"next.adopt\": { severityNote: \"step\", meaning: \"One service in the fleet has no spec.md — nothing about it is written down, so no feature can be graded against it — or has one marked `adoption: partial`: `loam archive` wrote it from one feature's slice into a service nobody had adopted, so what the service already did is still unwritten. One entry per such service.\", fix: \"The step IS the action: run its `command`, `loam adopt --service <id> --json`. For a partial adoption the brief shows spec.md as present — write the baseline around the slice, never replace it — and then delete the `adoption: partial` line, which is the only thing that retires the step.\" },\n \"next.complete-service\": { severityNote: \"step\", meaning: \"Adoption does not end at spec.md: a service has one and no model.likec4, the state archive warns about and the fleet gate reports incomplete until something models it.\", fix: \"The step IS the action: run its `command`, `loam validate --service <id> --json`.\" },\n \"next.revouch\": { severityNote: \"step\", meaning: \"A vouched service's spec.md or arch.spec.md changed after the person read it — `content.stale`, computable from the docs repo because it needs nothing but the document. `status: verified` still stands, so every fleet readout says vouched (stale) and this step keeps `next.fleet-clean` from saying nothing is owed. One entry per service, naming the documents that moved.\", fix: \"Not an agent's step: its `execution` is a human review. Prepare the reading list with `loam vouch --pack --service <id>`, then a person re-reads what moved and runs the step's `command`, `loam vouch --service <id>`, from that service's own repository. Never revert the document or touch `content_digest` to silence it.\" },\n \"next.feature\": { severityNote: \"step\", meaning: \"One feature in flight that is not verified yet, with where it stands said in words — docs being written, docs ready with N of M claims answered, blocked — or, when it is blocked by another feature, the features it is waiting on. The fleet form lists every feature before any service's adoption rung. In a service repository whose bound service a feature introduces, the first entry is that feature's, saying so.\", fix: \"The step IS the action: run its `command`, `loam status <FEAT-id> --json`, for that feature's own next list.\" },\n \"next.archive\": { severityNote: \"step\", meaning: \"In the fleet form, a feature that is authored and verified: archive it, and everything queued behind it is released. In a feature's own list it is always the last entry. Archive merges the deltas into the living docs and checks the documents only — never the code or the verification record — so it will not stop you archiving work nobody built; finish the steps above it first.\", fix: \"The step IS the action: run its `command`, `loam archive <FEAT-id> --dry-run --json`; the dry run writes nothing and lists every file the merge would touch.\" },\n \"next.elided\": { severityNote: \"step\", meaning: \"The fleet list is capped, and this says how many steps it left out, counted by code. The list is ordered most-unblocking first, so what was elided is the least urgent — a list nobody reads is not navigation.\", fix: \"The step IS the action: run its `command`, `loam list --json`, or work down the printed list and run status again.\" },\n \"next.fleet-clean\": { severityNote: \"step\", meaning: \"Services exist, nothing is in flight, and nothing is owed. Only that truthful case: over an EMPTY fleet the same sentence was vacuously true, and the first-hour ladder owns that repository now.\", fix: \"The step IS the action: run its `command`, `loam validate --all --json`, then start the next feature.\" },\n \"next.fleet-gate\": { severityNote: \"step\", meaning: \"The last entry of every fleet list, and always present: `status` grades nothing, so the least it can do is say where grading happens — `loam validate --all` is the gate this repository has to pass and the one CI runs.\", fix: \"The step IS the action: run its `command`, `loam validate --all --json`.\" },\n \"next.recover-commit\": { severityNote: \"step\", meaning: \"Always first, and never elided by the fleet form's cap: a journaled writer was killed mid-commit, so everything below this step is derived from files that may be half-written. Where the journal itself cannot be read, nothing below can be trusted until a human compares the living docs against version control.\", fix: \"The step IS the action: run its `command` — the interrupted command re-run, which recovers first under the lock, or `loam doctor --json` when the journal is unreadable and no loam command can repair it.\" },\n \"next.archived\": { severityNote: \"step\", meaning: \"The whole `next[]` for an archived feature: its delta is folded into the living docs. Archiving checks documents, not code, so the step also says whether the feature was ever verified.\", fix: \"The step IS the action: run its `command`, `loam show <FEAT-id> --json`.\" },\n \"next.author-intent\": { severityNote: \"step\", meaning: \"The feature has no intent document — what it is for, in prose, before anything is derived from it.\", fix: \"The step IS the action: write the file the step names, then run its `command`, `loam validate <FEAT-id> --json`. The command never writes the artifact: loam does not author.\" },\n \"next.touch-service\": { severityNote: \"step\", meaning: \"The feature carries no per-service delta at all, so nothing says which governed boundaries it changes.\", fix: \"The step IS the action: run its `command`, `loam list services --json`, then add specs/<service>/spec.md for every service the feature changes.\" },\n \"next.author-spec\": { severityNote: \"step\", meaning: \"One service the feature touches has no requirement delta — the ADDED / MODIFIED / REMOVED requirements the feature makes to that service, each with a scenario.\", fix: \"The step IS the action: write the file the step names, then run its `command`, `loam delta <FEAT-id> --service <id> --json`, which projects the delta onto the living document.\" },\n \"next.author-openapi\": { severityNote: \"step\", meaning: \"Nothing gives one of the feature's services a living openapi.yaml, so this feature is the only thing that can write down its API surface. Deliberately not phrased as the service being absent from the living docs: a service adopted without a contract is the commoner case, and that wording sent readers looking for a directory that was right there.\", fix: \"The step IS the action: write the file the step names, then run its `command`, `loam delta <FEAT-id> --service <id> --json`.\" },\n \"next.author-scenarios\": { severityNote: \"step\", meaning: \"Requirements in one service's delta carry no `#### Scenario:`, so they generate no test and no verify claim — a promise that reaches neither the suite nor the done-check. One entry per service and never per requirement, because a delta with forty bare requirements would otherwise BE the payload.\", fix: \"The step IS the action: write a scenario under each bare requirement, then run its `command`, `loam delta <FEAT-id> --service <id> --json`.\" },\n \"next.rebase\": { severityNote: \"step\", meaning: \"The feature carries requirements or operations with no baseline pin, on any of the three axes; until they have one the merge cannot tell what it EDITS from what it merely quotes.\", fix: \"The step IS the action: run its `command`, `loam rebase <FEAT-id>`.\" },\n \"next.archive-first\": { severityNote: \"step\", meaning: \"The feature builds on other features still in flight, which have to archive before it can.\", fix: \"The step IS the action: run its `command`, `loam dependencies <FEAT-id> --json`.\" },\n \"next.fix-coherence\": { severityNote: \"step\", meaning: \"The feature has findings that stop it, named starting with the first. Everything EITHER gate refuses on is counted, so a warning marked as gating archive is in the tally even though `validate` grades the feature valid — which is why its exit code alone will not show you why archive refuses.\", fix: \"The step IS the action: run its `command`, `loam validate <FEAT-id> --json`.\" },\n \"next.generate-tests\": { severityNote: \"step\", meaning: \"The feature's delta for a service carries scenarios no test run has answered yet. `loam gherkin` writes the .feature files whose green run is the only thing that may answer a `scenario.tested` claim, and it writes into the service's own repository — so the step names which repo to run it in when that is not this one.\", fix: \"The step IS the action: run its `command`, `loam gherkin <FEAT-id> --service <id>`, from that service's own checkout.\" },\n \"next.verify\": { severityNote: \"step\", meaning: \"The done-check has not been started, or its record cannot be used. Five situations share this code because they share the work — nothing recorded, a record file that does not read as a record, a record the feature has moved out from under, a record that answers no claims at all, and a feature with nothing to derive a checklist from yet — and the step's own statement says which.\", fix: \"The step IS the action: run its `command`, `loam verify <FEAT-id> --json`, which derives the checklist and prints what it asks. A record file nothing can read is repaired by hand or, when it is one service's own `verification/<svc>.yaml`, deleted and recorded again by that service; the one-file `verification.yaml` may hold other services' attestations and is restored from version control, never deleted. Nothing overwrites it while it is unreadable.\" },\n \"next.verify-unconfirmed\": { severityNote: \"step\", meaning: \"Claims on the feature are open — unconfirmed or unanswered — and this repository is not one of the services that owes an answer, so the recording form is not a step anyone can take from here.\", fix: \"The step IS the action: run its `command`, `loam verify <FEAT-id> --json`. The open claims are closed from each affected service's own repository.\" },\n \"next.attest-service\": { severityNote: \"step\", meaning: \"Claims are open AND this repository is one of the services that owes an answer, so the recording form is nameable here: `--record --service` binds the answers to this repo's HEAD and refuses anywhere else.\", fix: \"The step IS the action: run its `command`, `loam verify <FEAT-id> --record answers.json --service <id>`, answering the claims filed under this service; the rest belong to their own repositories.\" },\n \"next.verify-attested\": { severityNote: \"step\", meaning: \"Every claim is answered and some scenario claims are confirmed on an agent's word rather than on a test run (`verify.scenario-attested`) — complete work resting on an assertion, which is what `ready` has always meant here.\", fix: \"The step IS the action: run its `command`, `loam verify <FEAT-id> --results <report.json>` — a cucumber JSON report, or loam's runner-neutral `loamScenarioReport` shape for any other runner — and the record stops resting on an assertion.\" },\n },\n};\n\n/**\n * `loam diff` — what CHANGED between a base git ref of the docs repo and the\n * working tree, not what is WRONG with either. That is why most rows below have\n * no repair: the meanings are the `DiffCode` union's own doc comments\n * (core/diff/semantic.ts), and the two error rows are the only ones naming a\n * repair. The two `-modified` rows name work too, but not loam's: whether a\n * changed schema breaks its readers is the specialist diff's answer.\n */\nconst DIFF: Family = {\n scope: \"loam diff --base <ref>\",\n codes: {\n \"diff.service-added\": { severityNote: \"ok\", meaning: \"A services/<id>/ directory exists now that did not exist at the base ref.\", fix: \"Nothing to fix: `loam diff` says what changed between two points of the living docs, never what is wrong with them. This is the class of the change, for a reviewer to read.\" },\n \"diff.service-removed\": { severityNote: \"warn\", meaning: \"A service present at the base ref is gone from the working tree; the finding names the directory it occupied.\", fix: \"A review question rather than a defect: nothing in the working tree describes that boundary any more. `loam validate --all` is what grades the fleet that is left.\" },\n \"diff.requirement-added\": { severityNote: \"ok\", meaning: \"A living requirement not present at base — by `Requirement-ID:` where one is authored, by heading otherwise, the same join `loam rebase` pins against.\", fix: \"Nothing to fix: this is the class of the change, for a reviewer to read.\" },\n \"diff.requirement-removed\": { severityNote: \"warn\", meaning: \"A requirement present at the base ref is no longer in the living spec under the same identity.\", fix: \"A review question. A requirement that CHANGED identity — a new `Requirement-ID:`, a renamed heading — reads here as a removal plus an addition, which is the join being honest about what it can see rather than guessing a rename.\" },\n \"diff.requirement-modified\": { severityNote: \"ok\", meaning: \"The same requirement identity is on both sides and its digest moved. A rebase pin never moves that digest, so this is a real edit to the requirement's text.\", fix: \"Nothing to fix: this is the class of the change, for a reviewer to read.\" },\n \"diff.op-added\": { severityNote: \"ok\", meaning: \"An operationId in the living contract that was absent at the base ref; the message names its method and path.\", fix: \"Nothing to fix: this is the class of the change, for a reviewer to read.\" },\n \"diff.op-removed\": { severityNote: \"warn\", meaning: \"A base operationId is gone from the living contract and no current edge of the `architecture/` project, requirement or use-case hop names it — or, in the second wording this code also carries, whether one does could NOT be fully answered, and the details name the possible consumers nobody could check: a consumer document that was not scannable, or a landscape edge into this service drawn with no `metadata { op }`.\", fix: \"Read which of the two sentences it is. Nobody could be checked is never nobody names it: an unreadable document carries the run to exit 1 on its own, and an edge with no op is answered by putting the operation it calls on the edge (`spine.op-link-missing` names the same edge).\" },\n \"diff.op-removed-consumed\": { severityNote: \"error\", meaning: \"An operation was removed since the base ref and the current fleet still names it — an edge of the `architecture/` project, another service's requirement in spec.md or arch.spec.md (not one naming its own service's operation of the same id), or a use-case hop attributed to it: the consumers the archive gate refuses on too. The details list the victims, and the finding sets `breaking`.\", fix: \"These joins break. Either restore the operation, or land the consumers' own deltas in the same change so nothing in the fleet is left calling something that is gone.\" },\n \"diff.op-deprecated\": { severityNote: \"warn\", meaning: \"`deprecated: true` was introduced on an operation since the base ref. The details name the current consumers, under one of three deliberately honest phrasings: some still name it, none does, or whether any does could not be fully answered.\", fix: \"Deprecation is a promise to the consumers the details name, and nothing is broken yet. Read which phrasing it is before treating a silent list as an empty one.\" },\n \"diff.op-modified\": { severityNote: \"warn\", meaning: \"The same operationId is on both sides and the operation changed: its own definition, its method or path, or anything its internal `$ref`s reach — a field renamed in a shared `components` schema counts. The details name the authored consumers, the same scan `diff.op-deprecated` runs. loam does not read what a schema says, so it never grades whether the change is breaking.\", fix: \"Run `oasdiff breaking` on the two states of this contract to learn whether it breaks anyone; the details are who to tell. A warning on purpose: a new optional field and a renamed required one look identical from here.\" },\n \"diff.message-added\": { severityNote: \"ok\", meaning: \"An AsyncAPI message name absent at the base ref.\", fix: \"Nothing to fix: this is the class of the change, for a reviewer to read.\" },\n \"diff.message-removed\": { severityNote: \"warn\", meaning: \"A base message is gone. The finding says which of three cases it is: another current service still sends it (an `action: send` operation — a service that only receives it is a consumer) or an `#external` element still publishes it (a `publishes` edge from it in the `architecture/` project, the outside producer `spine.message-unproduced` accepts), nothing currently consumes it, or whether anything does could not be fully answered because some consumer documents were not scannable.\", fix: \"Read which case it is. A name another service still sends, or an `#external` element still publishes, is not orphaned, and an unanswerable scan is not an empty one — only positive evidence vouches here.\" },\n \"diff.message-removed-consumed\": { severityNote: \"error\", meaning: \"A message was removed since the base ref and the current fleet still consumes it — a `Consumes:` line in either spec file, a consumes edge of the `architecture/` project, or a use-case hop it backs. The details list the victims, and the finding sets `breaking`.\", fix: \"These joins break. Either restore the message, or land the consumers' own deltas in the same change.\" },\n \"diff.message-modified\": { severityNote: \"warn\", meaning: \"The same AsyncAPI message name is on both sides and its declaration, or anything its internal `$ref`s reach, changed — a payload field renamed counts. The details name the authored consumers: consumes-edges, `Consumes:` lines and the use-case hops they back. Content equality only: nothing inside the payload is ever joined on, and whether the change breaks a consumer is not graded.\", fix: \"Run `asyncapi diff` on the two states of this contract to learn whether it breaks anyone; the details are who to tell.\" },\n \"diff.consumer-added\": { severityNote: \"ok\", meaning: \"A cross-service join appeared since base: another service's living requirements — spec.md or arch.spec.md — now name this service's operation or message. A line naming an operation the consumer's own contract defines names its own, and is no join. Filed on the PROVIDER — the service whose surface the join lands on.\", fix: \"Nothing to fix, and the change class most worth reading: a new consumer is a new obligation on this service's contract, and removing that operation later is what `diff.op-removed-consumed` will be about.\" },\n \"diff.consumer-removed\": { severityNote: \"ok\", meaning: \"A cross-service join present at the base ref is gone: a consumer's living requirements no longer name this service's operation or message.\", fix: \"Nothing to fix: this is the class of the change, for a reviewer to read.\" },\n },\n};\n\n/**\n * `loam gate` — the can-i-deploy question, a pure query over evidence other\n * commands already recorded. Nothing here re-derives a coherence plan, so every\n * repair below is somebody else's command.\n */\nconst GATE: Family = {\n scope: \"loam gate\",\n codes: {\n \"gate.partners-unknown\": { severityNote: \"warn when the map is absent; error when it exists and cannot be used\", meaning: \"The partner set for the gated service could not be derived from architecture/landscape.likec4 — it is absent, or it exists and does not parse. That means nobody could look, never that nothing joins this service. Absent is a warning because a repo before its first adopt legitimately has no map yet; a broken map is an error because `loam validate --all` fails that repo for the same file, and a deploy gate passing where the fleet gate fails would be the quieter of two contradictory verdicts.\", fix: \"Fix the landscape and re-run. `loam validate --all` diagnoses the file itself; this check only refuses the false silence.\" },\n \"gate.service-undocumented\": { severityNote: \"error\", meaning: \"The service being deployed sits below `documented` on the adoption ladder, so the docs cannot say what its joins even are and no recorded evidence can answer the deploy question. That includes a spec.md marked `adoption: partial` — one archived feature's slice, written into a service nobody had adopted. The details list what the next rung wants.\", fix: \"Author the baseline — `loam adopt --service <id>` briefs exactly what is missing — and this check passes once the required artifact set exists; for a partial adoption, write the rest of spec.md from the code and then delete its `adoption: partial` line.\" },\n \"gate.partner-undocumented\": { severityNote: \"warn\", meaning: \"A service that joins the gated one has no services/<id>/ directory at all, or has one sitting below `documented`: its side of the join is not recorded, so the gate cannot see what that partner promises. An `#external` partner is exempt on purpose — somebody else's system is unrecorded by design.\", fix: \"Adopt the partner (`loam adopt --service <id>` briefs it), bind its landscape element to the right service with `metadata { service '<id>' }`, or tag it `#external` if it is not ours.\" },\n \"gate.feature-unverified\": { severityNote: \"warn\", meaning: \"An active feature touching the gated service — or, under `--since <ref>`, one archived after that docs-repo ref (its `features/archive/` directory absent at the ref, or changed since: a feature unarchived and archived again ships again) — is not verified: no record at all, a record file that does not read as a record, a record the feature moved out from under (for an archived feature, one that no longer answered the checklist `loam archive` captured as it merged), a record answering no claims, or open claims counted in the message. A record that is merely `attested` is NOT reported under this code — it carries `verify.scenario-attested` instead, because complete work resting on an assertion is a different fact from work nobody checked. Without `--since` an archived feature is never read, so archiving one takes it out of this check.\", fix: \"Derive the checklist and answer every claim with evidence: `loam verify <FEAT-id> --json`. A record file nothing can read is repaired by hand or, when it is one service's own `verification/<svc>.yaml`, deleted and recorded again by that service; the one-file `verification.yaml` may hold other services' attestations and is restored from version control, never deleted. Nothing overwrites it while it is unreadable. An archived feature's record is frozen: `loam unarchive <FEAT-id>` re-opens it if its claims must be answered before the deploy.\" },\n },\n};\n\n/** In listing order, though every consumer sorts by code — the order is documentation, not contract. */\nconst FAMILIES: readonly Family[] = [DOCTOR, NEXT_STEPS, DIFF, GATE];\n\n/** One family row, in the shape `FindingEntry` (lookup.ts) takes. */\nexport interface FamilyFinding extends FamilyEntry {\n readonly scope: string;\n}\n\n/**\n * The registry's answer for one subject, or null.\n *\n * Built per call over constants already in memory, never cached at module\n * level, for the reason lookup.ts's header gives: tests fork and chdir, and the\n * MCP server outlives many calls.\n */\nexport function familyFinding(subject: string): FamilyFinding | null {\n for (const family of FAMILIES) {\n const entry = family.codes[subject];\n if (entry !== undefined) return { scope: family.scope, ...entry };\n }\n return null;\n}\n\n/** Every code the registry answers, sorted — the same plain sort the code inventory uses. */\nexport function familyCodes(): string[] {\n return FAMILIES.flatMap((family) => Object.keys(family.codes)).sort();\n}\n"]}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * The fix-table parser: `loam explain`'s finding-code content, read at runtime
3
+ * out of the workflow bodies the binary ships. Every protocol body in
4
+ * `COMMANDS` is walked, so a table added to any workflow is picked up without
5
+ * touching this parser — today the tables live in the /loam-check body
6
+ * (src/core/agent/workflows/check.ts) and the /loam-verify body's notice
7
+ * table (src/core/agent/workflows/closing.ts).
8
+ *
9
+ * A PARSER rather than a table of its own, deliberately: the /loam-check fix
10
+ * tables are already the documentation corpus test/codes-drift.test.ts holds
11
+ * every emitted finding code against, so they are the one place the
12
+ * meaning-and-fix prose is guaranteed to exist and to stay current. A second
13
+ * copy inside an `explain` registry would be exactly the hand-maintained map
14
+ * that silently trails the binary — worse than no command. Reading the shipped
15
+ * constant instead means `loam explain spine.op-undefined` and the /loam-check
16
+ * page cannot disagree, because they are the same bytes.
17
+ *
18
+ * The same walk also STRIPS those tables (`withoutFixTables`), which is what
19
+ * `loam instructions <workflow> --no-fix-tables` prints. One walk and not two,
20
+ * deliberately: a stripper carrying a regex of its own would be free to
21
+ * disagree with the parser about where a table begins and ends, and the failure
22
+ * that produces is both silent and precisely the wrong one — a narrowed
23
+ * protocol whose omitted rows `loam explain` cannot answer, telling an agent to
24
+ * look up a code nothing explains. Sharing the block detection makes "what was
25
+ * dropped" and "what can be explained" the same computation rather than two
26
+ * that agree today.
27
+ *
28
+ * The row grammar this depends on (test/explain.test.ts pins it with probes
29
+ * and a count floor, so a table reformat fails loudly instead of leaving the
30
+ * lookup silently empty):
31
+ *
32
+ * | `a.code` / `b.code` (severity note) | what it means | what to do |
33
+ *
34
+ * - the first cell holds one or more backticked codes and an optional trailing
35
+ * parenthetical severity note, printed verbatim (`(warn)`, `(error, or
36
+ * warn)`, `(warn, gates archive; one per service)`, `(ok)`); a row with no
37
+ * note is an error, the tables' own default;
38
+ * - cells never contain the ` | ` separator today; if a meaning cell ever
39
+ * grows one, the probes convict the mis-split rather than letting it ship;
40
+ * - the paragraph introducing each table (`` `--service <id>` — one service's
41
+ * own axes… ``) names the scope its rows are graded in, so a code that
42
+ * appears in two tables (`spec.merge-conflict`) explains both contexts.
43
+ */
44
+ const CODE_SPAN = /`([a-z][a-z0-9.-]*)`/g;
45
+ const SEVERITY_NOTE = /\(([^)]+)\)\s*$/;
46
+ /**
47
+ * The scope label: the introducing paragraph's first line up to its ` — `
48
+ * dash, backticks stripped — "`--feature <FEAT-id>` — a change's three axes…"
49
+ * labels its rows `--feature <FEAT-id>`. A paragraph with no dash (none exist
50
+ * today) falls back to its whole first line minus the trailing colon.
51
+ */
52
+ function scopeLabel(firstLine) {
53
+ const head = firstLine.split(" — ")[0] ?? firstLine;
54
+ return head.replace(/`/g, "").replace(/:$/, "").trim();
55
+ }
56
+ /**
57
+ * Split one table row into its cells, or null for a line that is not a
58
+ * three-cell row (the `|---|---|---|` separator has no ` | ` and yields one
59
+ * cell). More than three cells re-joins the tail into the fix column — the
60
+ * meaning cell is the split's second field either way, and the probe tests
61
+ * are what convict a cell that ever grows a ` | ` of its own.
62
+ */
63
+ function splitRow(line) {
64
+ if (!line.startsWith("|") || !line.endsWith("|"))
65
+ return null;
66
+ const cells = line.slice(1, -1).split(" | ").map((cell) => cell.trim());
67
+ return cells.length >= 3 ? cells : null;
68
+ }
69
+ /**
70
+ * Every fix table of one workflow body, in document order, each with its rows.
71
+ *
72
+ * The scope tracking is why this walks lines rather than matching rows
73
+ * globally: each table's introducing paragraph ends one blank line above the
74
+ * header row, so the label is the most recently COMPLETED paragraph when a
75
+ * table opens (or the one still being built, for a table glued directly under
76
+ * its intro).
77
+ *
78
+ * A run of consecutive `|` lines is one block, and the first line that is not
79
+ * one closes it. That is the whole grammar — markdown gives a table no other
80
+ * terminator — and it is why the blank line after a table belongs to what
81
+ * follows rather than to the block.
82
+ */
83
+ function fixTableBlocks(body) {
84
+ const lines = body.split("\n");
85
+ const blocks = [];
86
+ let paragraph = [];
87
+ let lastParagraph = [];
88
+ let scope = "";
89
+ let open = null;
90
+ for (const [index, raw] of lines.entries()) {
91
+ const line = raw.trimEnd();
92
+ if (!line.startsWith("|")) {
93
+ if (open !== null) {
94
+ blocks.push({ start: open.start, end: index, rows: open.rows });
95
+ open = null;
96
+ }
97
+ if (line === "") {
98
+ if (paragraph.length > 0)
99
+ lastParagraph = paragraph;
100
+ paragraph = [];
101
+ }
102
+ else {
103
+ paragraph.push(line);
104
+ }
105
+ continue;
106
+ }
107
+ const intro = paragraph.length > 0 ? paragraph : lastParagraph;
108
+ if (intro.length > 0) {
109
+ scope = scopeLabel(intro[0]);
110
+ // Consumed: the next table needs its own intro, not this one again.
111
+ lastParagraph = [];
112
+ paragraph = [];
113
+ }
114
+ if (open === null)
115
+ open = { start: index, rows: [] };
116
+ const cells = splitRow(line);
117
+ if (cells === null)
118
+ continue;
119
+ const codeCell = cells[0];
120
+ const codes = [...codeCell.matchAll(CODE_SPAN)].map((m) => m[1]);
121
+ // The `| code | what it means | …` header row has no backticked code.
122
+ if (codes.length === 0)
123
+ continue;
124
+ open.rows.push({
125
+ codes,
126
+ severityNote: SEVERITY_NOTE.exec(codeCell)?.[1] ?? "error",
127
+ meaning: cells[1],
128
+ fix: cells.slice(2).join(" | "),
129
+ scope,
130
+ });
131
+ }
132
+ // A body ending mid-table has no closing line to end the block; today every
133
+ // body ends in prose, and a table that is the last thing in one must still
134
+ // be seen rather than silently dropped from the lookup.
135
+ if (open !== null)
136
+ blocks.push({ start: open.start, end: lines.length, rows: open.rows });
137
+ return blocks;
138
+ }
139
+ /** Every fix-table row of one workflow body, in document order. */
140
+ export function parseFixRows(body) {
141
+ return fixTableBlocks(body).flatMap((block) => [...block.rows]);
142
+ }
143
+ /**
144
+ * The same body with every fix table collapsed to one line naming what was
145
+ * dropped and how to get it back.
146
+ *
147
+ * What this is FOR: /loam-check's body is 83 KB, about a fifth of a 100k-token
148
+ * window, and every generated command and skill file opens by telling an agent
149
+ * to run it. The rows are the whole of that weight and almost none of them are
150
+ * about the run in hand — `loam explain <code>` answers one row in 473 bytes,
151
+ * which is the lazy path this makes payable.
152
+ *
153
+ * The introducing PARAGRAPH stays, and that is not a formatting nicety. It is
154
+ * the sentence that says which scope a code was graded in (`--service <id>`,
155
+ * `--feature <FEAT-id>`, `loam archive`), and the same code means different
156
+ * things in two of them — `spec.merge-conflict` is graded on a living document
157
+ * and on a delta of it. Drop the intro and the remaining prose stops saying
158
+ * which run it is describing.
159
+ */
160
+ export function withoutFixTables(body) {
161
+ const lines = body.split("\n");
162
+ const out = [];
163
+ let at = 0;
164
+ for (const { start, end, rows } of fixTableBlocks(body)) {
165
+ // A block with no parsed rows is not a fix table — a two-column table, or
166
+ // a row grammar that has moved. Left standing rather than replaced by a
167
+ // line claiming rows nobody can look up.
168
+ if (rows.length === 0)
169
+ continue;
170
+ out.push(...lines.slice(at, start));
171
+ out.push(`(${rows.length} row${rows.length === 1 ? "" : "s"} omitted — ` +
172
+ `run \`loam explain <code>\` on any code this run reports.)`);
173
+ at = end;
174
+ }
175
+ out.push(...lines.slice(at));
176
+ return out.join("\n");
177
+ }
178
+ //# sourceMappingURL=fix-tables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix-tables.js","sourceRoot":"","sources":["../../../src/core/explain/fix-tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAeH,MAAM,SAAS,GAAG,uBAAuB,CAAC;AAC1C,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAExC;;;;;GAKG;AACH,SAAS,UAAU,CAAC,SAAiB;IACnC,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;IACpD,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACzD,CAAC;AAED;;;;;;GAMG;AACH,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACxE,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C,CAAC;AAmBD;;;;;;;;;;;;;GAaG;AACH,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,IAAI,SAAS,GAAa,EAAE,CAAC;IAC7B,IAAI,aAAa,GAAa,EAAE,CAAC;IACjC,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,IAAI,GAA6C,IAAI,CAAC;IAC1D,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAChE,IAAI,GAAG,IAAI,CAAC;YACd,CAAC;YACD,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;gBAChB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;oBAAE,aAAa,GAAG,SAAS,CAAC;gBACpD,SAAS,GAAG,EAAE,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;YACD,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;QAC/D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;YAC9B,oEAAoE;YACpE,aAAa,GAAG,EAAE,CAAC;YACnB,SAAS,GAAG,EAAE,CAAC;QACjB,CAAC;QACD,IAAI,IAAI,KAAK,IAAI;YAAE,IAAI,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACrD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;QAClE,sEAAsE;QACtE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACjC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACb,KAAK;YACL,YAAY,EAAE,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO;YAC1D,OAAO,EAAE,KAAK,CAAC,CAAC,CAAE;YAClB,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YAC/B,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IACD,4EAA4E;IAC5E,2EAA2E;IAC3E,wDAAwD;IACxD,IAAI,IAAI,KAAK,IAAI;QAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1F,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,KAAK,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QACxD,0EAA0E;QAC1E,wEAAwE;QACxE,yCAAyC;QACzC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAChC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QACpC,GAAG,CAAC,IAAI,CACN,IAAI,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,aAAa;YAC7D,4DAA4D,CAC/D,CAAC;QACF,EAAE,GAAG,GAAG,CAAC;IACX,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7B,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC","sourcesContent":["/**\n * The fix-table parser: `loam explain`'s finding-code content, read at runtime\n * out of the workflow bodies the binary ships. Every protocol body in\n * `COMMANDS` is walked, so a table added to any workflow is picked up without\n * touching this parser — today the tables live in the /loam-check body\n * (src/core/agent/workflows/check.ts) and the /loam-verify body's notice\n * table (src/core/agent/workflows/closing.ts).\n *\n * A PARSER rather than a table of its own, deliberately: the /loam-check fix\n * tables are already the documentation corpus test/codes-drift.test.ts holds\n * every emitted finding code against, so they are the one place the\n * meaning-and-fix prose is guaranteed to exist and to stay current. A second\n * copy inside an `explain` registry would be exactly the hand-maintained map\n * that silently trails the binary — worse than no command. Reading the shipped\n * constant instead means `loam explain spine.op-undefined` and the /loam-check\n * page cannot disagree, because they are the same bytes.\n *\n * The same walk also STRIPS those tables (`withoutFixTables`), which is what\n * `loam instructions <workflow> --no-fix-tables` prints. One walk and not two,\n * deliberately: a stripper carrying a regex of its own would be free to\n * disagree with the parser about where a table begins and ends, and the failure\n * that produces is both silent and precisely the wrong one — a narrowed\n * protocol whose omitted rows `loam explain` cannot answer, telling an agent to\n * look up a code nothing explains. Sharing the block detection makes \"what was\n * dropped\" and \"what can be explained\" the same computation rather than two\n * that agree today.\n *\n * The row grammar this depends on (test/explain.test.ts pins it with probes\n * and a count floor, so a table reformat fails loudly instead of leaving the\n * lookup silently empty):\n *\n * | `a.code` / `b.code` (severity note) | what it means | what to do |\n *\n * - the first cell holds one or more backticked codes and an optional trailing\n * parenthetical severity note, printed verbatim (`(warn)`, `(error, or\n * warn)`, `(warn, gates archive; one per service)`, `(ok)`); a row with no\n * note is an error, the tables' own default;\n * - cells never contain the ` | ` separator today; if a meaning cell ever\n * grows one, the probes convict the mis-split rather than letting it ship;\n * - the paragraph introducing each table (`` `--service <id>` — one service's\n * own axes… ``) names the scope its rows are graded in, so a code that\n * appears in two tables (`spec.merge-conflict`) explains both contexts.\n */\n\nexport interface FixRow {\n /** The backticked code(s) of the row's first cell — multi-code rows share one meaning. */\n readonly codes: readonly string[];\n /** The verbatim parenthetical from the first cell, or \"error\" — the tables' default. */\n readonly severityNote: string;\n /** The \"what it means\" cell, verbatim. */\n readonly meaning: string;\n /** The \"what to do\" cell, verbatim. */\n readonly fix: string;\n /** The short label of the table's introducing paragraph (`--service <id>`, `loam archive`, …). */\n readonly scope: string;\n}\n\nconst CODE_SPAN = /`([a-z][a-z0-9.-]*)`/g;\nconst SEVERITY_NOTE = /\\(([^)]+)\\)\\s*$/;\n\n/**\n * The scope label: the introducing paragraph's first line up to its ` — `\n * dash, backticks stripped — \"`--feature <FEAT-id>` — a change's three axes…\"\n * labels its rows `--feature <FEAT-id>`. A paragraph with no dash (none exist\n * today) falls back to its whole first line minus the trailing colon.\n */\nfunction scopeLabel(firstLine: string): string {\n const head = firstLine.split(\" — \")[0] ?? firstLine;\n return head.replace(/`/g, \"\").replace(/:$/, \"\").trim();\n}\n\n/**\n * Split one table row into its cells, or null for a line that is not a\n * three-cell row (the `|---|---|---|` separator has no ` | ` and yields one\n * cell). More than three cells re-joins the tail into the fix column — the\n * meaning cell is the split's second field either way, and the probe tests\n * are what convict a cell that ever grows a ` | ` of its own.\n */\nfunction splitRow(line: string): string[] | null {\n if (!line.startsWith(\"|\") || !line.endsWith(\"|\")) return null;\n const cells = line.slice(1, -1).split(\" | \").map((cell) => cell.trim());\n return cells.length >= 3 ? cells : null;\n}\n\n/**\n * One fix table as it sits in a body: which lines it occupies, and the rows\n * read out of them.\n *\n * The line span is what makes the stripper possible without a second notion of\n * where a table is. `start` is the header row (`| code | what it means | …`)\n * and `end` is one PAST the last table line, so `lines.slice(start, end)` is\n * exactly the block and `lines.slice(end)` is exactly what follows it — the\n * blank line and the next paragraph included, which is why the introducing\n * paragraph survives a strip.\n */\ninterface TableBlock {\n readonly start: number;\n readonly end: number;\n readonly rows: readonly FixRow[];\n}\n\n/**\n * Every fix table of one workflow body, in document order, each with its rows.\n *\n * The scope tracking is why this walks lines rather than matching rows\n * globally: each table's introducing paragraph ends one blank line above the\n * header row, so the label is the most recently COMPLETED paragraph when a\n * table opens (or the one still being built, for a table glued directly under\n * its intro).\n *\n * A run of consecutive `|` lines is one block, and the first line that is not\n * one closes it. That is the whole grammar — markdown gives a table no other\n * terminator — and it is why the blank line after a table belongs to what\n * follows rather than to the block.\n */\nfunction fixTableBlocks(body: string): TableBlock[] {\n const lines = body.split(\"\\n\");\n const blocks: TableBlock[] = [];\n let paragraph: string[] = [];\n let lastParagraph: string[] = [];\n let scope = \"\";\n let open: { start: number; rows: FixRow[] } | null = null;\n for (const [index, raw] of lines.entries()) {\n const line = raw.trimEnd();\n if (!line.startsWith(\"|\")) {\n if (open !== null) {\n blocks.push({ start: open.start, end: index, rows: open.rows });\n open = null;\n }\n if (line === \"\") {\n if (paragraph.length > 0) lastParagraph = paragraph;\n paragraph = [];\n } else {\n paragraph.push(line);\n }\n continue;\n }\n const intro = paragraph.length > 0 ? paragraph : lastParagraph;\n if (intro.length > 0) {\n scope = scopeLabel(intro[0]!);\n // Consumed: the next table needs its own intro, not this one again.\n lastParagraph = [];\n paragraph = [];\n }\n if (open === null) open = { start: index, rows: [] };\n const cells = splitRow(line);\n if (cells === null) continue;\n const codeCell = cells[0]!;\n const codes = [...codeCell.matchAll(CODE_SPAN)].map((m) => m[1]!);\n // The `| code | what it means | …` header row has no backticked code.\n if (codes.length === 0) continue;\n open.rows.push({\n codes,\n severityNote: SEVERITY_NOTE.exec(codeCell)?.[1] ?? \"error\",\n meaning: cells[1]!,\n fix: cells.slice(2).join(\" | \"),\n scope,\n });\n }\n // A body ending mid-table has no closing line to end the block; today every\n // body ends in prose, and a table that is the last thing in one must still\n // be seen rather than silently dropped from the lookup.\n if (open !== null) blocks.push({ start: open.start, end: lines.length, rows: open.rows });\n return blocks;\n}\n\n/** Every fix-table row of one workflow body, in document order. */\nexport function parseFixRows(body: string): FixRow[] {\n return fixTableBlocks(body).flatMap((block) => [...block.rows]);\n}\n\n/**\n * The same body with every fix table collapsed to one line naming what was\n * dropped and how to get it back.\n *\n * What this is FOR: /loam-check's body is 83 KB, about a fifth of a 100k-token\n * window, and every generated command and skill file opens by telling an agent\n * to run it. The rows are the whole of that weight and almost none of them are\n * about the run in hand — `loam explain <code>` answers one row in 473 bytes,\n * which is the lazy path this makes payable.\n *\n * The introducing PARAGRAPH stays, and that is not a formatting nicety. It is\n * the sentence that says which scope a code was graded in (`--service <id>`,\n * `--feature <FEAT-id>`, `loam archive`), and the same code means different\n * things in two of them — `spec.merge-conflict` is graded on a living document\n * and on a delta of it. Drop the intro and the remaining prose stops saying\n * which run it is describing.\n */\nexport function withoutFixTables(body: string): string {\n const lines = body.split(\"\\n\");\n const out: string[] = [];\n let at = 0;\n for (const { start, end, rows } of fixTableBlocks(body)) {\n // A block with no parsed rows is not a fix table — a two-column table, or\n // a row grammar that has moved. Left standing rather than replaced by a\n // line claiming rows nobody can look up.\n if (rows.length === 0) continue;\n out.push(...lines.slice(at, start));\n out.push(\n `(${rows.length} row${rows.length === 1 ? \"\" : \"s\"} omitted — ` +\n `run \\`loam explain <code>\\` on any code this run reports.)`,\n );\n at = end;\n }\n out.push(...lines.slice(at));\n return out.join(\"\\n\");\n}\n"]}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * The explain lookup: one subject in — a finding code, an envelope refusal
3
+ * code, or a concept term — one discriminated explanation out. It also answers
4
+ * the two listings the command prints with no subject: `listTerms` for the
5
+ * concept vocabulary and `listCodes` for the code vocabulary, the latter built
6
+ * from the same `findingIn` the per-code answer uses so the inventory cannot
7
+ * describe a code differently from the page about it.
8
+ *
9
+ * Assembled ON DEMAND, never cached at module level: tests run in forked
10
+ * processes that chdir per invocation, and a long-running host (the MCP
11
+ * server) outlives many calls — a table built at import time is exactly the
12
+ * module-level mutable state AGENTS.md names as a hazard. The build is a walk
13
+ * over constants already in memory, so there is nothing worth caching anyway.
14
+ *
15
+ * Resolution order — finding tables first, then the family registry, then
16
+ * refusal codes, then terms — IS the tie-break: a subject in two families
17
+ * would silently take the earlier family's answer (a refusal named like a term
18
+ * alias would win over the term). No naming convention keeps them apart —
19
+ * `based-on` is a dashed term alias, exactly the shape a refusal code takes —
20
+ * so test/explain.test.ts asserts the key sets are pairwise disjoint, and the
21
+ * order never actually decides anything.
22
+ *
23
+ * The one place that order is load-bearing anyway is the fix tables against
24
+ * ./families.ts: the tables are PARSED from the bytes the binary ships and the
25
+ * registry is written by hand, so where both could answer, the parsed prose has
26
+ * to win and the hand-written row must never silently shadow it. It is written
27
+ * first here and asserted disjoint there, which makes the precedence a fact
28
+ * about the code as well as a fact about the data.
29
+ */
30
+ import { COMMANDS } from "../agent/protocol.js";
31
+ import { VALIDATE_CHECKS } from "../brief/checks.js";
32
+ import { familyCodes, familyFinding } from "./families.js";
33
+ import { parseFixRows } from "./fix-tables.js";
34
+ import { REFUSAL_MEANINGS } from "./refusals.js";
35
+ import { TERM_GROUPS, TERMS } from "./terms.js";
36
+ /** Every fix-table row shipped in the workflow bodies, in protocol order. */
37
+ function allRows() {
38
+ return COMMANDS.flatMap((command) => parseFixRows(command.body));
39
+ }
40
+ function briefFor(subject) {
41
+ return VALIDATE_CHECKS.find((check) => check.code === subject);
42
+ }
43
+ /** Terms match case-insensitively, by name or alias — codes stay exact, they are already lowercase by grammar. */
44
+ function termFor(subject) {
45
+ const wanted = subject.toLowerCase();
46
+ return TERMS.find((entry) => entry.term === wanted || entry.aliases.includes(wanted));
47
+ }
48
+ /**
49
+ * The finding answer for one subject out of rows ALREADY parsed, or null when
50
+ * no table grades it.
51
+ *
52
+ * Split out of `explainSubject` so `listCodes` builds its rows through the
53
+ * very same function rather than a parallel one: the inventory's per-code
54
+ * payload is then the per-code answer by construction, not by two pieces of
55
+ * code agreeing. It also keeps the inventory's cost linear — `explainSubject`
56
+ * re-parses every workflow body on each call, and calling it 270 times to
57
+ * enumerate the vocabulary would re-walk the whole corpus 270 times.
58
+ */
59
+ function findingIn(rows, subject) {
60
+ const brief = briefFor(subject);
61
+ // VALIDATE_CHECKS contributes `via` ONLY, never a fallback entry. An
62
+ // earlier draft synthesized a row from the brief when the tables had none,
63
+ // and that fallback was both unreachable (every brief check has a table
64
+ // row, pinned by test/explain.test.ts) and wrong if ever reached: its
65
+ // scope would have been the brief's invocation string, a spelling no
66
+ // parsed row uses. A brief check that LOSES its table row should fail
67
+ // loudly there — explain refusing is the tripwire — not render a
68
+ // one-of-a-kind page nobody else prints.
69
+ const entries = rows
70
+ .filter((row) => row.codes.includes(subject))
71
+ .map(({ scope, severityNote, meaning, fix }) => ({ scope, severityNote, meaning, fix }));
72
+ if (entries.length === 0)
73
+ return null;
74
+ return { kind: "finding", entries, ...(brief === undefined ? {} : { via: brief.via }) };
75
+ }
76
+ /**
77
+ * The finding answer from EITHER source, tables first.
78
+ *
79
+ * One function rather than two call sites choosing an order, because the order
80
+ * is the precedence rule: a code a fix table grades is answered from the bytes
81
+ * the binary ships, and ./families.ts only ever answers codes no table reaches.
82
+ * `via` is a fix-table-only fact — it comes from a `VALIDATE_CHECKS` entry, and
83
+ * no brief check names a `doctor.*`, `next.*`, `diff.*` or `gate.*` code — so a
84
+ * registry answer carries a single entry and nothing else, which is the same
85
+ * shape a one-table code already returns.
86
+ */
87
+ function findingFor(rows, subject) {
88
+ const table = findingIn(rows, subject);
89
+ if (table !== null)
90
+ return table;
91
+ const family = familyFinding(subject);
92
+ return family === null ? null : { kind: "finding", entries: [family] };
93
+ }
94
+ export function explainSubject(subject) {
95
+ const finding = findingFor(allRows(), subject);
96
+ if (finding !== null)
97
+ return finding;
98
+ // Through Object.entries rather than an indexed read: the record's keys are
99
+ // `ErrorCode`, `subject` is an arbitrary string, and the Map lookup needs
100
+ // neither a key cast nor a hasOwn pre-check.
101
+ const refusal = new Map(Object.entries(REFUSAL_MEANINGS)).get(subject);
102
+ if (refusal !== undefined)
103
+ return { kind: "refusal", meaning: refusal };
104
+ const term = termFor(subject);
105
+ if (term !== undefined)
106
+ return { kind: "term", term: term.term, paragraph: term.paragraph };
107
+ return null;
108
+ }
109
+ /**
110
+ * Every subject `explainSubject` can answer — for the unknown-subject
111
+ * refusal's close-match suggestions. Sorted, so suggestion ties break the
112
+ * same way on every machine.
113
+ */
114
+ export function knownSubjects() {
115
+ const known = new Set();
116
+ for (const row of allRows())
117
+ for (const rowCode of row.codes)
118
+ known.add(rowCode);
119
+ for (const familyCode of familyCodes())
120
+ known.add(familyCode);
121
+ for (const check of VALIDATE_CHECKS)
122
+ known.add(check.code);
123
+ for (const key of Object.keys(REFUSAL_MEANINGS))
124
+ known.add(key);
125
+ for (const entry of TERMS) {
126
+ known.add(entry.term);
127
+ for (const alias of entry.aliases)
128
+ known.add(alias);
129
+ }
130
+ return [...known].sort();
131
+ }
132
+ /**
133
+ * A paragraph's first sentence — the one-line summary form both listings
134
+ * print. One definition rather than two: the term listing and the code
135
+ * listing must cut prose the same way, or the same sentence reads as two
136
+ * different summaries depending on which command printed it.
137
+ */
138
+ export function firstSentence(text) {
139
+ const cut = text.indexOf(". ");
140
+ return cut === -1 ? text : text.slice(0, cut + 1);
141
+ }
142
+ /** The no-argument listing: each term with its paragraph's first sentence as the one-line summary. */
143
+ export function listTerms() {
144
+ return TERMS.map(({ term, paragraph }) => ({ term, summary: firstSentence(paragraph) }));
145
+ }
146
+ /**
147
+ * The same listing under the headings the text view prints — the subject
148
+ * groups of ./terms/, in order. A second function rather than a `heading` key
149
+ * on `listTerms`' rows: those rows are the `--json` listing's `terms[]`, whose
150
+ * shape is contract, and a group is typography for a reader scanning twenty
151
+ * terms, not a fact a caller branches on.
152
+ */
153
+ export function listTermGroups() {
154
+ return TERM_GROUPS.map(({ heading, terms }) => ({
155
+ heading,
156
+ terms: terms.map(({ term, paragraph }) => ({ term, summary: firstSentence(paragraph) })),
157
+ }));
158
+ }
159
+ /**
160
+ * Every code `explainSubject` can answer — the machine-readable inventory of
161
+ * the vocabulary, which is otherwise discoverable only by parsing the 83 KB
162
+ * prose body of `loam instructions loam-check` or by reading TypeScript
163
+ * unions that are erased at runtime.
164
+ *
165
+ * Sorted within each kind rather than left in document order: the fix tables
166
+ * are ordered by scope for somebody working through one table, but an
167
+ * inventory is read by name and diffed between binaries, and document order
168
+ * would reshuffle on an unrelated table edit.
169
+ */
170
+ export function listCodes() {
171
+ const rows = allRows();
172
+ // One sorted finding group over BOTH sources rather than a third listing
173
+ // heading. A caller building a code-to-fix cache asks "what does this binary
174
+ // explain", and a `doctor.*` row that arrived from ./families.ts rather than
175
+ // from a parsed table is the same answer to that question — the row it gets
176
+ // is `explain <code> --json`'s payload either way. Splitting them would put
177
+ // the provenance of the prose into the machine contract, where nothing
178
+ // branches on it.
179
+ const findings = [...new Set([...rows.flatMap((row) => row.codes), ...familyCodes()])]
180
+ .sort()
181
+ // Non-null: the code came out of `rows` or out of the registry, and
182
+ // `findingFor` reads exactly those two.
183
+ .map((code) => ({ code, ...findingFor(rows, code) }));
184
+ // Through a Map for the same reason `explainSubject` reads one: the record's
185
+ // keys are `ErrorCode` and this listing's are plain strings. Plain `.sort()`
186
+ // throughout, never `localeCompare` — the order is part of the machine
187
+ // contract and must not depend on the host's ICU locale.
188
+ const meanings = new Map(Object.entries(REFUSAL_MEANINGS));
189
+ const refusals = [...meanings.keys()]
190
+ .sort()
191
+ .map((code) => ({ code, kind: "refusal", meaning: meanings.get(code) }));
192
+ return [...findings, ...refusals];
193
+ }
194
+ //# sourceMappingURL=lookup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../../src/core/explain/lookup.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The explain lookup: one subject in — a finding code, an envelope refusal\n * code, or a concept term — one discriminated explanation out. It also answers\n * the two listings the command prints with no subject: `listTerms` for the\n * concept vocabulary and `listCodes` for the code vocabulary, the latter built\n * from the same `findingIn` the per-code answer uses so the inventory cannot\n * describe a code differently from the page about it.\n *\n * Assembled ON DEMAND, never cached at module level: tests run in forked\n * processes that chdir per invocation, and a long-running host (the MCP\n * server) outlives many calls — a table built at import time is exactly the\n * module-level mutable state AGENTS.md names as a hazard. The build is a walk\n * over constants already in memory, so there is nothing worth caching anyway.\n *\n * Resolution order — finding tables first, then the family registry, then\n * refusal codes, then terms — IS the tie-break: a subject in two families\n * would silently take the earlier family's answer (a refusal named like a term\n * alias would win over the term). No naming convention keeps them apart —\n * `based-on` is a dashed term alias, exactly the shape a refusal code takes —\n * so test/explain.test.ts asserts the key sets are pairwise disjoint, and the\n * order never actually decides anything.\n *\n * The one place that order is load-bearing anyway is the fix tables against\n * ./families.ts: the tables are PARSED from the bytes the binary ships and the\n * registry is written by hand, so where both could answer, the parsed prose has\n * to win and the hand-written row must never silently shadow it. It is written\n * first here and asserted disjoint there, which makes the precedence a fact\n * about the code as well as a fact about the data.\n */\nimport { COMMANDS } from \"../agent/protocol.js\";\nimport { VALIDATE_CHECKS, type BriefCheck } from \"../brief/checks.js\";\nimport { familyCodes, familyFinding } from \"./families.js\";\nimport { parseFixRows, type FixRow } from \"./fix-tables.js\";\nimport { REFUSAL_MEANINGS } from \"./refusals.js\";\nimport { TERM_GROUPS, TERMS } from \"./terms.js\";\nimport type { TermEntry } from \"./terms/entry.js\";\n\nexport interface FindingEntry {\n /** Which table graded it — `--service <id>`, `--feature <FEAT-id>`, `--all`, `loam archive`, … */\n readonly scope: string;\n /** The table's verbatim parenthetical, or \"error\" — its default. */\n readonly severityNote: string;\n readonly meaning: string;\n readonly fix: string;\n}\n\nexport type Explanation =\n | { readonly kind: \"finding\"; readonly entries: readonly FindingEntry[]; readonly via?: string }\n | { readonly kind: \"refusal\"; readonly meaning: string }\n | { readonly kind: \"term\"; readonly term: string; readonly paragraph: string };\n\n/** Every fix-table row shipped in the workflow bodies, in protocol order. */\nfunction allRows(): FixRow[] {\n return COMMANDS.flatMap((command) => parseFixRows(command.body));\n}\n\nfunction briefFor(subject: string): BriefCheck | undefined {\n return VALIDATE_CHECKS.find((check) => check.code === subject);\n}\n\n/** Terms match case-insensitively, by name or alias — codes stay exact, they are already lowercase by grammar. */\nfunction termFor(subject: string): TermEntry | undefined {\n const wanted = subject.toLowerCase();\n return TERMS.find((entry) => entry.term === wanted || entry.aliases.includes(wanted));\n}\n\n/**\n * The finding answer for one subject out of rows ALREADY parsed, or null when\n * no table grades it.\n *\n * Split out of `explainSubject` so `listCodes` builds its rows through the\n * very same function rather than a parallel one: the inventory's per-code\n * payload is then the per-code answer by construction, not by two pieces of\n * code agreeing. It also keeps the inventory's cost linear — `explainSubject`\n * re-parses every workflow body on each call, and calling it 270 times to\n * enumerate the vocabulary would re-walk the whole corpus 270 times.\n */\nfunction findingIn(rows: readonly FixRow[], subject: string): Extract<Explanation, { kind: \"finding\" }> | null {\n const brief = briefFor(subject);\n // VALIDATE_CHECKS contributes `via` ONLY, never a fallback entry. An\n // earlier draft synthesized a row from the brief when the tables had none,\n // and that fallback was both unreachable (every brief check has a table\n // row, pinned by test/explain.test.ts) and wrong if ever reached: its\n // scope would have been the brief's invocation string, a spelling no\n // parsed row uses. A brief check that LOSES its table row should fail\n // loudly there — explain refusing is the tripwire — not render a\n // one-of-a-kind page nobody else prints.\n const entries: FindingEntry[] = rows\n .filter((row) => row.codes.includes(subject))\n .map(({ scope, severityNote, meaning, fix }) => ({ scope, severityNote, meaning, fix }));\n if (entries.length === 0) return null;\n return { kind: \"finding\", entries, ...(brief === undefined ? {} : { via: brief.via }) };\n}\n\n/**\n * The finding answer from EITHER source, tables first.\n *\n * One function rather than two call sites choosing an order, because the order\n * is the precedence rule: a code a fix table grades is answered from the bytes\n * the binary ships, and ./families.ts only ever answers codes no table reaches.\n * `via` is a fix-table-only fact — it comes from a `VALIDATE_CHECKS` entry, and\n * no brief check names a `doctor.*`, `next.*`, `diff.*` or `gate.*` code — so a\n * registry answer carries a single entry and nothing else, which is the same\n * shape a one-table code already returns.\n */\nfunction findingFor(rows: readonly FixRow[], subject: string): Extract<Explanation, { kind: \"finding\" }> | null {\n const table = findingIn(rows, subject);\n if (table !== null) return table;\n const family = familyFinding(subject);\n return family === null ? null : { kind: \"finding\", entries: [family] };\n}\n\nexport function explainSubject(subject: string): Explanation | null {\n const finding = findingFor(allRows(), subject);\n if (finding !== null) return finding;\n // Through Object.entries rather than an indexed read: the record's keys are\n // `ErrorCode`, `subject` is an arbitrary string, and the Map lookup needs\n // neither a key cast nor a hasOwn pre-check.\n const refusal = new Map<string, string>(Object.entries(REFUSAL_MEANINGS)).get(subject);\n if (refusal !== undefined) return { kind: \"refusal\", meaning: refusal };\n const term = termFor(subject);\n if (term !== undefined) return { kind: \"term\", term: term.term, paragraph: term.paragraph };\n return null;\n}\n\n/**\n * Every subject `explainSubject` can answer — for the unknown-subject\n * refusal's close-match suggestions. Sorted, so suggestion ties break the\n * same way on every machine.\n */\nexport function knownSubjects(): string[] {\n const known = new Set<string>();\n for (const row of allRows()) for (const rowCode of row.codes) known.add(rowCode);\n for (const familyCode of familyCodes()) known.add(familyCode);\n for (const check of VALIDATE_CHECKS) known.add(check.code);\n for (const key of Object.keys(REFUSAL_MEANINGS)) known.add(key);\n for (const entry of TERMS) {\n known.add(entry.term);\n for (const alias of entry.aliases) known.add(alias);\n }\n return [...known].sort();\n}\n\n/**\n * A paragraph's first sentence — the one-line summary form both listings\n * print. One definition rather than two: the term listing and the code\n * listing must cut prose the same way, or the same sentence reads as two\n * different summaries depending on which command printed it.\n */\nexport function firstSentence(text: string): string {\n const cut = text.indexOf(\". \");\n return cut === -1 ? text : text.slice(0, cut + 1);\n}\n\n/** The no-argument listing: each term with its paragraph's first sentence as the one-line summary. */\nexport function listTerms(): Array<{ term: string; summary: string }> {\n return TERMS.map(({ term, paragraph }) => ({ term, summary: firstSentence(paragraph) }));\n}\n\n/**\n * The same listing under the headings the text view prints — the subject\n * groups of ./terms/, in order. A second function rather than a `heading` key\n * on `listTerms`' rows: those rows are the `--json` listing's `terms[]`, whose\n * shape is contract, and a group is typography for a reader scanning twenty\n * terms, not a fact a caller branches on.\n */\nexport function listTermGroups(): Array<{ heading: string; terms: Array<{ term: string; summary: string }> }> {\n return TERM_GROUPS.map(({ heading, terms }) => ({\n heading,\n terms: terms.map(({ term, paragraph }) => ({ term, summary: firstSentence(paragraph) })),\n }));\n}\n\n/**\n * One row of the code inventory: the per-code answer with its code attached.\n *\n * DERIVED from `Explanation` rather than restated, so `loam explain <code>\n * --json` and `loam explain --codes --json` cannot describe the same code with\n * two different key sets — a caching consumer reads one and looks up the other.\n * The `term` arm is excluded on purpose: a concept term is a different kind of\n * subject, and the bare `loam explain` listing keeps them.\n *\n * There is deliberately NO `severity` or `gates` key here, and adding one\n * would be a defect rather than an improvement. A fix table carries only the\n * verbatim parenthetical its author wrote (`warn, gates archive; one per\n * service`), which is prose about a scope, while the answer a caller would\n * actually branch on is computed per ISSUE at runtime by `gatesArchive()` and\n * `approveOverrides()` in core/vocabulary/issue.ts — from `severity`, an\n * optional per-issue `gates`, and a never-overridable code set. A severity\n * derived from the parenthetical here would be a second answer to a question\n * that already has one, free to disagree with the binary's own gate.\n */\nexport type CodeListing = { readonly code: string } & Exclude<Explanation, { kind: \"term\" }>;\n\n/**\n * Every code `explainSubject` can answer — the machine-readable inventory of\n * the vocabulary, which is otherwise discoverable only by parsing the 83 KB\n * prose body of `loam instructions loam-check` or by reading TypeScript\n * unions that are erased at runtime.\n *\n * Sorted within each kind rather than left in document order: the fix tables\n * are ordered by scope for somebody working through one table, but an\n * inventory is read by name and diffed between binaries, and document order\n * would reshuffle on an unrelated table edit.\n */\nexport function listCodes(): CodeListing[] {\n const rows = allRows();\n // One sorted finding group over BOTH sources rather than a third listing\n // heading. A caller building a code-to-fix cache asks \"what does this binary\n // explain\", and a `doctor.*` row that arrived from ./families.ts rather than\n // from a parsed table is the same answer to that question — the row it gets\n // is `explain <code> --json`'s payload either way. Splitting them would put\n // the provenance of the prose into the machine contract, where nothing\n // branches on it.\n const findings: CodeListing[] = [...new Set([...rows.flatMap((row) => row.codes), ...familyCodes()])]\n .sort()\n // Non-null: the code came out of `rows` or out of the registry, and\n // `findingFor` reads exactly those two.\n .map((code) => ({ code, ...findingFor(rows, code)! }));\n // Through a Map for the same reason `explainSubject` reads one: the record's\n // keys are `ErrorCode` and this listing's are plain strings. Plain `.sort()`\n // throughout, never `localeCompare` — the order is part of the machine\n // contract and must not depend on the host's ICU locale.\n const meanings = new Map<string, string>(Object.entries(REFUSAL_MEANINGS));\n const refusals: CodeListing[] = [...meanings.keys()]\n .sort()\n .map((code) => ({ code, kind: \"refusal\" as const, meaning: meanings.get(code)! }));\n return [...findings, ...refusals];\n}\n"]}