@ybotok/loam 0.1.0-beta.2 → 0.2.0-alpha.1

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 (1026) hide show
  1. package/CHANGELOG.md +2570 -61
  2. package/COMPARISON.md +80 -63
  3. package/CONTRIBUTING.md +84 -0
  4. package/MIGRATING-from-OpenSpec.md +213 -54
  5. package/QUICKSTART.md +125 -0
  6. package/README.md +450 -150
  7. package/ROADMAP.md +494 -0
  8. package/SCHEMA.md +2362 -245
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +701 -0
  11. package/dist/cli.js +113 -19
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +209 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +268 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +77 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/plan/contracts/asyncapi.js +178 -0
  20. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/openapi.js +159 -0
  22. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  23. package/dist/commands/archive/plan/gate.js +317 -0
  24. package/dist/commands/archive/plan/gate.js.map +1 -0
  25. package/dist/commands/archive/plan/landscape.js +161 -0
  26. package/dist/commands/archive/plan/landscape.js.map +1 -0
  27. package/dist/commands/archive/plan/refusal.js +111 -0
  28. package/dist/commands/archive/plan/refusal.js.map +1 -0
  29. package/dist/commands/archive/plan/specs.js +237 -0
  30. package/dist/commands/archive/plan/specs.js.map +1 -0
  31. package/dist/commands/archive/plan/state.js +27 -0
  32. package/dist/commands/archive/plan/state.js.map +1 -0
  33. package/dist/commands/archive/run.js +251 -0
  34. package/dist/commands/archive/run.js.map +1 -0
  35. package/dist/commands/context/context.js +99 -0
  36. package/dist/commands/context/context.js.map +1 -0
  37. package/dist/commands/context/print.js +283 -0
  38. package/dist/commands/context/print.js.map +1 -0
  39. package/dist/commands/delta/delta.js +279 -0
  40. package/dist/commands/delta/delta.js.map +1 -0
  41. package/dist/commands/delta/print.js +205 -0
  42. package/dist/commands/delta/print.js.map +1 -0
  43. package/dist/commands/dependencies.js +9 -7
  44. package/dist/commands/dependencies.js.map +1 -1
  45. package/dist/commands/diff/diff.js +93 -0
  46. package/dist/commands/diff/diff.js.map +1 -0
  47. package/dist/commands/diff/print.js +38 -0
  48. package/dist/commands/diff/print.js.map +1 -0
  49. package/dist/commands/doctor.js +5 -4
  50. package/dist/commands/doctor.js.map +1 -1
  51. package/dist/commands/explain/explain.js +151 -0
  52. package/dist/commands/explain/explain.js.map +1 -0
  53. package/dist/commands/explore.js +29 -24
  54. package/dist/commands/explore.js.map +1 -1
  55. package/dist/commands/gate/gate.js +115 -0
  56. package/dist/commands/gate/gate.js.map +1 -0
  57. package/dist/commands/gate/print.js +54 -0
  58. package/dist/commands/gate/print.js.map +1 -0
  59. package/dist/commands/gherkin/commit.js +146 -0
  60. package/dist/commands/gherkin/commit.js.map +1 -0
  61. package/dist/commands/gherkin/gherkin.js +246 -0
  62. package/dist/commands/gherkin/gherkin.js.map +1 -0
  63. package/dist/commands/gherkin/reconcile.js +149 -0
  64. package/dist/commands/gherkin/reconcile.js.map +1 -0
  65. package/dist/commands/gherkin/render.js +77 -0
  66. package/dist/commands/gherkin/render.js.map +1 -0
  67. package/dist/commands/init/example.js +204 -0
  68. package/dist/commands/init/example.js.map +1 -0
  69. package/dist/commands/init/first-hour.js +28 -0
  70. package/dist/commands/init/first-hour.js.map +1 -0
  71. package/dist/commands/{init.js → init/init.js} +146 -71
  72. package/dist/commands/init/init.js.map +1 -0
  73. package/dist/commands/init/mcp.js +131 -0
  74. package/dist/commands/init/mcp.js.map +1 -0
  75. package/dist/commands/init/options.js +78 -0
  76. package/dist/commands/init/options.js.map +1 -0
  77. package/dist/commands/instructions.js +82 -14
  78. package/dist/commands/instructions.js.map +1 -1
  79. package/dist/commands/list/campaign/campaign.js +65 -0
  80. package/dist/commands/list/campaign/campaign.js.map +1 -0
  81. package/dist/commands/list/campaign/owners.js +65 -0
  82. package/dist/commands/list/campaign/owners.js.map +1 -0
  83. package/dist/commands/list/json.js +157 -0
  84. package/dist/commands/list/json.js.map +1 -0
  85. package/dist/commands/list/list.js +343 -0
  86. package/dist/commands/list/list.js.map +1 -0
  87. package/dist/commands/list/print.js +301 -0
  88. package/dist/commands/list/print.js.map +1 -0
  89. package/dist/commands/list/review.js +120 -0
  90. package/dist/commands/list/review.js.map +1 -0
  91. package/dist/commands/list/views.js +105 -0
  92. package/dist/commands/list/views.js.map +1 -0
  93. package/dist/commands/mcp/dispatch.js +183 -0
  94. package/dist/commands/mcp/dispatch.js.map +1 -0
  95. package/dist/commands/mcp/mcp.js +34 -0
  96. package/dist/commands/mcp/mcp.js.map +1 -0
  97. package/dist/commands/mcp/serve.js +55 -0
  98. package/dist/commands/mcp/serve.js.map +1 -0
  99. package/dist/commands/migrate-openspec/materialize/active.js +170 -0
  100. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  101. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  102. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  103. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  104. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  105. package/dist/commands/migrate-openspec/materialize/stage.js +142 -0
  106. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  107. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  108. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  109. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  110. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  111. package/dist/commands/migrate-openspec/openspec/decisions.js +91 -0
  112. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  113. package/dist/commands/migrate-openspec/openspec/error.js +19 -0
  114. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  115. package/dist/commands/migrate-openspec/openspec/mapping.js +170 -0
  116. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  117. package/dist/commands/migrate-openspec/openspec/paths.js +43 -0
  118. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  119. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  120. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  121. package/dist/commands/migrate-openspec/print.js +89 -0
  122. package/dist/commands/migrate-openspec/print.js.map +1 -0
  123. package/dist/commands/new/commit.js +76 -0
  124. package/dist/commands/new/commit.js.map +1 -0
  125. package/dist/commands/new/new.js +283 -0
  126. package/dist/commands/new/new.js.map +1 -0
  127. package/dist/commands/new/templates.js +355 -0
  128. package/dist/commands/new/templates.js.map +1 -0
  129. package/dist/commands/open.js +203 -0
  130. package/dist/commands/open.js.map +1 -0
  131. package/dist/commands/policy/format.js +152 -0
  132. package/dist/commands/policy/format.js.map +1 -0
  133. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +11 -11
  134. package/dist/commands/policy/gate.js.map +1 -0
  135. package/dist/commands/rebase/edit.js +106 -0
  136. package/dist/commands/rebase/edit.js.map +1 -0
  137. package/dist/commands/rebase/living.js +185 -0
  138. package/dist/commands/rebase/living.js.map +1 -0
  139. package/dist/commands/rebase/plan.js +245 -0
  140. package/dist/commands/rebase/plan.js.map +1 -0
  141. package/dist/commands/rebase/rebase.js +275 -0
  142. package/dist/commands/rebase/rebase.js.map +1 -0
  143. package/dist/commands/seed/commit.js +192 -0
  144. package/dist/commands/seed/commit.js.map +1 -0
  145. package/dist/commands/seed/plan.js +133 -0
  146. package/dist/commands/seed/plan.js.map +1 -0
  147. package/dist/commands/seed/seed.js +172 -0
  148. package/dist/commands/seed/seed.js.map +1 -0
  149. package/dist/commands/show/feature.js +178 -0
  150. package/dist/commands/show/feature.js.map +1 -0
  151. package/dist/commands/show/marks.js +24 -0
  152. package/dist/commands/show/marks.js.map +1 -0
  153. package/dist/commands/{show.js → show/service.js} +63 -152
  154. package/dist/commands/show/service.js.map +1 -0
  155. package/dist/commands/show/show.js +77 -0
  156. package/dist/commands/show/show.js.map +1 -0
  157. package/dist/commands/status/json.js +45 -0
  158. package/dist/commands/status/json.js.map +1 -0
  159. package/dist/commands/status/print.js +157 -0
  160. package/dist/commands/status/print.js.map +1 -0
  161. package/dist/commands/status/status.js +119 -0
  162. package/dist/commands/status/status.js.map +1 -0
  163. package/dist/commands/steps/steps.js +189 -0
  164. package/dist/commands/steps/steps.js.map +1 -0
  165. package/dist/commands/subsystem/edit.js +192 -0
  166. package/dist/commands/subsystem/edit.js.map +1 -0
  167. package/dist/commands/subsystem/move.js +265 -0
  168. package/dist/commands/subsystem/move.js.map +1 -0
  169. package/dist/commands/subsystem/query.js +115 -0
  170. package/dist/commands/subsystem/query.js.map +1 -0
  171. package/dist/commands/subsystem/subsystem.js +101 -0
  172. package/dist/commands/subsystem/subsystem.js.map +1 -0
  173. package/dist/commands/subsystem/sync.js +103 -0
  174. package/dist/commands/subsystem/sync.js.map +1 -0
  175. package/dist/commands/subsystem/txn/txn.js +94 -0
  176. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  177. package/dist/commands/subsystem/txn/views.js +70 -0
  178. package/dist/commands/subsystem/txn/views.js.map +1 -0
  179. package/dist/commands/unarchive/manifest.js +160 -0
  180. package/dist/commands/unarchive/manifest.js.map +1 -0
  181. package/dist/commands/{unarchive.js → unarchive/restore.js} +47 -160
  182. package/dist/commands/unarchive/restore.js.map +1 -0
  183. package/dist/commands/unarchive/unarchive.js +67 -0
  184. package/dist/commands/unarchive/unarchive.js.map +1 -0
  185. package/dist/commands/validate/arch-coverage.js +194 -0
  186. package/dist/commands/validate/arch-coverage.js.map +1 -0
  187. package/dist/commands/validate/checks/fleet-shape.js +296 -0
  188. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  189. package/dist/commands/validate/checks/health-deps.js +55 -0
  190. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  191. package/dist/commands/validate/checks/requirements.js +254 -0
  192. package/dist/commands/validate/checks/requirements.js.map +1 -0
  193. package/dist/commands/validate/checks/sources.js +76 -0
  194. package/dist/commands/validate/checks/sources.js.map +1 -0
  195. package/dist/commands/validate/checks/vocabulary.js +31 -0
  196. package/dist/commands/validate/checks/vocabulary.js.map +1 -0
  197. package/dist/commands/validate/feature.js +216 -0
  198. package/dist/commands/validate/feature.js.map +1 -0
  199. package/dist/commands/validate/fleet/census.js +69 -0
  200. package/dist/commands/validate/fleet/census.js.map +1 -0
  201. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  202. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  203. package/dist/commands/validate/fleet/landscape.js +353 -0
  204. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  205. package/dist/commands/validate/fleet/load.js +52 -0
  206. package/dist/commands/validate/fleet/load.js.map +1 -0
  207. package/dist/commands/validate/fleet/obligations.js +236 -0
  208. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  209. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  210. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  211. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  212. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  213. package/dist/commands/validate/fleet/scorecard/print.js +63 -0
  214. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  215. package/dist/commands/validate/fleet/scorecard/scorecard.js +156 -0
  216. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  217. package/dist/commands/validate/fleet/usecases/capability-tag.js +94 -0
  218. package/dist/commands/validate/fleet/usecases/capability-tag.js.map +1 -0
  219. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  220. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  221. package/dist/commands/validate/fleet/usecases/requirement-tag.js +95 -0
  222. package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +1 -0
  223. package/dist/commands/validate/fleet/usecases/steps.js +197 -0
  224. package/dist/commands/validate/fleet/usecases/steps.js.map +1 -0
  225. package/dist/commands/validate/fleet/usecases/usecases.js +99 -0
  226. package/dist/commands/validate/fleet/usecases/usecases.js.map +1 -0
  227. package/dist/commands/validate/fleet/views/ids.js +40 -0
  228. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  229. package/dist/commands/validate/fleet/views/stale.js +59 -0
  230. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  231. package/dist/commands/validate/links/corpus.js +92 -0
  232. package/dist/commands/validate/links/corpus.js.map +1 -0
  233. package/dist/commands/validate/links/glossary.js +75 -0
  234. package/dist/commands/validate/links/glossary.js.map +1 -0
  235. package/dist/commands/validate/report.js +269 -0
  236. package/dist/commands/validate/report.js.map +1 -0
  237. package/dist/commands/validate/service/api.js +338 -0
  238. package/dist/commands/validate/service/api.js.map +1 -0
  239. package/dist/commands/validate/service/events/events.js +219 -0
  240. package/dist/commands/validate/service/events/events.js.map +1 -0
  241. package/dist/commands/validate/service/events/message-producers.js +77 -0
  242. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  243. package/dist/commands/validate/service/evidence-pins.js +131 -0
  244. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  245. package/dist/commands/validate/service/service.js +250 -0
  246. package/dist/commands/validate/service/service.js.map +1 -0
  247. package/dist/commands/validate/service/specs.js +219 -0
  248. package/dist/commands/validate/service/specs.js.map +1 -0
  249. package/dist/commands/validate/service/spine.js +113 -0
  250. package/dist/commands/validate/service/spine.js.map +1 -0
  251. package/dist/commands/validate/validate.js +338 -0
  252. package/dist/commands/validate/validate.js.map +1 -0
  253. package/dist/commands/verify/cross/diff.js +182 -0
  254. package/dist/commands/verify/cross/diff.js.map +1 -0
  255. package/dist/commands/verify/evidence/contract.js +32 -0
  256. package/dist/commands/verify/evidence/contract.js.map +1 -0
  257. package/dist/commands/verify/evidence/pins.js +52 -0
  258. package/dist/commands/verify/evidence/pins.js.map +1 -0
  259. package/dist/commands/verify/evidence/read.js +72 -0
  260. package/dist/commands/verify/evidence/read.js.map +1 -0
  261. package/dist/commands/verify/frozen.js +241 -0
  262. package/dist/commands/verify/frozen.js.map +1 -0
  263. package/dist/commands/verify/record.js +226 -0
  264. package/dist/commands/verify/record.js.map +1 -0
  265. package/dist/commands/verify/report.js +223 -0
  266. package/dist/commands/verify/report.js.map +1 -0
  267. package/dist/commands/verify/results.js +246 -0
  268. package/dist/commands/verify/results.js.map +1 -0
  269. package/dist/commands/verify/verify.js +217 -0
  270. package/dist/commands/verify/verify.js.map +1 -0
  271. package/dist/commands/vouch/contract.js +11 -0
  272. package/dist/commands/vouch/contract.js.map +1 -0
  273. package/dist/commands/vouch/pack/contract.js +2 -0
  274. package/dist/commands/vouch/pack/contract.js.map +1 -0
  275. package/dist/commands/vouch/pack/pack.js +266 -0
  276. package/dist/commands/vouch/pack/pack.js.map +1 -0
  277. package/dist/commands/vouch/pack/print.js +271 -0
  278. package/dist/commands/vouch/pack/print.js.map +1 -0
  279. package/dist/commands/vouch/pack/sections.js +142 -0
  280. package/dist/commands/vouch/pack/sections.js.map +1 -0
  281. package/dist/commands/vouch/prompt/confirm.js +46 -0
  282. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  283. package/dist/commands/vouch/report.js +101 -0
  284. package/dist/commands/vouch/report.js.map +1 -0
  285. package/dist/commands/vouch/run.js +285 -0
  286. package/dist/commands/vouch/run.js.map +1 -0
  287. package/dist/commands/vouch/sample/plan.js +125 -0
  288. package/dist/commands/vouch/sample/plan.js.map +1 -0
  289. package/dist/commands/vouch/sample/print.js +109 -0
  290. package/dist/commands/vouch/sample/print.js.map +1 -0
  291. package/dist/commands/vouch/vet/verify.js +123 -0
  292. package/dist/commands/vouch/vet/verify.js.map +1 -0
  293. package/dist/commands/vouch/vouch.js +176 -0
  294. package/dist/commands/vouch/vouch.js.map +1 -0
  295. package/dist/core/agent/agents-md/artifacts.js +220 -0
  296. package/dist/core/agent/agents-md/artifacts.js.map +1 -0
  297. package/dist/core/agent/agents-md/command-map.js +324 -0
  298. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  299. package/dist/core/agent/agents-md/cycle.js +165 -0
  300. package/dist/core/agent/agents-md/cycle.js.map +1 -0
  301. package/dist/core/agent/agents-md/map/explain.js +34 -0
  302. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  303. package/dist/core/agent/agents-md/map/lenses/context.js +41 -0
  304. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  305. package/dist/core/agent/agents-md/map/lenses/diff.js +46 -0
  306. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  307. package/dist/core/agent/agents-md/map/lenses/gate.js +57 -0
  308. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  309. package/dist/core/agent/agents-md/map/mcp.js +41 -0
  310. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  311. package/dist/core/agent/agents-md/map/status.js +62 -0
  312. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  313. package/dist/core/agent/agents-md/map/subsystem.js +32 -0
  314. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  315. package/dist/core/agent/agents-md/map/usecases.js +60 -0
  316. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  317. package/dist/core/agent/agents-md/refusals.js +246 -0
  318. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  319. package/dist/core/agent/agents-md/shipped/archive-gate.js +98 -0
  320. package/dist/core/agent/agents-md/shipped/archive-gate.js.map +1 -0
  321. package/dist/core/agent/agents-md/spine.js +40 -0
  322. package/dist/core/agent/agents-md/spine.js.map +1 -0
  323. package/dist/core/agent/agents-md.js +170 -0
  324. package/dist/core/agent/agents-md.js.map +1 -0
  325. package/dist/core/agent/agents-stamp.js +155 -0
  326. package/dist/core/agent/agents-stamp.js.map +1 -0
  327. package/dist/core/agent/contract.js +2 -0
  328. package/dist/core/agent/contract.js.map +1 -0
  329. package/dist/core/agent/protocol.js +193 -0
  330. package/dist/core/agent/protocol.js.map +1 -0
  331. package/dist/core/agent/scaffold.js +259 -0
  332. package/dist/core/agent/scaffold.js.map +1 -0
  333. package/dist/core/agent/support/report.js +103 -0
  334. package/dist/core/agent/support/report.js.map +1 -0
  335. package/dist/core/agent/tools/dialects.js +150 -0
  336. package/dist/core/agent/tools/dialects.js.map +1 -0
  337. package/dist/core/agent/tools/registry.js +228 -0
  338. package/dist/core/agent/tools/registry.js.map +1 -0
  339. package/dist/core/agent/workflows/adopt.js +133 -0
  340. package/dist/core/agent/workflows/adopt.js.map +1 -0
  341. package/dist/core/agent/workflows/check.js +334 -0
  342. package/dist/core/agent/workflows/check.js.map +1 -0
  343. package/dist/core/agent/workflows/closing.js +262 -0
  344. package/dist/core/agent/workflows/closing.js.map +1 -0
  345. package/dist/core/agent/workflows/feature.js +105 -0
  346. package/dist/core/agent/workflows/feature.js.map +1 -0
  347. package/dist/core/agent/workflows/implement.js +105 -0
  348. package/dist/core/agent/workflows/implement.js.map +1 -0
  349. package/dist/core/agent/workflows/reference/authoring.js +209 -0
  350. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  351. package/dist/core/agent/workflows/reference/codes.js +65 -0
  352. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  353. package/dist/core/agent/workflows/reference/done-check.js +188 -0
  354. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  355. package/dist/core/agent/workflows/reference/reference.js +16 -0
  356. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  357. package/dist/core/agent/workflows/reference/spine.js +297 -0
  358. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  359. package/dist/core/asyncapi/baseline/plan.js +110 -0
  360. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  361. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  362. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  363. package/dist/core/asyncapi/depth.js +164 -0
  364. package/dist/core/asyncapi/depth.js.map +1 -0
  365. package/dist/core/asyncapi/digest.js +141 -0
  366. package/dist/core/asyncapi/digest.js.map +1 -0
  367. package/dist/core/asyncapi/merge/components.js +91 -0
  368. package/dist/core/asyncapi/merge/components.js.map +1 -0
  369. package/dist/core/asyncapi/merge/error.js +33 -0
  370. package/dist/core/asyncapi/merge/error.js.map +1 -0
  371. package/dist/core/asyncapi/merge/markers.js +308 -0
  372. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  373. package/dist/core/asyncapi/merge/merge.js +215 -0
  374. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  375. package/dist/core/asyncapi/merge/pin.js +107 -0
  376. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  377. package/dist/core/asyncapi/model.js +11 -0
  378. package/dist/core/asyncapi/model.js.map +1 -0
  379. package/dist/core/asyncapi/producers.js +50 -0
  380. package/dist/core/asyncapi/producers.js.map +1 -0
  381. package/dist/core/asyncapi/read.js +239 -0
  382. package/dist/core/asyncapi/read.js.map +1 -0
  383. package/dist/core/brief/brief.js +225 -0
  384. package/dist/core/brief/brief.js.map +1 -0
  385. package/dist/core/brief/checks.js +250 -0
  386. package/dist/core/brief/checks.js.map +1 -0
  387. package/dist/core/brief/landscape.js +194 -0
  388. package/dist/core/brief/landscape.js.map +1 -0
  389. package/dist/core/brief/targets.js +226 -0
  390. package/dist/core/brief/targets.js.map +1 -0
  391. package/dist/core/brief/unchecked.js +47 -0
  392. package/dist/core/brief/unchecked.js.map +1 -0
  393. package/dist/core/c4/arch.js +282 -0
  394. package/dist/core/c4/arch.js.map +1 -0
  395. package/dist/core/c4/likec4.js +88 -0
  396. package/dist/core/c4/likec4.js.map +1 -0
  397. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  398. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  399. package/dist/core/c4/parsed/specification.js +78 -0
  400. package/dist/core/c4/parsed/specification.js.map +1 -0
  401. package/dist/core/c4/parsed/values.js +57 -0
  402. package/dist/core/c4/parsed/values.js.map +1 -0
  403. package/dist/core/c4/parsed/view-ids.js +75 -0
  404. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  405. package/dist/core/c4/project/architecture.js +45 -0
  406. package/dist/core/c4/project/architecture.js.map +1 -0
  407. package/dist/core/c4/project/documents.js +58 -0
  408. package/dist/core/c4/project/documents.js.map +1 -0
  409. package/dist/core/c4/project/load.js +183 -0
  410. package/dist/core/c4/project/load.js.map +1 -0
  411. package/dist/core/c4/resolve/service.js +113 -0
  412. package/dist/core/c4/resolve/service.js.map +1 -0
  413. package/dist/core/c4/seed/fleet-file.js +201 -0
  414. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  415. package/dist/core/c4/seed/items.js +91 -0
  416. package/dist/core/c4/seed/items.js.map +1 -0
  417. package/dist/core/c4/seed/stamp.js +48 -0
  418. package/dist/core/c4/seed/stamp.js.map +1 -0
  419. package/dist/core/c4/seed/template.js +109 -0
  420. package/dist/core/c4/seed/template.js.map +1 -0
  421. package/dist/core/c4/source-mask.js +82 -0
  422. package/dist/core/c4/source-mask.js.map +1 -0
  423. package/dist/core/c4/source-scan.js +227 -0
  424. package/dist/core/c4/source-scan.js.map +1 -0
  425. package/dist/core/c4/splice/authored-source.js +101 -0
  426. package/dist/core/c4/splice/authored-source.js.map +1 -0
  427. package/dist/core/c4/splice/contract.js +10 -0
  428. package/dist/core/c4/splice/contract.js.map +1 -0
  429. package/dist/core/c4/splice/delta-blocks.js +126 -0
  430. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  431. package/dist/core/c4/splice/identity/edges.js +36 -0
  432. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  433. package/dist/core/c4/splice/landscape-merge.js +269 -0
  434. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  435. package/dist/core/c4/splice/placement.js +194 -0
  436. package/dist/core/c4/splice/placement.js.map +1 -0
  437. package/dist/core/c4/workspace.js +172 -0
  438. package/dist/core/c4/workspace.js.map +1 -0
  439. package/dist/core/capabilities/authoring/notes.js +141 -0
  440. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  441. package/dist/core/capabilities/capabilities.js +124 -0
  442. package/dist/core/capabilities/capabilities.js.map +1 -0
  443. package/dist/core/capabilities/delta/doc.js +50 -0
  444. package/dist/core/capabilities/delta/doc.js.map +1 -0
  445. package/dist/core/capabilities/delta/overlay.js +129 -0
  446. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  447. package/dist/core/capabilities/delta/summary.js +57 -0
  448. package/dist/core/capabilities/delta/summary.js.map +1 -0
  449. package/dist/core/capabilities/delta/tree.js +43 -0
  450. package/dist/core/capabilities/delta/tree.js.map +1 -0
  451. package/dist/core/capabilities/delta/uncovered.js +222 -0
  452. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  453. package/dist/core/capabilities/findings.js +342 -0
  454. package/dist/core/capabilities/findings.js.map +1 -0
  455. package/dist/core/capabilities/realizes/findings.js +181 -0
  456. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  457. package/dist/core/capabilities/realizes/join.js +143 -0
  458. package/dist/core/capabilities/realizes/join.js.map +1 -0
  459. package/dist/core/capabilities/rollup.js +199 -0
  460. package/dist/core/capabilities/rollup.js.map +1 -0
  461. package/dist/core/capabilities/tree.js +126 -0
  462. package/dist/core/capabilities/tree.js.map +1 -0
  463. package/dist/core/capabilities/usecase-join.js +277 -0
  464. package/dist/core/capabilities/usecase-join.js.map +1 -0
  465. package/dist/core/coherence/authoring/scaffold.js +177 -0
  466. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  467. package/dist/core/coherence/authoring/sentinels.js +74 -0
  468. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  469. package/dist/core/coherence/coherence.js +251 -0
  470. package/dist/core/coherence/coherence.js.map +1 -0
  471. package/dist/core/coherence/declared.js +269 -0
  472. package/dist/core/coherence/declared.js.map +1 -0
  473. package/dist/core/coherence/events/declared.js +206 -0
  474. package/dist/core/coherence/events/declared.js.map +1 -0
  475. package/dist/core/coherence/events/events.js +204 -0
  476. package/dist/core/coherence/events/events.js.map +1 -0
  477. package/dist/core/coherence/events/grades.js +166 -0
  478. package/dist/core/coherence/events/grades.js.map +1 -0
  479. package/dist/core/coherence/events/lookups.js +122 -0
  480. package/dist/core/coherence/events/lookups.js.map +1 -0
  481. package/dist/core/coherence/events/merged.js +40 -0
  482. package/dist/core/coherence/events/merged.js.map +1 -0
  483. package/dist/core/coherence/living.js +198 -0
  484. package/dist/core/coherence/living.js.map +1 -0
  485. package/dist/core/coherence/lookups.js +155 -0
  486. package/dist/core/coherence/lookups.js.map +1 -0
  487. package/dist/core/coherence/pending.js +39 -0
  488. package/dist/core/coherence/pending.js.map +1 -0
  489. package/dist/core/conflict-markers.js +60 -0
  490. package/dist/core/conflict-markers.js.map +1 -0
  491. package/dist/core/delta/claims.js +73 -0
  492. package/dist/core/delta/claims.js.map +1 -0
  493. package/dist/core/delta/delta.js +296 -0
  494. package/dist/core/delta/delta.js.map +1 -0
  495. package/dist/core/delta/document.js +177 -0
  496. package/dist/core/delta/document.js.map +1 -0
  497. package/dist/core/delta/scope.js +48 -0
  498. package/dist/core/delta/scope.js.map +1 -0
  499. package/dist/core/delta/select.js +237 -0
  500. package/dist/core/delta/select.js.map +1 -0
  501. package/dist/core/dependencies/dependencies.js +141 -0
  502. package/dist/core/dependencies/dependencies.js.map +1 -0
  503. package/dist/core/dependencies/facts.js +165 -0
  504. package/dist/core/dependencies/facts.js.map +1 -0
  505. package/dist/core/dependencies/fanin.js +88 -0
  506. package/dist/core/dependencies/fanin.js.map +1 -0
  507. package/dist/core/dependencies/graph.js +106 -0
  508. package/dist/core/dependencies/graph.js.map +1 -0
  509. package/dist/core/diff/base-git.js +148 -0
  510. package/dist/core/diff/base-git.js.map +1 -0
  511. package/dist/core/diff/base-state.js +209 -0
  512. package/dist/core/diff/base-state.js.map +1 -0
  513. package/dist/core/diff/current-state.js +96 -0
  514. package/dist/core/diff/current-state.js.map +1 -0
  515. package/dist/core/diff/scope/changed-paths.js +188 -0
  516. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  517. package/dist/core/diff/semantic.js +243 -0
  518. package/dist/core/diff/semantic.js.map +1 -0
  519. package/dist/core/diff/victims.js +247 -0
  520. package/dist/core/diff/victims.js.map +1 -0
  521. package/dist/core/docs.js +59 -55
  522. package/dist/core/docs.js.map +1 -1
  523. package/dist/core/doctor/agents.js +222 -0
  524. package/dist/core/doctor/agents.js.map +1 -0
  525. package/dist/core/doctor/config.js +135 -0
  526. package/dist/core/doctor/config.js.map +1 -0
  527. package/dist/core/doctor/doctor.js +275 -0
  528. package/dist/core/doctor/doctor.js.map +1 -0
  529. package/dist/core/doctor/report.js +13 -0
  530. package/dist/core/doctor/report.js.map +1 -0
  531. package/dist/core/doctor/residue.js +110 -0
  532. package/dist/core/doctor/residue.js.map +1 -0
  533. package/dist/core/document/apply.js +77 -0
  534. package/dist/core/document/apply.js.map +1 -0
  535. package/dist/core/{frontmatter.js → document/frontmatter.js} +48 -2
  536. package/dist/core/document/frontmatter.js.map +1 -0
  537. package/dist/core/document/grammar/directives.js +143 -0
  538. package/dist/core/document/grammar/directives.js.map +1 -0
  539. package/dist/core/document/parse.js +263 -0
  540. package/dist/core/document/parse.js.map +1 -0
  541. package/dist/core/document/scenarios.js +221 -0
  542. package/dist/core/document/scenarios.js.map +1 -0
  543. package/dist/core/document/spec.js +241 -0
  544. package/dist/core/document/spec.js.map +1 -0
  545. package/dist/core/{config.js → envelope/config.js} +79 -18
  546. package/dist/core/envelope/config.js.map +1 -0
  547. package/dist/core/envelope/json.js +175 -0
  548. package/dist/core/envelope/json.js.map +1 -0
  549. package/dist/core/{version.js → envelope/version.js} +3 -3
  550. package/dist/core/envelope/version.js.map +1 -0
  551. package/dist/core/explain/families.js +175 -0
  552. package/dist/core/explain/families.js.map +1 -0
  553. package/dist/core/explain/fix-tables.js +178 -0
  554. package/dist/core/explain/fix-tables.js.map +1 -0
  555. package/dist/core/explain/lookup.js +181 -0
  556. package/dist/core/explain/lookup.js.map +1 -0
  557. package/dist/core/explain/refusals.js +49 -0
  558. package/dist/core/explain/refusals.js.map +1 -0
  559. package/dist/core/explain/terms.js +144 -0
  560. package/dist/core/explain/terms.js.map +1 -0
  561. package/dist/core/explore/describe.js +105 -0
  562. package/dist/core/explore/describe.js.map +1 -0
  563. package/dist/core/{explore.js → explore/explore.js} +50 -101
  564. package/dist/core/explore/explore.js.map +1 -0
  565. package/dist/core/fleet-context.js +132 -77
  566. package/dist/core/fleet-context.js.map +1 -1
  567. package/dist/core/gate/checks.js +201 -0
  568. package/dist/core/gate/checks.js.map +1 -0
  569. package/dist/core/gate/partners.js +205 -0
  570. package/dist/core/gate/partners.js.map +1 -0
  571. package/dist/core/gate/report.js +47 -0
  572. package/dist/core/gate/report.js.map +1 -0
  573. package/dist/core/gate/verification.js +113 -0
  574. package/dist/core/gate/verification.js.map +1 -0
  575. package/dist/core/gherkin/digest.js +60 -0
  576. package/dist/core/gherkin/digest.js.map +1 -0
  577. package/dist/core/gherkin/emit.js +177 -0
  578. package/dist/core/gherkin/emit.js.map +1 -0
  579. package/dist/core/gherkin/read.js +76 -0
  580. package/dist/core/gherkin/read.js.map +1 -0
  581. package/dist/core/gherkin/stale.js +234 -0
  582. package/dist/core/gherkin/stale.js.map +1 -0
  583. package/dist/core/gherkin/stamp.js +77 -0
  584. package/dist/core/gherkin/stamp.js.map +1 -0
  585. package/dist/core/gherkin/steps/catalogue.js +154 -0
  586. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  587. package/dist/core/gherkin/steps/inventory.js +98 -0
  588. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  589. package/dist/core/gherkin/steps/phrase.js +72 -0
  590. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  591. package/dist/core/glossary/delta.js +106 -0
  592. package/dist/core/glossary/delta.js.map +1 -0
  593. package/dist/core/glossary/tree.js +86 -0
  594. package/dist/core/glossary/tree.js.map +1 -0
  595. package/dist/core/kernel/concurrency.js.map +1 -0
  596. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  597. package/dist/core/kernel/document-bytes.js.map +1 -0
  598. package/dist/core/kernel/fences.js +42 -0
  599. package/dist/core/kernel/fences.js.map +1 -0
  600. package/dist/core/kernel/ids/capability.js +72 -0
  601. package/dist/core/kernel/ids/capability.js.map +1 -0
  602. package/dist/core/kernel/ids/dirs.js +33 -0
  603. package/dist/core/kernel/ids/dirs.js.map +1 -0
  604. package/dist/core/kernel/ids/feature.js +75 -0
  605. package/dist/core/kernel/ids/feature.js.map +1 -0
  606. package/dist/core/kernel/ids/service.js +156 -0
  607. package/dist/core/kernel/ids/service.js.map +1 -0
  608. package/dist/core/kernel/ids/subsystem.js +63 -0
  609. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  610. package/dist/core/{path-safety.js → kernel/path-safety.js} +18 -4
  611. package/dist/core/kernel/path-safety.js.map +1 -0
  612. package/dist/core/kernel/records.js.map +1 -0
  613. package/dist/core/links/backlinks.js +68 -0
  614. package/dist/core/links/backlinks.js.map +1 -0
  615. package/dist/core/links/case.js +74 -0
  616. package/dist/core/links/case.js.map +1 -0
  617. package/dist/core/links/corpus.js +104 -0
  618. package/dist/core/links/corpus.js.map +1 -0
  619. package/dist/core/links/findings.js +110 -0
  620. package/dist/core/links/findings.js.map +1 -0
  621. package/dist/core/links/parse.js +236 -0
  622. package/dist/core/links/parse.js.map +1 -0
  623. package/dist/core/mcp/argv.js +111 -0
  624. package/dist/core/mcp/argv.js.map +1 -0
  625. package/dist/core/mcp/author-tools.js +72 -0
  626. package/dist/core/mcp/author-tools.js.map +1 -0
  627. package/dist/core/mcp/framing.js +46 -0
  628. package/dist/core/mcp/framing.js.map +1 -0
  629. package/dist/core/mcp/protocol.js +280 -0
  630. package/dist/core/mcp/protocol.js.map +1 -0
  631. package/dist/core/mcp/tools.js +314 -0
  632. package/dist/core/mcp/tools.js.map +1 -0
  633. package/dist/core/obligations/obligations.js +106 -0
  634. package/dist/core/obligations/obligations.js.map +1 -0
  635. package/dist/core/openapi/baseline/gate.js +166 -0
  636. package/dist/core/openapi/baseline/gate.js.map +1 -0
  637. package/dist/core/openapi/baseline/plan.js +112 -0
  638. package/dist/core/openapi/baseline/plan.js.map +1 -0
  639. package/dist/core/openapi/baseline/record.js +175 -0
  640. package/dist/core/openapi/baseline/record.js.map +1 -0
  641. package/dist/core/openapi/depth.js +122 -0
  642. package/dist/core/openapi/depth.js.map +1 -0
  643. package/dist/core/openapi/digest.js +189 -0
  644. package/dist/core/openapi/digest.js.map +1 -0
  645. package/dist/core/{openapi.js → openapi/doc.js} +44 -106
  646. package/dist/core/openapi/doc.js.map +1 -0
  647. package/dist/core/openapi/merge/components.js +234 -0
  648. package/dist/core/openapi/merge/components.js.map +1 -0
  649. package/dist/core/openapi/merge/error.js +26 -0
  650. package/dist/core/openapi/merge/error.js.map +1 -0
  651. package/dist/core/openapi/merge/markers.js +208 -0
  652. package/dist/core/openapi/merge/markers.js.map +1 -0
  653. package/dist/core/openapi/merge/merge.js +256 -0
  654. package/dist/core/openapi/merge/merge.js.map +1 -0
  655. package/dist/core/openapi/merge/pin.js +128 -0
  656. package/dist/core/openapi/merge/pin.js.map +1 -0
  657. package/dist/core/openspec/decide/capabilities.js +244 -0
  658. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  659. package/dist/core/openspec/decide/dispositions.js +63 -0
  660. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  661. package/dist/core/openspec/decide/renames.js +179 -0
  662. package/dist/core/openspec/decide/renames.js.map +1 -0
  663. package/dist/core/openspec/decide/verdict.js +84 -0
  664. package/dist/core/openspec/decide/verdict.js.map +1 -0
  665. package/dist/core/openspec/inventory.js +221 -0
  666. package/dist/core/openspec/inventory.js.map +1 -0
  667. package/dist/core/openspec/model/mapping.js +76 -0
  668. package/dist/core/openspec/model/mapping.js.map +1 -0
  669. package/dist/core/openspec/model/model.js +65 -0
  670. package/dist/core/openspec/model/model.js.map +1 -0
  671. package/dist/core/openspec/scan/changes.js +235 -0
  672. package/dist/core/openspec/scan/changes.js.map +1 -0
  673. package/dist/core/openspec/scan/config.js +200 -0
  674. package/dist/core/openspec/scan/config.js.map +1 -0
  675. package/dist/core/openspec/scan/shape.js +260 -0
  676. package/dist/core/openspec/scan/shape.js.map +1 -0
  677. package/dist/core/openspec/scan/walk.js +133 -0
  678. package/dist/core/openspec/scan/walk.js.map +1 -0
  679. package/dist/core/openspec/scan/workspace.js +71 -0
  680. package/dist/core/openspec/scan/workspace.js.map +1 -0
  681. package/dist/core/owners/codeowners.js +141 -0
  682. package/dist/core/owners/codeowners.js.map +1 -0
  683. package/dist/core/pack/features.js +120 -0
  684. package/dist/core/pack/features.js.map +1 -0
  685. package/dist/core/pack/joins.js +112 -0
  686. package/dist/core/pack/joins.js.map +1 -0
  687. package/dist/core/pack/living.js +118 -0
  688. package/dist/core/pack/living.js.map +1 -0
  689. package/dist/core/pack/pack.js +76 -0
  690. package/dist/core/pack/pack.js.map +1 -0
  691. package/dist/core/permissions/permissions.js +87 -0
  692. package/dist/core/permissions/permissions.js.map +1 -0
  693. package/dist/core/projection/api.js +84 -0
  694. package/dist/core/projection/api.js.map +1 -0
  695. package/dist/core/projection/arch-slice.js +63 -0
  696. package/dist/core/projection/arch-slice.js.map +1 -0
  697. package/dist/core/projection/events.js +34 -0
  698. package/dist/core/projection/events.js.map +1 -0
  699. package/dist/core/provenance/findings.js +208 -0
  700. package/dist/core/provenance/findings.js.map +1 -0
  701. package/dist/core/provenance/git.js +225 -0
  702. package/dist/core/provenance/git.js.map +1 -0
  703. package/dist/core/provenance/gitq/moves.js +182 -0
  704. package/dist/core/provenance/gitq/moves.js.map +1 -0
  705. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  706. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  707. package/dist/core/provenance/sample/scope.js +238 -0
  708. package/dist/core/provenance/sample/scope.js.map +1 -0
  709. package/dist/core/provenance/sample/sections.js +61 -0
  710. package/dist/core/provenance/sample/sections.js.map +1 -0
  711. package/dist/core/provenance/sources.js +263 -0
  712. package/dist/core/provenance/sources.js.map +1 -0
  713. package/dist/core/provenance/stamp.js +232 -0
  714. package/dist/core/provenance/stamp.js.map +1 -0
  715. package/dist/core/provenance/walk.js +157 -0
  716. package/dist/core/provenance/walk.js.map +1 -0
  717. package/dist/core/repo/authored/paths.js +192 -0
  718. package/dist/core/repo/authored/paths.js.map +1 -0
  719. package/dist/core/repo/entries.js +126 -0
  720. package/dist/core/repo/entries.js.map +1 -0
  721. package/dist/core/repo/paths.js +236 -0
  722. package/dist/core/repo/paths.js.map +1 -0
  723. package/dist/core/repo/repo.js +248 -0
  724. package/dist/core/repo/repo.js.map +1 -0
  725. package/dist/core/repo/service-target.js +153 -0
  726. package/dist/core/repo/service-target.js.map +1 -0
  727. package/dist/core/repo/state.js +58 -0
  728. package/dist/core/repo/state.js.map +1 -0
  729. package/dist/core/repo/tree/find.js +52 -0
  730. package/dist/core/repo/tree/find.js.map +1 -0
  731. package/dist/core/repo/tree/fs.js +64 -0
  732. package/dist/core/repo/tree/fs.js.map +1 -0
  733. package/dist/core/repo/tree/marker.js +61 -0
  734. package/dist/core/repo/tree/marker.js.map +1 -0
  735. package/dist/core/repo/tree/views.js +172 -0
  736. package/dist/core/repo/tree/views.js.map +1 -0
  737. package/dist/core/repo/tree/walk.js +234 -0
  738. package/dist/core/repo/tree/walk.js.map +1 -0
  739. package/dist/core/results.js +99 -2
  740. package/dist/core/results.js.map +1 -1
  741. package/dist/core/scaffold/landscape.js +131 -0
  742. package/dist/core/scaffold/landscape.js.map +1 -0
  743. package/dist/core/scaffold/readme.js +84 -0
  744. package/dist/core/scaffold/readme.js.map +1 -0
  745. package/dist/core/staging/commit.js +241 -0
  746. package/dist/core/staging/commit.js.map +1 -0
  747. package/dist/core/staging/interrupted.js +96 -0
  748. package/dist/core/staging/interrupted.js.map +1 -0
  749. package/dist/core/staging/lock.js +206 -0
  750. package/dist/core/staging/lock.js.map +1 -0
  751. package/dist/core/staging/recovery/finding.js +35 -0
  752. package/dist/core/staging/recovery/finding.js.map +1 -0
  753. package/dist/core/staging/recovery/intent.js +98 -0
  754. package/dist/core/staging/recovery/intent.js.map +1 -0
  755. package/dist/core/staging/recovery/recover.js +126 -0
  756. package/dist/core/staging/recovery/recover.js.map +1 -0
  757. package/dist/core/staging/recovery/residue.js +62 -0
  758. package/dist/core/staging/recovery/residue.js.map +1 -0
  759. package/dist/core/staging/snapshot.js +202 -0
  760. package/dist/core/staging/snapshot.js.map +1 -0
  761. package/dist/core/staging/txn/forward.js +171 -0
  762. package/dist/core/staging/txn/forward.js.map +1 -0
  763. package/dist/core/staging/txn/journal.js +139 -0
  764. package/dist/core/staging/txn/journal.js.map +1 -0
  765. package/dist/core/staging/txn/transaction.js +75 -0
  766. package/dist/core/staging/txn/transaction.js.map +1 -0
  767. package/dist/core/staging/writes.js +113 -0
  768. package/dist/core/staging/writes.js.map +1 -0
  769. package/dist/core/status/actions/execution.js +49 -0
  770. package/dist/core/status/actions/execution.js.map +1 -0
  771. package/dist/core/status/contracts.js +102 -0
  772. package/dist/core/status/contracts.js.map +1 -0
  773. package/dist/core/status/feature/artifacts.js +171 -0
  774. package/dist/core/status/feature/artifacts.js.map +1 -0
  775. package/dist/core/status/feature/feature.js +207 -0
  776. package/dist/core/status/feature/feature.js.map +1 -0
  777. package/dist/core/status/feature/next.js +150 -0
  778. package/dist/core/status/feature/next.js.map +1 -0
  779. package/dist/core/status/feature/state.js +21 -0
  780. package/dist/core/status/feature/state.js.map +1 -0
  781. package/dist/core/status/fleet/fleet.js +187 -0
  782. package/dist/core/status/fleet/fleet.js.map +1 -0
  783. package/dist/core/status/fleet/next.js +207 -0
  784. package/dist/core/status/fleet/next.js.map +1 -0
  785. package/dist/core/status/interrupted.js +97 -0
  786. package/dist/core/status/interrupted.js.map +1 -0
  787. package/dist/core/status/report.js +31 -0
  788. package/dist/core/status/report.js.map +1 -0
  789. package/dist/core/status/scan.js +41 -0
  790. package/dist/core/status/scan.js.map +1 -0
  791. package/dist/core/status/verification.js +201 -0
  792. package/dist/core/status/verification.js.map +1 -0
  793. package/dist/core/usecases/capability.js +169 -0
  794. package/dist/core/usecases/capability.js.map +1 -0
  795. package/dist/core/usecases/delta/claims.js +116 -0
  796. package/dist/core/usecases/delta/claims.js.map +1 -0
  797. package/dist/core/usecases/delta/flows.js +103 -0
  798. package/dist/core/usecases/delta/flows.js.map +1 -0
  799. package/dist/core/usecases/delta/overlay.js +235 -0
  800. package/dist/core/usecases/delta/overlay.js.map +1 -0
  801. package/dist/core/usecases/fleet.js +137 -0
  802. package/dist/core/usecases/fleet.js.map +1 -0
  803. package/dist/core/usecases/operations.js +111 -0
  804. package/dist/core/usecases/operations.js.map +1 -0
  805. package/dist/core/usecases/place.js +44 -0
  806. package/dist/core/usecases/place.js.map +1 -0
  807. package/dist/core/usecases/touch.js +101 -0
  808. package/dist/core/usecases/touch.js.map +1 -0
  809. package/dist/core/verify/answers.js +173 -0
  810. package/dist/core/verify/answers.js.map +1 -0
  811. package/dist/core/verify/build.js +150 -0
  812. package/dist/core/verify/build.js.map +1 -0
  813. package/dist/core/verify/checklist.js +201 -0
  814. package/dist/core/verify/checklist.js.map +1 -0
  815. package/dist/core/verify/claims/identity.js +61 -0
  816. package/dist/core/verify/claims/identity.js.map +1 -0
  817. package/dist/core/verify/cross/diff.js +97 -0
  818. package/dist/core/verify/cross/diff.js.map +1 -0
  819. package/dist/core/verify/evidence/contract.js +169 -0
  820. package/dist/core/verify/evidence/contract.js.map +1 -0
  821. package/dist/core/verify/file.js +257 -0
  822. package/dist/core/verify/file.js.map +1 -0
  823. package/dist/core/verify/pins/lint.js +157 -0
  824. package/dist/core/verify/pins/lint.js.map +1 -0
  825. package/dist/core/verify/pins/pin.js +95 -0
  826. package/dist/core/verify/pins/pin.js.map +1 -0
  827. package/dist/core/verify/record.js +142 -0
  828. package/dist/core/verify/record.js.map +1 -0
  829. package/dist/core/verify/store/commit.js +89 -0
  830. package/dist/core/verify/store/commit.js.map +1 -0
  831. package/dist/core/verify/store/render.js +57 -0
  832. package/dist/core/verify/store/render.js.map +1 -0
  833. package/dist/core/vocabulary/health.js +91 -0
  834. package/dist/core/vocabulary/health.js.map +1 -0
  835. package/dist/core/vocabulary/issue.js +55 -0
  836. package/dist/core/vocabulary/issue.js.map +1 -0
  837. package/dist/core/vocabulary/maturity.js +145 -0
  838. package/dist/core/vocabulary/maturity.js.map +1 -0
  839. package/dist/core/{report.js → vocabulary/report.js} +30 -2
  840. package/dist/core/vocabulary/report.js.map +1 -0
  841. package/dist/core/vocabulary/steps.js +266 -0
  842. package/dist/core/vocabulary/steps.js.map +1 -0
  843. package/dist/core/workspace/discover.js +239 -0
  844. package/dist/core/workspace/discover.js.map +1 -0
  845. package/dist/core/workspace/render.js +52 -0
  846. package/dist/core/workspace/render.js.map +1 -0
  847. package/examples/README.md +189 -0
  848. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  849. package/examples/docs/architecture/capabilities.yaml +31 -0
  850. package/examples/docs/architecture/landscape.likec4 +280 -0
  851. package/examples/docs/architecture/obligations.yaml +23 -0
  852. package/examples/docs/architecture/permissions.yaml +50 -0
  853. package/examples/docs/architecture/subsystems.likec4 +11 -0
  854. package/examples/docs/architecture/usecases/order-notification.likec4 +65 -0
  855. package/examples/docs/capabilities/checkout/spec.md +55 -0
  856. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  857. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  858. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  859. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  860. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  861. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  862. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +129 -0
  863. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  864. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  865. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  866. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  867. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  868. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +28 -0
  869. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  870. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  871. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  872. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  873. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  874. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  875. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  876. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  877. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  878. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  879. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +70 -0
  880. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  881. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  882. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  883. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  884. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  885. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  886. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  887. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  888. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  889. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  890. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  891. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  892. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  893. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  894. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  895. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  896. package/examples/docs/glossary/order.md +15 -0
  897. package/examples/docs/glossary/payments/authorization.md +14 -0
  898. package/examples/docs/likec4.config.json +9 -0
  899. package/examples/docs/loam.json +3 -0
  900. package/examples/docs/services/checkout-web/model.likec4 +109 -0
  901. package/examples/docs/services/checkout-web/spec.md +91 -0
  902. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  903. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  904. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  905. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  906. package/examples/docs/services/order-service/arch.spec.md +127 -0
  907. package/examples/docs/services/order-service/asyncapi.yaml +108 -0
  908. package/examples/docs/services/order-service/health.yaml +57 -0
  909. package/examples/docs/services/order-service/model.likec4 +138 -0
  910. package/examples/docs/services/order-service/openapi.yaml +257 -0
  911. package/examples/docs/services/order-service/runbook.md +62 -0
  912. package/examples/docs/services/order-service/spec.md +134 -0
  913. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  914. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  915. package/examples/docs/services/payment-service/arch.spec.md +73 -0
  916. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  917. package/examples/docs/services/payment-service/health.yaml +39 -0
  918. package/examples/docs/services/payment-service/model.likec4 +67 -0
  919. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  920. package/examples/docs/services/payment-service/runbook.md +37 -0
  921. package/examples/docs/services/payment-service/spec.md +88 -0
  922. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  923. package/examples/docs/services/platform/identity-service/arch.spec.md +117 -0
  924. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  925. package/examples/docs/services/platform/identity-service/model.likec4 +83 -0
  926. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  927. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  928. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  929. package/examples/docs/services/platform/notification-service/asyncapi.yaml +199 -0
  930. package/examples/docs/services/platform/notification-service/health.yaml +35 -0
  931. package/examples/docs/services/platform/notification-service/model.likec4 +118 -0
  932. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  933. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  934. package/examples/docs/services/platform/subsystem.yaml +2 -0
  935. package/examples/fleet.yaml +57 -0
  936. package/package.json +19 -6
  937. package/dist/commands/adopt.js +0 -240
  938. package/dist/commands/adopt.js.map +0 -1
  939. package/dist/commands/archive.js +0 -1313
  940. package/dist/commands/archive.js.map +0 -1
  941. package/dist/commands/delta.js +0 -388
  942. package/dist/commands/delta.js.map +0 -1
  943. package/dist/commands/docs-repo-gate.js.map +0 -1
  944. package/dist/commands/format.js +0 -17
  945. package/dist/commands/format.js.map +0 -1
  946. package/dist/commands/gherkin.js +0 -309
  947. package/dist/commands/gherkin.js.map +0 -1
  948. package/dist/commands/init.js.map +0 -1
  949. package/dist/commands/list.js +0 -291
  950. package/dist/commands/list.js.map +0 -1
  951. package/dist/commands/migrate-openspec.js +0 -950
  952. package/dist/commands/migrate-openspec.js.map +0 -1
  953. package/dist/commands/new.js +0 -413
  954. package/dist/commands/new.js.map +0 -1
  955. package/dist/commands/rebase.js +0 -356
  956. package/dist/commands/rebase.js.map +0 -1
  957. package/dist/commands/show.js.map +0 -1
  958. package/dist/commands/status.js +0 -254
  959. package/dist/commands/status.js.map +0 -1
  960. package/dist/commands/unarchive.js.map +0 -1
  961. package/dist/commands/validate.js +0 -1591
  962. package/dist/commands/validate.js.map +0 -1
  963. package/dist/commands/verify.js +0 -775
  964. package/dist/commands/verify.js.map +0 -1
  965. package/dist/commands/vouch.js +0 -343
  966. package/dist/commands/vouch.js.map +0 -1
  967. package/dist/core/agent.js +0 -2065
  968. package/dist/core/agent.js.map +0 -1
  969. package/dist/core/agents-stamp.js +0 -68
  970. package/dist/core/agents-stamp.js.map +0 -1
  971. package/dist/core/arch.js +0 -130
  972. package/dist/core/arch.js.map +0 -1
  973. package/dist/core/brief.js +0 -733
  974. package/dist/core/brief.js.map +0 -1
  975. package/dist/core/coherence.js +0 -577
  976. package/dist/core/coherence.js.map +0 -1
  977. package/dist/core/concurrency.js.map +0 -1
  978. package/dist/core/config.js.map +0 -1
  979. package/dist/core/delta.js +0 -476
  980. package/dist/core/delta.js.map +0 -1
  981. package/dist/core/dependencies.js +0 -356
  982. package/dist/core/dependencies.js.map +0 -1
  983. package/dist/core/doctor.js +0 -559
  984. package/dist/core/doctor.js.map +0 -1
  985. package/dist/core/document-bytes.js.map +0 -1
  986. package/dist/core/explore.js.map +0 -1
  987. package/dist/core/frontmatter.js.map +0 -1
  988. package/dist/core/gherkin.js +0 -463
  989. package/dist/core/gherkin.js.map +0 -1
  990. package/dist/core/health.js +0 -67
  991. package/dist/core/health.js.map +0 -1
  992. package/dist/core/ids.js +0 -122
  993. package/dist/core/ids.js.map +0 -1
  994. package/dist/core/issue.js +0 -9
  995. package/dist/core/issue.js.map +0 -1
  996. package/dist/core/json.js +0 -74
  997. package/dist/core/json.js.map +0 -1
  998. package/dist/core/likec4.js +0 -479
  999. package/dist/core/likec4.js.map +0 -1
  1000. package/dist/core/maturity.js +0 -66
  1001. package/dist/core/maturity.js.map +0 -1
  1002. package/dist/core/openapi-merge.js +0 -552
  1003. package/dist/core/openapi-merge.js.map +0 -1
  1004. package/dist/core/openapi.js.map +0 -1
  1005. package/dist/core/openspec-inventory.js +0 -1440
  1006. package/dist/core/openspec-inventory.js.map +0 -1
  1007. package/dist/core/path-safety.js.map +0 -1
  1008. package/dist/core/provenance.js +0 -720
  1009. package/dist/core/provenance.js.map +0 -1
  1010. package/dist/core/records.js.map +0 -1
  1011. package/dist/core/repo.js +0 -436
  1012. package/dist/core/repo.js.map +0 -1
  1013. package/dist/core/report.js.map +0 -1
  1014. package/dist/core/spec.js +0 -481
  1015. package/dist/core/spec.js.map +0 -1
  1016. package/dist/core/staging.js +0 -890
  1017. package/dist/core/staging.js.map +0 -1
  1018. package/dist/core/status.js +0 -1104
  1019. package/dist/core/status.js.map +0 -1
  1020. package/dist/core/steps.js +0 -72
  1021. package/dist/core/steps.js.map +0 -1
  1022. package/dist/core/verify.js +0 -807
  1023. package/dist/core/verify.js.map +0 -1
  1024. package/dist/core/version.js.map +0 -1
  1025. /package/dist/core/{concurrency.js → kernel/concurrency.js} +0 -0
  1026. /package/dist/core/{records.js → kernel/records.js} +0 -0
@@ -0,0 +1,254 @@
1
+ /**
2
+ * What a requirement document owes, checked the same way wherever it lives.
3
+ *
4
+ * The same `### Requirement:` grammar is authored in four places — a service's
5
+ * spec.md and arch.spec.md, and a feature's per-service deltas of both — and
6
+ * every breach below carries from a delta into the living document through the
7
+ * archive merge. So the checks are one set called from both target kinds
8
+ * (`service/` and `feature/`): grading a delta more leniently than the file it
9
+ * is about to become is how a defect acquires a signature saying it was
10
+ * reviewed.
11
+ *
12
+ * None of these read the filesystem and none of them print — they take parsed
13
+ * requirements and answer in findings.
14
+ */
15
+ import {} from "../../../core/vocabulary/report.js";
16
+ import { requirementsMissingScenarios } from "../../../core/document/scenarios.js";
17
+ import { requirementIdProblems } from "../../../core/document/spec.js";
18
+ import { closeIds, coversCandidates, entryResolves, parseCoversEntry, } from "../../../core/c4/arch.js";
19
+ import {} from "../../../core/permissions/permissions.js";
20
+ import {} from "../../../core/openapi/doc.js";
21
+ /** The parsed Covers entries of every requirement that will live (REMOVED covers nothing). */
22
+ export function coversEntries(reqs) {
23
+ return reqs.filter((r) => r.kind !== "REMOVED").flatMap((r) => r.covers.map(parseCoversEntry));
24
+ }
25
+ /**
26
+ * `spec.duplicate-requirement` — two `### Requirement:` blocks with one name in
27
+ * one LIVING document. Nothing else catches it, and the merge algebra
28
+ * (applyRequirementDelta) matches by name and edits only the FIRST match: a
29
+ * later archive rewrites one copy and the other survives as a stale snapshot
30
+ * of whatever the requirement used to say. Per file on purpose — spec.md and
31
+ * arch.spec.md are separate requirement namespaces (their merges never cross
32
+ * files), so one name appearing in both is legal and unflagged.
33
+ */
34
+ export function duplicateRequirementFindings(reqs, where, subject) {
35
+ const counts = new Map();
36
+ for (const r of reqs)
37
+ counts.set(r.name, (counts.get(r.name) ?? 0) + 1);
38
+ return [...counts]
39
+ .filter(([, n]) => n > 1)
40
+ .map(([name, n]) => ({
41
+ severity: "error",
42
+ code: "spec.duplicate-requirement",
43
+ subject,
44
+ message: `${where}: requirement '${name}' is defined ${n} times — a merge edits only the first, every other copy lives on stale; keep exactly one`,
45
+ }));
46
+ }
47
+ /** Stable IDs are optional, but once authored they must select exactly one requirement. */
48
+ export function requirementIdFindings(reqs, where, subject) {
49
+ return requirementIdProblems(reqs).map((problem) => {
50
+ if (problem.kind === "invalid") {
51
+ return {
52
+ severity: "error",
53
+ code: "spec.requirement-id-invalid",
54
+ subject,
55
+ message: `${where}: requirement '${problem.requirement}' has invalid Requirement-ID '${problem.value}' — use 1-128 characters matching [A-Za-z][A-Za-z0-9._-]*`,
56
+ };
57
+ }
58
+ if (problem.kind === "repeated") {
59
+ return {
60
+ severity: "error",
61
+ code: "spec.requirement-id-repeated",
62
+ subject,
63
+ message: `${where}: requirement '${problem.requirement}' declares Requirement-ID ${problem.values.length} times — identity must be declared exactly once`,
64
+ };
65
+ }
66
+ return {
67
+ severity: "error",
68
+ code: "spec.requirement-id-duplicate",
69
+ subject,
70
+ message: `${where}: Requirement-ID '${problem.id}' is shared by ${problem.requirements.map((name) => `'${name}'`).join(", ")} — one ID may identify only one requirement`,
71
+ };
72
+ });
73
+ }
74
+ /**
75
+ * The two list lines of the requirement grammar, exactly as core/document/spec.ts spells
76
+ * them (mirrored here, not exported from there, because the parser's grammar is
77
+ * its own; a drift shows up as this check counting differently than the parser
78
+ * assigns). A SECOND matching line in one requirement body REPLACES the first —
79
+ * assignment, not append, the documented keep-last quirk — so the author's
80
+ * "long list in two lines" pattern silently loses its first line.
81
+ */
82
+ const OPERATIONS_LINE_RE = /^\s*Operations?:\s*(.+?)\s*$/i;
83
+ const COVERS_LINE_RE = /^\s*Covers?:\s*(.+?)\s*$/i;
84
+ /**
85
+ * `spec.repeated-operations` / `spec.repeated-covers` — warn on the silent
86
+ * loss, keep the keep-last semantics (changing them would re-read every spec
87
+ * in the fleet). Scenario bodies never count: the parser only assigns from the
88
+ * requirement's own body lines, and `Requirement.text` is exactly those.
89
+ * REMOVED requirements are exempt the way coversEntries exempts them — content
90
+ * on its way out obliges nothing.
91
+ */
92
+ export function repeatedListLineFindings(reqs, where, subject) {
93
+ const out = [];
94
+ for (const r of reqs) {
95
+ if (r.kind === "REMOVED")
96
+ continue;
97
+ for (const { re, label, code } of [
98
+ { re: OPERATIONS_LINE_RE, label: "Operations:", code: "spec.repeated-operations" },
99
+ { re: COVERS_LINE_RE, label: "Covers:", code: "spec.repeated-covers" },
100
+ ]) {
101
+ const n = r.text.filter((line) => re.test(line)).length;
102
+ if (n < 2)
103
+ continue;
104
+ out.push({
105
+ severity: "warn",
106
+ code,
107
+ subject,
108
+ message: `${where}: requirement '${r.name}' has ${n} '${label}' lines — the last REPLACES the others (assignment, not append), the earlier list is silently lost; merge them into one comma-separated line`,
109
+ });
110
+ }
111
+ }
112
+ return out;
113
+ }
114
+ export function coversUnknownFindings(reqs, target, scope, healthUnreadable = false) {
115
+ const { where, subject } = target;
116
+ const out = [];
117
+ for (const r of reqs) {
118
+ if (r.kind === "REMOVED")
119
+ continue;
120
+ for (const raw of r.covers) {
121
+ const entry = parseCoversEntry(raw);
122
+ if (healthUnreadable && (entry.form === "alert" || entry.form === "sli"))
123
+ continue;
124
+ if (entryResolves(entry, scope))
125
+ continue;
126
+ const close = coversCandidates(entry, scope);
127
+ out.push({
128
+ severity: "warn",
129
+ code: "covers.unknown",
130
+ subject,
131
+ message: `${where}: requirement '${r.name}' — Covers: '${raw}' resolves to nothing` +
132
+ (close.length > 0
133
+ ? `. Did you mean: ${close.join(", ")}?`
134
+ : " in the model, the landscape or health.yaml"),
135
+ });
136
+ }
137
+ }
138
+ return out;
139
+ }
140
+ /**
141
+ * `permissions.unknown` — the typo guard on the `Requires:` line, and an ERROR
142
+ * where its `Covers:` sibling is a warning.
143
+ *
144
+ * The two differ because what they promise differs. `Covers:` is advisory end
145
+ * to end: a wrong id costs its author the coverage they wrote the line for and
146
+ * nothing else. `Requires:` names authorization the service actually enforces,
147
+ * and the failure it guards is the one an unaided reader cannot see — an
148
+ * invented permission reads exactly like a real one, in the requirement, in the
149
+ * generated scenario, and in the test somebody then writes against it. Its
150
+ * grade is `Operations:`', not `Covers:`'.
151
+ *
152
+ * Silent on ONE case only: an unreadable vocabulary, where
153
+ * `permissions.invalid` is the honest finding and grading every entry against a
154
+ * file nobody could parse is the false cascade `healthUnreadable` exists to
155
+ * stop one axis over. A MISSING vocabulary is not that case — the `Requires:`
156
+ * line is itself the opt-in, and a line that resolves against nothing while
157
+ * reading like a join is the failure this whole axis exists to prevent.
158
+ */
159
+ export function requiresUnknownFindings(reqs, target, vocabulary) {
160
+ const { where, subject } = target;
161
+ if (vocabulary.invalid !== undefined)
162
+ return [];
163
+ const known = [...vocabulary.byId.keys()];
164
+ const out = [];
165
+ for (const r of reqs) {
166
+ if (r.kind === "REMOVED")
167
+ continue;
168
+ for (const raw of r.requires) {
169
+ if (vocabulary.byId.has(raw))
170
+ continue;
171
+ const close = closeIds(raw, known);
172
+ out.push({
173
+ severity: "error",
174
+ code: "permissions.unknown",
175
+ subject,
176
+ message: `${where}: requirement '${r.name}' — Requires: '${raw}' is not declared in architecture/permissions.yaml` +
177
+ (!vocabulary.present
178
+ ? ", which does not exist. The `Requires:` line is the opt-in: create the fleet vocabulary with this permission under its subject kind, or drop the line"
179
+ : close.length > 0
180
+ ? `. Did you mean: ${close.join(", ")}?`
181
+ : ". Entries are '<subject>/<permission>'; declare it there, or fix the spelling"),
182
+ });
183
+ }
184
+ }
185
+ return out;
186
+ }
187
+ /**
188
+ * `api.response-ungoverned` — a declared 4xx/5xx response no scenario reaches.
189
+ *
190
+ * The gap this closes is the one a whole adoption can fall into: `api.ungoverned`
191
+ * grades OPERATIONS against requirements, so an endpoint with one happy-path
192
+ * requirement and twelve declared failure codes is fully governed by every
193
+ * check loam had. The refusals are where a service's decision layer surfaces —
194
+ * a permission denied, a field combination rejected, a state that forbids the
195
+ * transition — and the contract is the only artifact in the corpus that already
196
+ * enumerates them.
197
+ *
198
+ * A scenario "reaches" a code when the code appears as a standalone number
199
+ * anywhere in its body, `Examples` rows included — which is why this arrived
200
+ * with outline support and not before: a status column is exactly where a
201
+ * matrix puts its codes, and before it those rows were prose in a description.
202
+ * The match is textual and therefore generous by design. It answers "did
203
+ * anybody write this case down", not "is this scenario correct", and the
204
+ * failure it is built to catch is the code nobody mentioned at all. Warn, like
205
+ * its sibling: a service may legitimately declare a code its scenarios describe
206
+ * in words, and an error would teach authors to paste numbers into prose.
207
+ *
208
+ * Operations no requirement governs are skipped: `api.ungoverned` already
209
+ * names those, and reporting each of their codes as well is one defect
210
+ * counted twice.
211
+ */
212
+ export function responseGovernanceFindings(service, ops, livingReqs) {
213
+ const ungoverned = [];
214
+ for (const op of ops) {
215
+ if (op.failureCodes.length === 0)
216
+ continue;
217
+ const governing = livingReqs.filter((r) => r.kind !== "REMOVED" && r.operations.includes(op.id));
218
+ if (governing.length === 0)
219
+ continue;
220
+ const body = governing.flatMap((r) => r.scenarios.flatMap((s) => s.lines)).join("\n");
221
+ const missing = op.failureCodes.filter((code) => !new RegExp(`(?<!\\d)${code}(?!\\d)`).test(body));
222
+ if (missing.length > 0)
223
+ ungoverned.push(`${op.id}: ${missing.join(", ")}`);
224
+ }
225
+ if (ungoverned.length === 0)
226
+ return [];
227
+ return [
228
+ {
229
+ severity: "warn",
230
+ code: "api.response-ungoverned",
231
+ subject: service,
232
+ message: `${service}: ${ungoverned.length} operation(s) declare a failure response no scenario reaches — write the refusal as a scenario, or as a row in one`,
233
+ details: ungoverned,
234
+ },
235
+ ];
236
+ }
237
+ export function coverageFinding(label, reqs) {
238
+ const missing = requirementsMissingScenarios(reqs);
239
+ if (missing.length === 0) {
240
+ return {
241
+ severity: "ok",
242
+ code: "requirements.covered",
243
+ message: `${label} covered (${reqs.length} requirement${reqs.length === 1 ? "" : "s"}, all with scenarios)`,
244
+ };
245
+ }
246
+ return {
247
+ severity: "error",
248
+ code: "requirements.missing-scenarios",
249
+ message: `${label}: ${missing.length} requirement(s) without a scenario`,
250
+ details: missing.map((r) => r.name),
251
+ text: { detailPrefix: "- " },
252
+ };
253
+ }
254
+ //# sourceMappingURL=requirements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirements.js","sourceRoot":"","sources":["../../../../src/commands/validate/checks/requirements.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAgB,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAoB,MAAM,gCAAgC,CAAC;AACzF,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,gBAAgB,GAGjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAmB,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAkB,MAAM,8BAA8B,CAAC;AAE9D,8FAA8F;AAC9F,MAAM,UAAU,aAAa,CAAC,IAAmB;IAC/C,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC;AACjG,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,4BAA4B,CAAC,IAAmB,EAAE,KAAa,EAAE,OAAe;IAC9F,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxE,OAAO,CAAC,GAAG,MAAM,CAAC;SACf,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;SACxB,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnB,QAAQ,EAAE,OAAgB;QAC1B,IAAI,EAAE,4BAA4B;QAClC,OAAO;QACP,OAAO,EAAE,GAAG,KAAK,kBAAkB,IAAI,gBAAgB,CAAC,0FAA0F;KACnJ,CAAC,CAAC,CAAC;AACR,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,qBAAqB,CAAC,IAAmB,EAAE,KAAa,EAAE,OAAe;IACvF,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACjD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO;gBACL,QAAQ,EAAE,OAAgB;gBAC1B,IAAI,EAAE,6BAA6B;gBACnC,OAAO;gBACP,OAAO,EAAE,GAAG,KAAK,kBAAkB,OAAO,CAAC,WAAW,iCAAiC,OAAO,CAAC,KAAK,2DAA2D;aAChK,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAChC,OAAO;gBACL,QAAQ,EAAE,OAAgB;gBAC1B,IAAI,EAAE,8BAA8B;gBACpC,OAAO;gBACP,OAAO,EAAE,GAAG,KAAK,kBAAkB,OAAO,CAAC,WAAW,6BAA6B,OAAO,CAAC,MAAM,CAAC,MAAM,iDAAiD;aAC1J,CAAC;QACJ,CAAC;QACD,OAAO;YACL,QAAQ,EAAE,OAAgB;YAC1B,IAAI,EAAE,+BAA+B;YACrC,OAAO;YACP,OAAO,EAAE,GAAG,KAAK,qBAAqB,OAAO,CAAC,EAAE,kBAAkB,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,6CAA6C;SAC1K,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,kBAAkB,GAAG,+BAA+B,CAAC;AAC3D,MAAM,cAAc,GAAG,2BAA2B,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAmB,EAAE,KAAa,EAAE,OAAe;IAC1F,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS;QACnC,KAAK,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI;YAChC,EAAE,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,0BAA0B,EAAE;YAClF,EAAE,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,sBAAsB,EAAE;SACvE,EAAE,CAAC;YACF,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;YACxD,IAAI,CAAC,GAAG,CAAC;gBAAE,SAAS;YACpB,GAAG,CAAC,IAAI,CAAC;gBACP,QAAQ,EAAE,MAAM;gBAChB,IAAI;gBACJ,OAAO;gBACP,OAAO,EAAE,GAAG,KAAK,kBAAkB,CAAC,CAAC,IAAI,SAAS,CAAC,KAAK,KAAK,8IAA8I;aAC5M,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAiBD,MAAM,UAAU,qBAAqB,CACnC,IAAmB,EACnB,MAAsB,EACtB,KAAoB,EACpB,gBAAgB,GAAG,KAAK;IAExB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAClC,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS;QACnC,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,gBAAgB,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC;gBAAE,SAAS;YACnF,IAAI,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC;gBAAE,SAAS;YAC1C,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC7C,GAAG,CAAC,IAAI,CAAC;gBACP,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,gBAAgB;gBACtB,OAAO;gBACP,OAAO,EACL,GAAG,KAAK,kBAAkB,CAAC,CAAC,IAAI,gBAAgB,GAAG,uBAAuB;oBAC1E,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;wBACf,CAAC,CAAC,mBAAmB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;wBACxC,CAAC,CAAC,6CAA6C,CAAC;aACrD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,uBAAuB,CACrC,IAAmB,EACnB,MAAsB,EACtB,UAAsB;IAEtB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAClC,IAAI,UAAU,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAChD,MAAM,KAAK,GAAG,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS;QACnC,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC7B,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACnC,GAAG,CAAC,IAAI,CAAC;gBACP,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,qBAAqB;gBAC3B,OAAO;gBACP,OAAO,EACL,GAAG,KAAK,kBAAkB,CAAC,CAAC,IAAI,kBAAkB,GAAG,oDAAoD;oBACzG,CAAC,CAAC,UAAU,CAAC,OAAO;wBAClB,CAAC,CAAC,uJAAuJ;wBACzJ,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;4BAChB,CAAC,CAAC,mBAAmB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;4BACxC,CAAC,CAAC,+EAA+E,CAAC;aACzF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAAe,EACf,GAAgB,EAChB,UAAyB;IAEzB,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAC3C,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACjG,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACrC,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtF,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,WAAW,IAAI,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACnG,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,OAAO;QACL;YACE,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE,GAAG,OAAO,KAAK,UAAU,CAAC,MAAM,oHAAoH;YAC7J,OAAO,EAAE,UAAU;SACpB;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,IAAmB;IAChE,MAAM,OAAO,GAAG,4BAA4B,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,sBAAsB;YAC5B,OAAO,EAAE,GAAG,KAAK,aAAa,IAAI,CAAC,MAAM,eAAe,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,uBAAuB;SAC5G,CAAC;IACJ,CAAC;IACD,OAAO;QACL,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,gCAAgC;QACtC,OAAO,EAAE,GAAG,KAAK,KAAK,OAAO,CAAC,MAAM,oCAAoC;QACxE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACnC,IAAI,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KAC7B,CAAC;AACJ,CAAC","sourcesContent":["/**\n * What a requirement document owes, checked the same way wherever it lives.\n *\n * The same `### Requirement:` grammar is authored in four places — a service's\n * spec.md and arch.spec.md, and a feature's per-service deltas of both — and\n * every breach below carries from a delta into the living document through the\n * archive merge. So the checks are one set called from both target kinds\n * (`service/` and `feature/`): grading a delta more leniently than the file it\n * is about to become is how a defect acquires a signature saying it was\n * reviewed.\n *\n * None of these read the filesystem and none of them print — they take parsed\n * requirements and answer in findings.\n */\nimport { type Finding } from \"../../../core/vocabulary/report.js\";\nimport { requirementsMissingScenarios } from \"../../../core/document/scenarios.js\";\nimport { requirementIdProblems, type Requirement } from \"../../../core/document/spec.js\";\nimport {\n closeIds,\n coversCandidates,\n entryResolves,\n parseCoversEntry,\n type CoverageScope,\n type CoversEntry,\n} from \"../../../core/c4/arch.js\";\nimport { type Vocabulary } from \"../../../core/permissions/permissions.js\";\nimport { type Operation } from \"../../../core/openapi/doc.js\";\n\n/** The parsed Covers entries of every requirement that will live (REMOVED covers nothing). */\nexport function coversEntries(reqs: Requirement[]): CoversEntry[] {\n return reqs.filter((r) => r.kind !== \"REMOVED\").flatMap((r) => r.covers.map(parseCoversEntry));\n}\n\n/**\n * `spec.duplicate-requirement` — two `### Requirement:` blocks with one name in\n * one LIVING document. Nothing else catches it, and the merge algebra\n * (applyRequirementDelta) matches by name and edits only the FIRST match: a\n * later archive rewrites one copy and the other survives as a stale snapshot\n * of whatever the requirement used to say. Per file on purpose — spec.md and\n * arch.spec.md are separate requirement namespaces (their merges never cross\n * files), so one name appearing in both is legal and unflagged.\n */\nexport function duplicateRequirementFindings(reqs: Requirement[], where: string, subject: string): Finding[] {\n const counts = new Map<string, number>();\n for (const r of reqs) counts.set(r.name, (counts.get(r.name) ?? 0) + 1);\n return [...counts]\n .filter(([, n]) => n > 1)\n .map(([name, n]) => ({\n severity: \"error\" as const,\n code: \"spec.duplicate-requirement\",\n subject,\n message: `${where}: requirement '${name}' is defined ${n} times — a merge edits only the first, every other copy lives on stale; keep exactly one`,\n }));\n}\n\n/** Stable IDs are optional, but once authored they must select exactly one requirement. */\nexport function requirementIdFindings(reqs: Requirement[], where: string, subject: string): Finding[] {\n return requirementIdProblems(reqs).map((problem) => {\n if (problem.kind === \"invalid\") {\n return {\n severity: \"error\" as const,\n code: \"spec.requirement-id-invalid\",\n subject,\n message: `${where}: requirement '${problem.requirement}' has invalid Requirement-ID '${problem.value}' — use 1-128 characters matching [A-Za-z][A-Za-z0-9._-]*`,\n };\n }\n if (problem.kind === \"repeated\") {\n return {\n severity: \"error\" as const,\n code: \"spec.requirement-id-repeated\",\n subject,\n message: `${where}: requirement '${problem.requirement}' declares Requirement-ID ${problem.values.length} times — identity must be declared exactly once`,\n };\n }\n return {\n severity: \"error\" as const,\n code: \"spec.requirement-id-duplicate\",\n subject,\n message: `${where}: Requirement-ID '${problem.id}' is shared by ${problem.requirements.map((name) => `'${name}'`).join(\", \")} — one ID may identify only one requirement`,\n };\n });\n}\n\n/**\n * The two list lines of the requirement grammar, exactly as core/document/spec.ts spells\n * them (mirrored here, not exported from there, because the parser's grammar is\n * its own; a drift shows up as this check counting differently than the parser\n * assigns). A SECOND matching line in one requirement body REPLACES the first —\n * assignment, not append, the documented keep-last quirk — so the author's\n * \"long list in two lines\" pattern silently loses its first line.\n */\nconst OPERATIONS_LINE_RE = /^\\s*Operations?:\\s*(.+?)\\s*$/i;\nconst COVERS_LINE_RE = /^\\s*Covers?:\\s*(.+?)\\s*$/i;\n\n/**\n * `spec.repeated-operations` / `spec.repeated-covers` — warn on the silent\n * loss, keep the keep-last semantics (changing them would re-read every spec\n * in the fleet). Scenario bodies never count: the parser only assigns from the\n * requirement's own body lines, and `Requirement.text` is exactly those.\n * REMOVED requirements are exempt the way coversEntries exempts them — content\n * on its way out obliges nothing.\n */\nexport function repeatedListLineFindings(reqs: Requirement[], where: string, subject: string): Finding[] {\n const out: Finding[] = [];\n for (const r of reqs) {\n if (r.kind === \"REMOVED\") continue;\n for (const { re, label, code } of [\n { re: OPERATIONS_LINE_RE, label: \"Operations:\", code: \"spec.repeated-operations\" },\n { re: COVERS_LINE_RE, label: \"Covers:\", code: \"spec.repeated-covers\" },\n ]) {\n const n = r.text.filter((line) => re.test(line)).length;\n if (n < 2) continue;\n out.push({\n severity: \"warn\",\n code,\n subject,\n message: `${where}: requirement '${r.name}' has ${n} '${label}' lines — the last REPLACES the others (assignment, not append), the earlier list is silently lost; merge them into one comma-separated line`,\n });\n }\n }\n return out;\n}\n\n/**\n * `covers.unknown` — the typo guard on the Covers: line. Warn, not error: the\n * axis is advisory end to end, and a wrong id already costs its author the\n * coverage they wrote the line for. The hint offers only real ids (closeIds's\n * rule), and says where resolution looked when there is nothing close.\n * `healthUnreadable` mutes the alert:/sli: forms only: against a health.yaml\n * nobody could read, \"did you mean\" is a false diagnosis of a typo —\n * health.invalid (emitted by the service target) is the honest one.\n */\n/** Which document is being graded, and under whose name the finding is filed. */\nexport interface CoverageTarget {\n where: string;\n subject: string;\n}\n\nexport function coversUnknownFindings(\n reqs: Requirement[],\n target: CoverageTarget,\n scope: CoverageScope,\n healthUnreadable = false,\n): Finding[] {\n const { where, subject } = target;\n const out: Finding[] = [];\n for (const r of reqs) {\n if (r.kind === \"REMOVED\") continue;\n for (const raw of r.covers) {\n const entry = parseCoversEntry(raw);\n if (healthUnreadable && (entry.form === \"alert\" || entry.form === \"sli\")) continue;\n if (entryResolves(entry, scope)) continue;\n const close = coversCandidates(entry, scope);\n out.push({\n severity: \"warn\",\n code: \"covers.unknown\",\n subject,\n message:\n `${where}: requirement '${r.name}' — Covers: '${raw}' resolves to nothing` +\n (close.length > 0\n ? `. Did you mean: ${close.join(\", \")}?`\n : \" in the model, the landscape or health.yaml\"),\n });\n }\n }\n return out;\n}\n\n/**\n * `permissions.unknown` — the typo guard on the `Requires:` line, and an ERROR\n * where its `Covers:` sibling is a warning.\n *\n * The two differ because what they promise differs. `Covers:` is advisory end\n * to end: a wrong id costs its author the coverage they wrote the line for and\n * nothing else. `Requires:` names authorization the service actually enforces,\n * and the failure it guards is the one an unaided reader cannot see — an\n * invented permission reads exactly like a real one, in the requirement, in the\n * generated scenario, and in the test somebody then writes against it. Its\n * grade is `Operations:`', not `Covers:`'.\n *\n * Silent on ONE case only: an unreadable vocabulary, where\n * `permissions.invalid` is the honest finding and grading every entry against a\n * file nobody could parse is the false cascade `healthUnreadable` exists to\n * stop one axis over. A MISSING vocabulary is not that case — the `Requires:`\n * line is itself the opt-in, and a line that resolves against nothing while\n * reading like a join is the failure this whole axis exists to prevent.\n */\nexport function requiresUnknownFindings(\n reqs: Requirement[],\n target: CoverageTarget,\n vocabulary: Vocabulary,\n): Finding[] {\n const { where, subject } = target;\n if (vocabulary.invalid !== undefined) return [];\n const known = [...vocabulary.byId.keys()];\n const out: Finding[] = [];\n for (const r of reqs) {\n if (r.kind === \"REMOVED\") continue;\n for (const raw of r.requires) {\n if (vocabulary.byId.has(raw)) continue;\n const close = closeIds(raw, known);\n out.push({\n severity: \"error\",\n code: \"permissions.unknown\",\n subject,\n message:\n `${where}: requirement '${r.name}' — Requires: '${raw}' is not declared in architecture/permissions.yaml` +\n (!vocabulary.present\n ? \", which does not exist. The `Requires:` line is the opt-in: create the fleet vocabulary with this permission under its subject kind, or drop the line\"\n : close.length > 0\n ? `. Did you mean: ${close.join(\", \")}?`\n : \". Entries are '<subject>/<permission>'; declare it there, or fix the spelling\"),\n });\n }\n }\n return out;\n}\n\n/**\n * `api.response-ungoverned` — a declared 4xx/5xx response no scenario reaches.\n *\n * The gap this closes is the one a whole adoption can fall into: `api.ungoverned`\n * grades OPERATIONS against requirements, so an endpoint with one happy-path\n * requirement and twelve declared failure codes is fully governed by every\n * check loam had. The refusals are where a service's decision layer surfaces —\n * a permission denied, a field combination rejected, a state that forbids the\n * transition — and the contract is the only artifact in the corpus that already\n * enumerates them.\n *\n * A scenario \"reaches\" a code when the code appears as a standalone number\n * anywhere in its body, `Examples` rows included — which is why this arrived\n * with outline support and not before: a status column is exactly where a\n * matrix puts its codes, and before it those rows were prose in a description.\n * The match is textual and therefore generous by design. It answers \"did\n * anybody write this case down\", not \"is this scenario correct\", and the\n * failure it is built to catch is the code nobody mentioned at all. Warn, like\n * its sibling: a service may legitimately declare a code its scenarios describe\n * in words, and an error would teach authors to paste numbers into prose.\n *\n * Operations no requirement governs are skipped: `api.ungoverned` already\n * names those, and reporting each of their codes as well is one defect\n * counted twice.\n */\nexport function responseGovernanceFindings(\n service: string,\n ops: Operation[],\n livingReqs: Requirement[],\n): Finding[] {\n const ungoverned: string[] = [];\n for (const op of ops) {\n if (op.failureCodes.length === 0) continue;\n const governing = livingReqs.filter((r) => r.kind !== \"REMOVED\" && r.operations.includes(op.id));\n if (governing.length === 0) continue;\n const body = governing.flatMap((r) => r.scenarios.flatMap((s) => s.lines)).join(\"\\n\");\n const missing = op.failureCodes.filter((code) => !new RegExp(`(?<!\\\\d)${code}(?!\\\\d)`).test(body));\n if (missing.length > 0) ungoverned.push(`${op.id}: ${missing.join(\", \")}`);\n }\n if (ungoverned.length === 0) return [];\n return [\n {\n severity: \"warn\",\n code: \"api.response-ungoverned\",\n subject: service,\n message: `${service}: ${ungoverned.length} operation(s) declare a failure response no scenario reaches — write the refusal as a scenario, or as a row in one`,\n details: ungoverned,\n },\n ];\n}\n\nexport function coverageFinding(label: string, reqs: Requirement[]): Finding {\n const missing = requirementsMissingScenarios(reqs);\n if (missing.length === 0) {\n return {\n severity: \"ok\",\n code: \"requirements.covered\",\n message: `${label} covered (${reqs.length} requirement${reqs.length === 1 ? \"\" : \"s\"}, all with scenarios)`,\n };\n }\n return {\n severity: \"error\",\n code: \"requirements.missing-scenarios\",\n message: `${label}: ${missing.length} requirement(s) without a scenario`,\n details: missing.map((r) => r.name),\n text: { detailPrefix: \"- \" },\n };\n}\n"]}
@@ -0,0 +1,76 @@
1
+ import { existsSync } from "node:fs";
2
+ import {} from "../../../core/kernel/ids/service.js";
3
+ import { SPEC_AXES } from "../../../core/repo/paths.js";
4
+ import { locateServicePaths } from "../../../core/repo/service-target.js";
5
+ import { listField, readFrontmatter } from "../../../core/document/frontmatter.js";
6
+ import {} from "../../../core/vocabulary/report.js";
7
+ import { missingSources, patternSources, unsafeSources } from "../../../core/provenance/sources.js";
8
+ import { emptySourcesMessage, expandSourceFiles } from "../../../core/provenance/stamp.js";
9
+ import { UNVERIFIABLE } from "./vocabulary.js";
10
+ /**
11
+ * The two things a `sources` list can be that `serviceProvenance` cannot say.
12
+ *
13
+ * `sources.unverifiable-from-here` — the spec names sources and loam is NOT in
14
+ * that service's repository, so every sources check (existence, digest,
15
+ * staleness) is skipped. serviceProvenance returns an empty list in that case
16
+ * and the silence read as "checked and fine". It used to be counted only under
17
+ * `--all` and printed as one rollup line, which meant `validate --service X`
18
+ * run from the docs repo — the single most common way anyone looks at one
19
+ * service — reported nothing at all about its own blind spot. Severity `ok`,
20
+ * deliberately: nothing is WRONG with the docs, the check simply cannot run
21
+ * here, and grading it a warning would make a fully documented fleet
22
+ * permanently yellow and `--strict` permanently red in the docs repo's CI.
23
+ *
24
+ * `sources.empty` — the paths exist, and expand to no files at all: an empty
25
+ * directory, or a tree the repository itself ignores. A digest over nothing
26
+ * never changes, so the stamp would read as current forever. `loam vouch`
27
+ * already refuses to stamp it; until now `validate` said nothing, so an author
28
+ * got a green run followed by a refusal, two commands contradicting each other
29
+ * about one document. The sentence comes from `emptySourcesMessage`, the same
30
+ * definition vouch refuses with, under the label vouch uses.
31
+ */
32
+ export async function sourceScopeFindings(docsDir, service, repoDir, fleet) {
33
+ const paths = await locateServicePaths(docsDir, service, fleet);
34
+ const out = [];
35
+ // The axis pair is SPEC_AXES', not this function's: `serviceProvenance` grades
36
+ // the same two files from the same list, and a scope check that walked a
37
+ // shorter list than the grading would go quiet on the axis it forgot.
38
+ for (const { path, file } of SPEC_AXES.map((axis) => ({ path: paths[axis.key], file: axis.file }))) {
39
+ if (!existsSync(path))
40
+ continue;
41
+ const sources = listField(await readFrontmatter(path), "sources");
42
+ if (sources.length === 0)
43
+ continue;
44
+ // vouch's own labelling: a bare service id for spec.md, qualified for the
45
+ // arch axis. The refusal and the finding must be the same sentence.
46
+ const label = file === "spec.md" ? service : `${service}: ${file}`;
47
+ if (repoDir === undefined) {
48
+ out.push({
49
+ severity: "ok",
50
+ code: UNVERIFIABLE,
51
+ subject: service,
52
+ message: `${label}: ${sources.length} source(s) declared, but this is not ${service}'s repository — nothing here can resolve them. Run \`loam validate --service ${service}\` from inside it.`,
53
+ });
54
+ continue;
55
+ }
56
+ // Every other shape of broken list is serviceProvenance's to grade, and
57
+ // grading them twice would send an author fixing one thing from two
58
+ // findings. "Covers no files" is only meaningful once the paths are real.
59
+ if (patternSources(sources).length > 0 ||
60
+ unsafeSources(repoDir, sources).length > 0 ||
61
+ missingSources(repoDir, sources).length > 0) {
62
+ continue;
63
+ }
64
+ const expansion = await expandSourceFiles(repoDir, sources, label);
65
+ if (expansion.files.length > 0)
66
+ continue;
67
+ out.push({
68
+ severity: "warn",
69
+ code: "sources.empty",
70
+ subject: service,
71
+ message: expansion.empty ?? emptySourcesMessage(label, sources),
72
+ });
73
+ }
74
+ return out;
75
+ }
76
+ //# sourceMappingURL=sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../../../src/commands/validate/checks/sources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAwB,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAExD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,EAAgB,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpG,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAgB,EAChB,OAAwB,EACxB,OAA2B,EAC3B,KAAoB;IAEpB,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAChE,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,+EAA+E;IAC/E,yEAAyE;IACzE,sEAAsE;IACtE,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QACnG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAChC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;QAClE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACnC,0EAA0E;QAC1E,oEAAoE;QACpE,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,IAAI,EAAE,CAAC;QACnE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,GAAG,CAAC,IAAI,CAAC;gBACP,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,OAAO;gBAChB,OAAO,EAAE,GAAG,KAAK,KAAK,OAAO,CAAC,MAAM,wCAAwC,OAAO,gFAAgF,OAAO,oBAAoB;aAC/L,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,wEAAwE;QACxE,oEAAoE;QACpE,0EAA0E;QAC1E,IACE,cAAc,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;YAClC,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;YAC1C,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAC3C,CAAC;YACD,SAAS;QACX,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QACnE,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QACzC,GAAG,CAAC,IAAI,CAAC;YACP,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE,SAAS,CAAC,KAAK,IAAI,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC;SAChE,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { type PathableService } from \"../../../core/kernel/ids/service.js\";\nimport { SPEC_AXES } from \"../../../core/repo/paths.js\";\nimport type { FleetContext } from \"../../../core/fleet-context.js\";\nimport { locateServicePaths } from \"../../../core/repo/service-target.js\";\nimport { listField, readFrontmatter } from \"../../../core/document/frontmatter.js\";\nimport { type Finding } from \"../../../core/vocabulary/report.js\";\nimport { missingSources, patternSources, unsafeSources } from \"../../../core/provenance/sources.js\";\nimport { emptySourcesMessage, expandSourceFiles } from \"../../../core/provenance/stamp.js\";\nimport { UNVERIFIABLE } from \"./vocabulary.js\";\nimport type { DocsDir } from \"../../../core/kernel/ids/dirs.js\";\n\n/**\n * The two things a `sources` list can be that `serviceProvenance` cannot say.\n *\n * `sources.unverifiable-from-here` — the spec names sources and loam is NOT in\n * that service's repository, so every sources check (existence, digest,\n * staleness) is skipped. serviceProvenance returns an empty list in that case\n * and the silence read as \"checked and fine\". It used to be counted only under\n * `--all` and printed as one rollup line, which meant `validate --service X`\n * run from the docs repo — the single most common way anyone looks at one\n * service — reported nothing at all about its own blind spot. Severity `ok`,\n * deliberately: nothing is WRONG with the docs, the check simply cannot run\n * here, and grading it a warning would make a fully documented fleet\n * permanently yellow and `--strict` permanently red in the docs repo's CI.\n *\n * `sources.empty` — the paths exist, and expand to no files at all: an empty\n * directory, or a tree the repository itself ignores. A digest over nothing\n * never changes, so the stamp would read as current forever. `loam vouch`\n * already refuses to stamp it; until now `validate` said nothing, so an author\n * got a green run followed by a refusal, two commands contradicting each other\n * about one document. The sentence comes from `emptySourcesMessage`, the same\n * definition vouch refuses with, under the label vouch uses.\n */\nexport async function sourceScopeFindings(\n docsDir: DocsDir,\n service: PathableService,\n repoDir: string | undefined,\n fleet?: FleetContext,\n): Promise<Finding[]> {\n const paths = await locateServicePaths(docsDir, service, fleet);\n const out: Finding[] = [];\n // The axis pair is SPEC_AXES', not this function's: `serviceProvenance` grades\n // the same two files from the same list, and a scope check that walked a\n // shorter list than the grading would go quiet on the axis it forgot.\n for (const { path, file } of SPEC_AXES.map((axis) => ({ path: paths[axis.key], file: axis.file }))) {\n if (!existsSync(path)) continue;\n const sources = listField(await readFrontmatter(path), \"sources\");\n if (sources.length === 0) continue;\n // vouch's own labelling: a bare service id for spec.md, qualified for the\n // arch axis. The refusal and the finding must be the same sentence.\n const label = file === \"spec.md\" ? service : `${service}: ${file}`;\n if (repoDir === undefined) {\n out.push({\n severity: \"ok\",\n code: UNVERIFIABLE,\n subject: service,\n message: `${label}: ${sources.length} source(s) declared, but this is not ${service}'s repository — nothing here can resolve them. Run \\`loam validate --service ${service}\\` from inside it.`,\n });\n continue;\n }\n // Every other shape of broken list is serviceProvenance's to grade, and\n // grading them twice would send an author fixing one thing from two\n // findings. \"Covers no files\" is only meaningful once the paths are real.\n if (\n patternSources(sources).length > 0 ||\n unsafeSources(repoDir, sources).length > 0 ||\n missingSources(repoDir, sources).length > 0\n ) {\n continue;\n }\n const expansion = await expandSourceFiles(repoDir, sources, label);\n if (expansion.files.length > 0) continue;\n out.push({\n severity: \"warn\",\n code: \"sources.empty\",\n subject: service,\n message: expansion.empty ?? emptySourcesMessage(label, sources),\n });\n }\n return out;\n}\n"]}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The handful of facts every validate check speaks, and none of them owns.
3
+ *
4
+ * A leaf module rather than a paragraph beside its first caller, because the
5
+ * checks are spread across packages and each of these is read from more than
6
+ * one of them: the dispatcher's rollup and the service target's sources check
7
+ * both name one finding code, and several targets render parser diagnostics
8
+ * the same way. ACTOR_KINDS and EXTERNAL_TAG lived here too, until they
9
+ * reached a third copy (`core/gate/partners.ts`, `core/verify/checklist.ts`);
10
+ * their shared spelling is now `core/vocabulary/maturity.ts`, beside the
11
+ * landscape evidence that asks the same questions.
12
+ */
13
+ import {} from "../../../core/c4/likec4.js";
14
+ /** The one code the rollup line counts; spelled once so the two cannot drift. */
15
+ export const UNVERIFIABLE = "sources.unverifiable-from-here";
16
+ /**
17
+ * One parser diagnostic as a finding's evidence line: `L12:` when the parser
18
+ * knew a line, because that lets a reader open the file at the fault instead of
19
+ * searching for it.
20
+ *
21
+ * Three other modules hand-roll the same ternary (`commands/show.ts`,
22
+ * `commands/delta.ts`, `core/c4/splice/landscape-merge.ts`). All four belong
23
+ * beside `LikeC4Error` in `core/c4/likec4.ts`. That used to be blocked by the
24
+ * file limit — nine lines of headroom — and is not any more: moving the resolver
25
+ * out to `core/c4/resolve/service.ts` left the loader around 100 lines under.
26
+ * The consolidation is now unblocked and simply owed.
27
+ */
28
+ export function errorText(e) {
29
+ return typeof e.line === "number" ? `L${e.line}: ${e.message}` : e.message;
30
+ }
31
+ //# sourceMappingURL=vocabulary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vocabulary.js","sourceRoot":"","sources":["../../../../src/commands/validate/checks/vocabulary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAoB,MAAM,4BAA4B,CAAC;AAE9D,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GAAG,gCAAgC,CAAC;AAE7D;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS,CAAC,CAAc;IACtC,OAAO,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAC7E,CAAC","sourcesContent":["/**\n * The handful of facts every validate check speaks, and none of them owns.\n *\n * A leaf module rather than a paragraph beside its first caller, because the\n * checks are spread across packages and each of these is read from more than\n * one of them: the dispatcher's rollup and the service target's sources check\n * both name one finding code, and several targets render parser diagnostics\n * the same way. ACTOR_KINDS and EXTERNAL_TAG lived here too, until they\n * reached a third copy (`core/gate/partners.ts`, `core/verify/checklist.ts`);\n * their shared spelling is now `core/vocabulary/maturity.ts`, beside the\n * landscape evidence that asks the same questions.\n */\nimport { type LikeC4Error } from \"../../../core/c4/likec4.js\";\n\n/** The one code the rollup line counts; spelled once so the two cannot drift. */\nexport const UNVERIFIABLE = \"sources.unverifiable-from-here\";\n\n/**\n * One parser diagnostic as a finding's evidence line: `L12:` when the parser\n * knew a line, because that lets a reader open the file at the fault instead of\n * searching for it.\n *\n * Three other modules hand-roll the same ternary (`commands/show.ts`,\n * `commands/delta.ts`, `core/c4/splice/landscape-merge.ts`). All four belong\n * beside `LikeC4Error` in `core/c4/likec4.ts`. That used to be blocked by the\n * file limit — nine lines of headroom — and is not any more: moving the resolver\n * out to `core/c4/resolve/service.ts` left the loader around 100 lines under.\n * The consolidation is now unblocked and simply owed.\n */\nexport function errorText(e: LikeC4Error): string {\n return typeof e.line === \"number\" ? `L${e.line}: ${e.message}` : e.message;\n}\n"]}