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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1256) hide show
  1. package/CHANGELOG.md +5992 -82
  2. package/COMPARISON.md +168 -63
  3. package/CONTRIBUTING.md +121 -0
  4. package/MIGRATING-from-OpenSpec.md +238 -55
  5. package/QUICKSTART.md +302 -0
  6. package/README.md +653 -144
  7. package/ROADMAP.md +1035 -0
  8. package/SCHEMA.md +3916 -263
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +927 -0
  11. package/dist/cli.js +133 -21
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +204 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +309 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +74 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/closing.js +42 -0
  20. package/dist/commands/archive/closing.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
  22. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  23. package/dist/commands/archive/plan/contracts/consumers.js +56 -0
  24. package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
  25. package/dist/commands/archive/plan/contracts/openapi.js +193 -0
  26. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  27. package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
  28. package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
  29. package/dist/commands/archive/plan/document/head.js +151 -0
  30. package/dist/commands/archive/plan/document/head.js.map +1 -0
  31. package/dist/commands/archive/plan/document/links.js +284 -0
  32. package/dist/commands/archive/plan/document/links.js.map +1 -0
  33. package/dist/commands/archive/plan/document/run.js +136 -0
  34. package/dist/commands/archive/plan/document/run.js.map +1 -0
  35. package/dist/commands/archive/plan/gate.js +319 -0
  36. package/dist/commands/archive/plan/gate.js.map +1 -0
  37. package/dist/commands/archive/plan/landscape.js +298 -0
  38. package/dist/commands/archive/plan/landscape.js.map +1 -0
  39. package/dist/commands/archive/plan/model/extending.js +85 -0
  40. package/dist/commands/archive/plan/model/extending.js.map +1 -0
  41. package/dist/commands/archive/plan/refusal.js +106 -0
  42. package/dist/commands/archive/plan/refusal.js.map +1 -0
  43. package/dist/commands/archive/plan/specs.js +318 -0
  44. package/dist/commands/archive/plan/specs.js.map +1 -0
  45. package/dist/commands/archive/plan/state.js +30 -0
  46. package/dist/commands/archive/plan/state.js.map +1 -0
  47. package/dist/commands/archive/run.js +355 -0
  48. package/dist/commands/archive/run.js.map +1 -0
  49. package/dist/commands/archive/shipped.js +49 -0
  50. package/dist/commands/archive/shipped.js.map +1 -0
  51. package/dist/commands/context/context.js +166 -0
  52. package/dist/commands/context/context.js.map +1 -0
  53. package/dist/commands/context/print.js +305 -0
  54. package/dist/commands/context/print.js.map +1 -0
  55. package/dist/commands/delta/delta.js +367 -0
  56. package/dist/commands/delta/delta.js.map +1 -0
  57. package/dist/commands/delta/print.js +221 -0
  58. package/dist/commands/delta/print.js.map +1 -0
  59. package/dist/commands/dependencies.js +6 -8
  60. package/dist/commands/dependencies.js.map +1 -1
  61. package/dist/commands/diff/diff.js +86 -0
  62. package/dist/commands/diff/diff.js.map +1 -0
  63. package/dist/commands/diff/print.js +38 -0
  64. package/dist/commands/diff/print.js.map +1 -0
  65. package/dist/commands/doctor.js +65 -5
  66. package/dist/commands/doctor.js.map +1 -1
  67. package/dist/commands/explain/explain.js +227 -0
  68. package/dist/commands/explain/explain.js.map +1 -0
  69. package/dist/commands/explore.js +39 -28
  70. package/dist/commands/explore.js.map +1 -1
  71. package/dist/commands/gate/gate.js +152 -0
  72. package/dist/commands/gate/gate.js.map +1 -0
  73. package/dist/commands/gate/print.js +66 -0
  74. package/dist/commands/gate/print.js.map +1 -0
  75. package/dist/commands/gherkin/commit.js +105 -0
  76. package/dist/commands/gherkin/commit.js.map +1 -0
  77. package/dist/commands/gherkin/gherkin.js +262 -0
  78. package/dist/commands/gherkin/gherkin.js.map +1 -0
  79. package/dist/commands/gherkin/reconcile.js +146 -0
  80. package/dist/commands/gherkin/reconcile.js.map +1 -0
  81. package/dist/commands/gherkin/render.js +77 -0
  82. package/dist/commands/gherkin/render.js.map +1 -0
  83. package/dist/commands/init/example.js +204 -0
  84. package/dist/commands/init/example.js.map +1 -0
  85. package/dist/commands/init/first-hour.js +72 -0
  86. package/dist/commands/init/first-hour.js.map +1 -0
  87. package/dist/commands/{init.js → init/init.js} +142 -71
  88. package/dist/commands/init/init.js.map +1 -0
  89. package/dist/commands/init/mcp.js +131 -0
  90. package/dist/commands/init/mcp.js.map +1 -0
  91. package/dist/commands/init/options.js +78 -0
  92. package/dist/commands/init/options.js.map +1 -0
  93. package/dist/commands/instructions.js +72 -14
  94. package/dist/commands/instructions.js.map +1 -1
  95. package/dist/commands/list/campaign/campaign.js +63 -0
  96. package/dist/commands/list/campaign/campaign.js.map +1 -0
  97. package/dist/commands/list/campaign/owners.js +65 -0
  98. package/dist/commands/list/campaign/owners.js.map +1 -0
  99. package/dist/commands/list/json.js +155 -0
  100. package/dist/commands/list/json.js.map +1 -0
  101. package/dist/commands/list/list.js +358 -0
  102. package/dist/commands/list/list.js.map +1 -0
  103. package/dist/commands/list/print.js +344 -0
  104. package/dist/commands/list/print.js.map +1 -0
  105. package/dist/commands/list/review.js +120 -0
  106. package/dist/commands/list/review.js.map +1 -0
  107. package/dist/commands/list/suites/suites.js +140 -0
  108. package/dist/commands/list/suites/suites.js.map +1 -0
  109. package/dist/commands/list/views.js +108 -0
  110. package/dist/commands/list/views.js.map +1 -0
  111. package/dist/commands/mcp/dispatch.js +238 -0
  112. package/dist/commands/mcp/dispatch.js.map +1 -0
  113. package/dist/commands/mcp/mcp.js +75 -0
  114. package/dist/commands/mcp/mcp.js.map +1 -0
  115. package/dist/commands/mcp/serve.js +55 -0
  116. package/dist/commands/mcp/serve.js.map +1 -0
  117. package/dist/commands/migrate-openspec/materialize/active.js +175 -0
  118. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  119. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  120. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  121. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  122. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  123. package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
  124. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  125. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  126. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  127. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  128. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  129. package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
  130. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  131. package/dist/commands/migrate-openspec/openspec/error.js +18 -0
  132. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  133. package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
  134. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  135. package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
  136. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  137. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  138. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  139. package/dist/commands/migrate-openspec/print.js +89 -0
  140. package/dist/commands/migrate-openspec/print.js.map +1 -0
  141. package/dist/commands/new/capability-template.js +118 -0
  142. package/dist/commands/new/capability-template.js.map +1 -0
  143. package/dist/commands/new/commit.js +62 -0
  144. package/dist/commands/new/commit.js.map +1 -0
  145. package/dist/commands/new/modifies.js +206 -0
  146. package/dist/commands/new/modifies.js.map +1 -0
  147. package/dist/commands/new/new.js +328 -0
  148. package/dist/commands/new/new.js.map +1 -0
  149. package/dist/commands/new/templates.js +279 -0
  150. package/dist/commands/new/templates.js.map +1 -0
  151. package/dist/commands/open.js +199 -0
  152. package/dist/commands/open.js.map +1 -0
  153. package/dist/commands/policy/format.js +152 -0
  154. package/dist/commands/policy/format.js.map +1 -0
  155. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
  156. package/dist/commands/policy/gate.js.map +1 -0
  157. package/dist/commands/rebase/edit.js +106 -0
  158. package/dist/commands/rebase/edit.js.map +1 -0
  159. package/dist/commands/rebase/living.js +185 -0
  160. package/dist/commands/rebase/living.js.map +1 -0
  161. package/dist/commands/rebase/plan.js +245 -0
  162. package/dist/commands/rebase/plan.js.map +1 -0
  163. package/dist/commands/rebase/rebase.js +300 -0
  164. package/dist/commands/rebase/rebase.js.map +1 -0
  165. package/dist/commands/seed/commit.js +221 -0
  166. package/dist/commands/seed/commit.js.map +1 -0
  167. package/dist/commands/seed/plan.js +278 -0
  168. package/dist/commands/seed/plan.js.map +1 -0
  169. package/dist/commands/seed/seed.js +174 -0
  170. package/dist/commands/seed/seed.js.map +1 -0
  171. package/dist/commands/show/feature.js +182 -0
  172. package/dist/commands/show/feature.js.map +1 -0
  173. package/dist/commands/show/introduced.js +157 -0
  174. package/dist/commands/show/introduced.js.map +1 -0
  175. package/dist/commands/show/marks.js +53 -0
  176. package/dist/commands/show/marks.js.map +1 -0
  177. package/dist/commands/show/service.js +239 -0
  178. package/dist/commands/show/service.js.map +1 -0
  179. package/dist/commands/show/show.js +87 -0
  180. package/dist/commands/show/show.js.map +1 -0
  181. package/dist/commands/status/fleet-next.js +90 -0
  182. package/dist/commands/status/fleet-next.js.map +1 -0
  183. package/dist/commands/status/json.js +47 -0
  184. package/dist/commands/status/json.js.map +1 -0
  185. package/dist/commands/status/print.js +209 -0
  186. package/dist/commands/status/print.js.map +1 -0
  187. package/dist/commands/status/status.js +115 -0
  188. package/dist/commands/status/status.js.map +1 -0
  189. package/dist/commands/steps/steps.js +269 -0
  190. package/dist/commands/steps/steps.js.map +1 -0
  191. package/dist/commands/subsystem/edit.js +192 -0
  192. package/dist/commands/subsystem/edit.js.map +1 -0
  193. package/dist/commands/subsystem/move.js +325 -0
  194. package/dist/commands/subsystem/move.js.map +1 -0
  195. package/dist/commands/subsystem/query.js +113 -0
  196. package/dist/commands/subsystem/query.js.map +1 -0
  197. package/dist/commands/subsystem/subsystem.js +98 -0
  198. package/dist/commands/subsystem/subsystem.js.map +1 -0
  199. package/dist/commands/subsystem/sync.js +318 -0
  200. package/dist/commands/subsystem/sync.js.map +1 -0
  201. package/dist/commands/subsystem/txn/exclude.js +132 -0
  202. package/dist/commands/subsystem/txn/exclude.js.map +1 -0
  203. package/dist/commands/subsystem/txn/links.js +128 -0
  204. package/dist/commands/subsystem/txn/links.js.map +1 -0
  205. package/dist/commands/subsystem/txn/report.js +174 -0
  206. package/dist/commands/subsystem/txn/report.js.map +1 -0
  207. package/dist/commands/subsystem/txn/txn.js +196 -0
  208. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  209. package/dist/commands/subsystem/txn/views.js +249 -0
  210. package/dist/commands/subsystem/txn/views.js.map +1 -0
  211. package/dist/commands/tasks/actions.js +107 -0
  212. package/dist/commands/tasks/actions.js.map +1 -0
  213. package/dist/commands/tasks/render.js +253 -0
  214. package/dist/commands/tasks/render.js.map +1 -0
  215. package/dist/commands/tasks/tasks.js +119 -0
  216. package/dist/commands/tasks/tasks.js.map +1 -0
  217. package/dist/commands/unarchive/manifest.js +176 -0
  218. package/dist/commands/unarchive/manifest.js.map +1 -0
  219. package/dist/commands/unarchive/restore.js +254 -0
  220. package/dist/commands/unarchive/restore.js.map +1 -0
  221. package/dist/commands/unarchive/unarchive.js +59 -0
  222. package/dist/commands/unarchive/unarchive.js.map +1 -0
  223. package/dist/commands/validate/arch-coverage.js +245 -0
  224. package/dist/commands/validate/arch-coverage.js.map +1 -0
  225. package/dist/commands/validate/checks/fleet-shape.js +204 -0
  226. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  227. package/dist/commands/validate/checks/health-deps.js +58 -0
  228. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  229. package/dist/commands/validate/checks/introduced.js +102 -0
  230. package/dist/commands/validate/checks/introduced.js.map +1 -0
  231. package/dist/commands/validate/checks/requirements.js +264 -0
  232. package/dist/commands/validate/checks/requirements.js.map +1 -0
  233. package/dist/commands/validate/checks/sources.js +85 -0
  234. package/dist/commands/validate/checks/sources.js.map +1 -0
  235. package/dist/commands/validate/coverage/covers-after.js +105 -0
  236. package/dist/commands/validate/coverage/covers-after.js.map +1 -0
  237. package/dist/commands/validate/feature.js +222 -0
  238. package/dist/commands/validate/feature.js.map +1 -0
  239. package/dist/commands/validate/fleet/census.js +93 -0
  240. package/dist/commands/validate/fleet/census.js.map +1 -0
  241. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  242. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  243. package/dist/commands/validate/fleet/landscape.js +371 -0
  244. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  245. package/dist/commands/validate/fleet/load.js +118 -0
  246. package/dist/commands/validate/fleet/load.js.map +1 -0
  247. package/dist/commands/validate/fleet/map/attest.js +98 -0
  248. package/dist/commands/validate/fleet/map/attest.js.map +1 -0
  249. package/dist/commands/validate/fleet/map/bindings.js +107 -0
  250. package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
  251. package/dist/commands/validate/fleet/map/consumers.js +244 -0
  252. package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
  253. package/dist/commands/validate/fleet/map/isolation.js +116 -0
  254. package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
  255. package/dist/commands/validate/fleet/map/usecases.js +54 -0
  256. package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
  257. package/dist/commands/validate/fleet/obligations.js +266 -0
  258. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  259. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  260. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  261. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  262. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  263. package/dist/commands/validate/fleet/scorecard/print.js +71 -0
  264. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  265. package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
  266. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  267. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  268. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  269. package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
  270. package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
  271. package/dist/commands/validate/fleet/views/ids.js +75 -0
  272. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  273. package/dist/commands/validate/fleet/views/projects.js +278 -0
  274. package/dist/commands/validate/fleet/views/projects.js.map +1 -0
  275. package/dist/commands/validate/fleet/views/root-documents.js +83 -0
  276. package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
  277. package/dist/commands/validate/fleet/views/stale.js +52 -0
  278. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  279. package/dist/commands/validate/links/corpus.js +89 -0
  280. package/dist/commands/validate/links/corpus.js.map +1 -0
  281. package/dist/commands/validate/links/glossary.js +75 -0
  282. package/dist/commands/validate/links/glossary.js.map +1 -0
  283. package/dist/commands/validate/render/repeats.js +63 -0
  284. package/dist/commands/validate/render/repeats.js.map +1 -0
  285. package/dist/commands/validate/render/rollups.js +115 -0
  286. package/dist/commands/validate/render/rollups.js.map +1 -0
  287. package/dist/commands/validate/render/text.js +199 -0
  288. package/dist/commands/validate/render/text.js.map +1 -0
  289. package/dist/commands/validate/report.js +145 -0
  290. package/dist/commands/validate/report.js.map +1 -0
  291. package/dist/commands/validate/scope.js +113 -0
  292. package/dist/commands/validate/scope.js.map +1 -0
  293. package/dist/commands/validate/service/api.js +252 -0
  294. package/dist/commands/validate/service/api.js.map +1 -0
  295. package/dist/commands/validate/service/contracts/generated.js +134 -0
  296. package/dist/commands/validate/service/contracts/generated.js.map +1 -0
  297. package/dist/commands/validate/service/events/events.js +241 -0
  298. package/dist/commands/validate/service/events/events.js.map +1 -0
  299. package/dist/commands/validate/service/events/message-producers.js +77 -0
  300. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  301. package/dist/commands/validate/service/evidence-pins.js +177 -0
  302. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  303. package/dist/commands/validate/service/model/diverged.js +226 -0
  304. package/dist/commands/validate/service/model/diverged.js.map +1 -0
  305. package/dist/commands/validate/service/model/grade.js +163 -0
  306. package/dist/commands/validate/service/model/grade.js.map +1 -0
  307. package/dist/commands/validate/service/service.js +310 -0
  308. package/dist/commands/validate/service/service.js.map +1 -0
  309. package/dist/commands/validate/service/specs.js +279 -0
  310. package/dist/commands/validate/service/specs.js.map +1 -0
  311. package/dist/commands/validate/service/spine.js +148 -0
  312. package/dist/commands/validate/service/spine.js.map +1 -0
  313. package/dist/commands/validate/service/usecases/tags.js +113 -0
  314. package/dist/commands/validate/service/usecases/tags.js.map +1 -0
  315. package/dist/commands/validate/service/usecases/usecases.js +209 -0
  316. package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
  317. package/dist/commands/validate/validate.js +363 -0
  318. package/dist/commands/validate/validate.js.map +1 -0
  319. package/dist/commands/verify/cross/diff.js +178 -0
  320. package/dist/commands/verify/cross/diff.js.map +1 -0
  321. package/dist/commands/verify/evidence/contract.js +32 -0
  322. package/dist/commands/verify/evidence/contract.js.map +1 -0
  323. package/dist/commands/verify/evidence/pins.js +52 -0
  324. package/dist/commands/verify/evidence/pins.js.map +1 -0
  325. package/dist/commands/verify/evidence/read.js +81 -0
  326. package/dist/commands/verify/evidence/read.js.map +1 -0
  327. package/dist/commands/verify/frozen.js +263 -0
  328. package/dist/commands/verify/frozen.js.map +1 -0
  329. package/dist/commands/verify/record.js +278 -0
  330. package/dist/commands/verify/record.js.map +1 -0
  331. package/dist/commands/verify/report.js +206 -0
  332. package/dist/commands/verify/report.js.map +1 -0
  333. package/dist/commands/verify/results.js +328 -0
  334. package/dist/commands/verify/results.js.map +1 -0
  335. package/dist/commands/verify/verify.js +220 -0
  336. package/dist/commands/verify/verify.js.map +1 -0
  337. package/dist/commands/vouch/contract.js +11 -0
  338. package/dist/commands/vouch/contract.js.map +1 -0
  339. package/dist/commands/vouch/pack/contract.js +2 -0
  340. package/dist/commands/vouch/pack/contract.js.map +1 -0
  341. package/dist/commands/vouch/pack/pack.js +266 -0
  342. package/dist/commands/vouch/pack/pack.js.map +1 -0
  343. package/dist/commands/vouch/pack/print.js +266 -0
  344. package/dist/commands/vouch/pack/print.js.map +1 -0
  345. package/dist/commands/vouch/pack/sections.js +141 -0
  346. package/dist/commands/vouch/pack/sections.js.map +1 -0
  347. package/dist/commands/vouch/prompt/confirm.js +46 -0
  348. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  349. package/dist/commands/vouch/report.js +101 -0
  350. package/dist/commands/vouch/report.js.map +1 -0
  351. package/dist/commands/vouch/run.js +230 -0
  352. package/dist/commands/vouch/run.js.map +1 -0
  353. package/dist/commands/vouch/sample/plan.js +111 -0
  354. package/dist/commands/vouch/sample/plan.js.map +1 -0
  355. package/dist/commands/vouch/sample/print.js +109 -0
  356. package/dist/commands/vouch/sample/print.js.map +1 -0
  357. package/dist/commands/vouch/vet/verify.js +155 -0
  358. package/dist/commands/vouch/vet/verify.js.map +1 -0
  359. package/dist/commands/vouch/vouch.js +169 -0
  360. package/dist/commands/vouch/vouch.js.map +1 -0
  361. package/dist/core/agent/agents-md/command-map.js +299 -0
  362. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  363. package/dist/core/agent/agents-md/map/explain.js +46 -0
  364. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  365. package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
  366. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  367. package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
  368. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  369. package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
  370. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  371. package/dist/core/agent/agents-md/map/mcp.js +44 -0
  372. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  373. package/dist/core/agent/agents-md/map/status.js +78 -0
  374. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  375. package/dist/core/agent/agents-md/map/subsystem.js +104 -0
  376. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  377. package/dist/core/agent/agents-md/map/usecases.js +138 -0
  378. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  379. package/dist/core/agent/agents-md/refusals.js +273 -0
  380. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  381. package/dist/core/agent/agents-md.js +203 -0
  382. package/dist/core/agent/agents-md.js.map +1 -0
  383. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
  384. package/dist/core/agent/agents-stamp.js.map +1 -0
  385. package/dist/core/agent/contract.js +2 -0
  386. package/dist/core/agent/contract.js.map +1 -0
  387. package/dist/core/agent/protocol.js +193 -0
  388. package/dist/core/agent/protocol.js.map +1 -0
  389. package/dist/core/agent/scaffold.js +254 -0
  390. package/dist/core/agent/scaffold.js.map +1 -0
  391. package/dist/core/agent/support/report.js +144 -0
  392. package/dist/core/agent/support/report.js.map +1 -0
  393. package/dist/core/agent/tools/dialects.js +151 -0
  394. package/dist/core/agent/tools/dialects.js.map +1 -0
  395. package/dist/core/agent/tools/registry.js +193 -0
  396. package/dist/core/agent/tools/registry.js.map +1 -0
  397. package/dist/core/agent/workflows/adopt.js +280 -0
  398. package/dist/core/agent/workflows/adopt.js.map +1 -0
  399. package/dist/core/agent/workflows/check.js +373 -0
  400. package/dist/core/agent/workflows/check.js.map +1 -0
  401. package/dist/core/agent/workflows/closing.js +323 -0
  402. package/dist/core/agent/workflows/closing.js.map +1 -0
  403. package/dist/core/agent/workflows/feature.js +220 -0
  404. package/dist/core/agent/workflows/feature.js.map +1 -0
  405. package/dist/core/agent/workflows/implement.js +188 -0
  406. package/dist/core/agent/workflows/implement.js.map +1 -0
  407. package/dist/core/agent/workflows/reference/authoring.js +311 -0
  408. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  409. package/dist/core/agent/workflows/reference/codes.js +67 -0
  410. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  411. package/dist/core/agent/workflows/reference/done-check.js +210 -0
  412. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  413. package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
  414. package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
  415. package/dist/core/agent/workflows/reference/reference.js +19 -0
  416. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  417. package/dist/core/agent/workflows/reference/spine.js +338 -0
  418. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  419. package/dist/core/asyncapi/baseline/plan.js +43 -0
  420. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  421. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  422. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  423. package/dist/core/asyncapi/depth.js +164 -0
  424. package/dist/core/asyncapi/depth.js.map +1 -0
  425. package/dist/core/asyncapi/digest.js +146 -0
  426. package/dist/core/asyncapi/digest.js.map +1 -0
  427. package/dist/core/asyncapi/merge/components.js +92 -0
  428. package/dist/core/asyncapi/merge/components.js.map +1 -0
  429. package/dist/core/asyncapi/merge/error.js +38 -0
  430. package/dist/core/asyncapi/merge/error.js.map +1 -0
  431. package/dist/core/asyncapi/merge/markers.js +290 -0
  432. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  433. package/dist/core/asyncapi/merge/merge.js +195 -0
  434. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  435. package/dist/core/asyncapi/merge/pin.js +83 -0
  436. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  437. package/dist/core/asyncapi/model.js +11 -0
  438. package/dist/core/asyncapi/model.js.map +1 -0
  439. package/dist/core/asyncapi/producers.js +50 -0
  440. package/dist/core/asyncapi/producers.js.map +1 -0
  441. package/dist/core/asyncapi/read.js +263 -0
  442. package/dist/core/asyncapi/read.js.map +1 -0
  443. package/dist/core/brief/brief.js +285 -0
  444. package/dist/core/brief/brief.js.map +1 -0
  445. package/dist/core/brief/checks.js +385 -0
  446. package/dist/core/brief/checks.js.map +1 -0
  447. package/dist/core/brief/landscape.js +273 -0
  448. package/dist/core/brief/landscape.js.map +1 -0
  449. package/dist/core/brief/map/extend.js +84 -0
  450. package/dist/core/brief/map/extend.js.map +1 -0
  451. package/dist/core/brief/map/owed.js +266 -0
  452. package/dist/core/brief/map/owed.js.map +1 -0
  453. package/dist/core/brief/targets.js +304 -0
  454. package/dist/core/brief/targets.js.map +1 -0
  455. package/dist/core/brief/unchecked.js +58 -0
  456. package/dist/core/brief/unchecked.js.map +1 -0
  457. package/dist/core/c4/arch.js +190 -0
  458. package/dist/core/c4/arch.js.map +1 -0
  459. package/dist/core/c4/direction/direction.js +114 -0
  460. package/dist/core/c4/direction/direction.js.map +1 -0
  461. package/dist/core/c4/likec4.js +243 -0
  462. package/dist/core/c4/likec4.js.map +1 -0
  463. package/dist/core/c4/locate/unlocated.js +150 -0
  464. package/dist/core/c4/locate/unlocated.js.map +1 -0
  465. package/dist/core/c4/parsed/deployment.js +160 -0
  466. package/dist/core/c4/parsed/deployment.js.map +1 -0
  467. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  468. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  469. package/dist/core/c4/parsed/specification.js +78 -0
  470. package/dist/core/c4/parsed/specification.js.map +1 -0
  471. package/dist/core/c4/parsed/values.js +110 -0
  472. package/dist/core/c4/parsed/values.js.map +1 -0
  473. package/dist/core/c4/parsed/view-ids.js +113 -0
  474. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  475. package/dist/core/c4/prefetch/fleet.js +134 -0
  476. package/dist/core/c4/prefetch/fleet.js.map +1 -0
  477. package/dist/core/c4/project/architecture.js +161 -0
  478. package/dist/core/c4/project/architecture.js.map +1 -0
  479. package/dist/core/c4/project/batch.js +140 -0
  480. package/dist/core/c4/project/batch.js.map +1 -0
  481. package/dist/core/c4/project/documents.js +89 -0
  482. package/dist/core/c4/project/documents.js.map +1 -0
  483. package/dist/core/c4/project/load.js +219 -0
  484. package/dist/core/c4/project/load.js.map +1 -0
  485. package/dist/core/c4/project/staged.js +277 -0
  486. package/dist/core/c4/project/staged.js.map +1 -0
  487. package/dist/core/c4/resolve/attested.js +0 -0
  488. package/dist/core/c4/resolve/attested.js.map +1 -0
  489. package/dist/core/c4/resolve/external.js +51 -0
  490. package/dist/core/c4/resolve/external.js.map +1 -0
  491. package/dist/core/c4/resolve/service.js +174 -0
  492. package/dist/core/c4/resolve/service.js.map +1 -0
  493. package/dist/core/c4/resolve/steps.js +290 -0
  494. package/dist/core/c4/resolve/steps.js.map +1 -0
  495. package/dist/core/c4/resolve/systems.js +154 -0
  496. package/dist/core/c4/resolve/systems.js.map +1 -0
  497. package/dist/core/c4/root-project/exclude.js +352 -0
  498. package/dist/core/c4/root-project/exclude.js.map +1 -0
  499. package/dist/core/c4/seed/fleet-file.js +201 -0
  500. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  501. package/dist/core/c4/seed/items.js +91 -0
  502. package/dist/core/c4/seed/items.js.map +1 -0
  503. package/dist/core/c4/seed/stamp.js +48 -0
  504. package/dist/core/c4/seed/stamp.js.map +1 -0
  505. package/dist/core/c4/seed/template.js +173 -0
  506. package/dist/core/c4/seed/template.js.map +1 -0
  507. package/dist/core/c4/service-model/created/models.js +96 -0
  508. package/dist/core/c4/service-model/created/models.js.map +1 -0
  509. package/dist/core/c4/service-model/documents.js +47 -0
  510. package/dist/core/c4/service-model/documents.js.map +1 -0
  511. package/dist/core/c4/service-model/fleet/extending.js +82 -0
  512. package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
  513. package/dist/core/c4/service-model/load.js +165 -0
  514. package/dist/core/c4/service-model/load.js.map +1 -0
  515. package/dist/core/c4/service-model/renderer.js +128 -0
  516. package/dist/core/c4/service-model/renderer.js.map +1 -0
  517. package/dist/core/c4/service-model/shape.js +106 -0
  518. package/dist/core/c4/service-model/shape.js.map +1 -0
  519. package/dist/core/c4/service-model/slice.js +188 -0
  520. package/dist/core/c4/service-model/slice.js.map +1 -0
  521. package/dist/core/c4/source-mask.js +369 -0
  522. package/dist/core/c4/source-mask.js.map +1 -0
  523. package/dist/core/c4/source-scan.js +308 -0
  524. package/dist/core/c4/source-scan.js.map +1 -0
  525. package/dist/core/c4/splice/authored-source.js +167 -0
  526. package/dist/core/c4/splice/authored-source.js.map +1 -0
  527. package/dist/core/c4/splice/contract.js +30 -0
  528. package/dist/core/c4/splice/contract.js.map +1 -0
  529. package/dist/core/c4/splice/delta-blocks.js +126 -0
  530. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  531. package/dist/core/c4/splice/identity/declared.js +87 -0
  532. package/dist/core/c4/splice/identity/declared.js.map +1 -0
  533. package/dist/core/c4/splice/identity/edges.js +73 -0
  534. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  535. package/dist/core/c4/splice/identity/existing.js +80 -0
  536. package/dist/core/c4/splice/identity/existing.js.map +1 -0
  537. package/dist/core/c4/splice/identity/interior.js +80 -0
  538. package/dist/core/c4/splice/identity/interior.js.map +1 -0
  539. package/dist/core/c4/splice/identity/owner.js +50 -0
  540. package/dist/core/c4/splice/identity/owner.js.map +1 -0
  541. package/dist/core/c4/splice/landscape-merge.js +337 -0
  542. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  543. package/dist/core/c4/splice/model/merge.js +151 -0
  544. package/dist/core/c4/splice/model/merge.js.map +1 -0
  545. package/dist/core/c4/splice/placement.js +298 -0
  546. package/dist/core/c4/splice/placement.js.map +1 -0
  547. package/dist/core/c4/splice/text/spot.js +131 -0
  548. package/dist/core/c4/splice/text/spot.js.map +1 -0
  549. package/dist/core/c4/workspace.js +166 -0
  550. package/dist/core/c4/workspace.js.map +1 -0
  551. package/dist/core/capabilities/authoring/notes.js +141 -0
  552. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  553. package/dist/core/capabilities/capabilities.js +124 -0
  554. package/dist/core/capabilities/capabilities.js.map +1 -0
  555. package/dist/core/capabilities/delta/doc.js +47 -0
  556. package/dist/core/capabilities/delta/doc.js.map +1 -0
  557. package/dist/core/capabilities/delta/overlay.js +129 -0
  558. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  559. package/dist/core/capabilities/delta/summary.js +57 -0
  560. package/dist/core/capabilities/delta/summary.js.map +1 -0
  561. package/dist/core/capabilities/delta/tree.js +43 -0
  562. package/dist/core/capabilities/delta/tree.js.map +1 -0
  563. package/dist/core/capabilities/delta/uncovered.js +222 -0
  564. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  565. package/dist/core/capabilities/findings.js +338 -0
  566. package/dist/core/capabilities/findings.js.map +1 -0
  567. package/dist/core/capabilities/realizes/findings.js +174 -0
  568. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  569. package/dist/core/capabilities/realizes/join.js +123 -0
  570. package/dist/core/capabilities/realizes/join.js.map +1 -0
  571. package/dist/core/capabilities/rollup.js +205 -0
  572. package/dist/core/capabilities/rollup.js.map +1 -0
  573. package/dist/core/capabilities/tree.js +104 -0
  574. package/dist/core/capabilities/tree.js.map +1 -0
  575. package/dist/core/capabilities/usecase-join.js +267 -0
  576. package/dist/core/capabilities/usecase-join.js.map +1 -0
  577. package/dist/core/coherence/authoring/scaffold.js +185 -0
  578. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  579. package/dist/core/coherence/authoring/sentinels.js +75 -0
  580. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  581. package/dist/core/coherence/calls/called.js +52 -0
  582. package/dist/core/coherence/calls/called.js.map +1 -0
  583. package/dist/core/coherence/coherence.js +332 -0
  584. package/dist/core/coherence/coherence.js.map +1 -0
  585. package/dist/core/coherence/consumed/operations.js +70 -0
  586. package/dist/core/coherence/consumed/operations.js.map +1 -0
  587. package/dist/core/coherence/consumed/refusal.js +38 -0
  588. package/dist/core/coherence/consumed/refusal.js.map +1 -0
  589. package/dist/core/coherence/covers/health.js +85 -0
  590. package/dist/core/coherence/covers/health.js.map +1 -0
  591. package/dist/core/coherence/declared.js +295 -0
  592. package/dist/core/coherence/declared.js.map +1 -0
  593. package/dist/core/coherence/events/declared.js +191 -0
  594. package/dist/core/coherence/events/declared.js.map +1 -0
  595. package/dist/core/coherence/events/events.js +335 -0
  596. package/dist/core/coherence/events/events.js.map +1 -0
  597. package/dist/core/coherence/events/grades.js +189 -0
  598. package/dist/core/coherence/events/grades.js.map +1 -0
  599. package/dist/core/coherence/events/lookups.js +63 -0
  600. package/dist/core/coherence/events/lookups.js.map +1 -0
  601. package/dist/core/coherence/events/produced.js +100 -0
  602. package/dist/core/coherence/events/produced.js.map +1 -0
  603. package/dist/core/coherence/living.js +198 -0
  604. package/dist/core/coherence/living.js.map +1 -0
  605. package/dist/core/coherence/lookups.js +95 -0
  606. package/dist/core/coherence/lookups.js.map +1 -0
  607. package/dist/core/coherence/pending.js +39 -0
  608. package/dist/core/coherence/pending.js.map +1 -0
  609. package/dist/core/coherence/retired/archived.js +285 -0
  610. package/dist/core/coherence/retired/archived.js.map +1 -0
  611. package/dist/core/coherence/retired/event-pair.js +62 -0
  612. package/dist/core/coherence/retired/event-pair.js.map +1 -0
  613. package/dist/core/coherence/retired/merged.js +79 -0
  614. package/dist/core/coherence/retired/merged.js.map +1 -0
  615. package/dist/core/coherence/retired/retirement.js +49 -0
  616. package/dist/core/coherence/retired/retirement.js.map +1 -0
  617. package/dist/core/coherence/retired/revival/arrivals.js +131 -0
  618. package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
  619. package/dist/core/coherence/retired/revival/revived.js +297 -0
  620. package/dist/core/coherence/retired/revival/revived.js.map +1 -0
  621. package/dist/core/conflict-markers.js +60 -0
  622. package/dist/core/conflict-markers.js.map +1 -0
  623. package/dist/core/consumers/after.js +113 -0
  624. package/dist/core/consumers/after.js.map +1 -0
  625. package/dist/core/consumers/consumers.js +296 -0
  626. package/dist/core/consumers/consumers.js.map +1 -0
  627. package/dist/core/consumers/current.js +211 -0
  628. package/dist/core/consumers/current.js.map +1 -0
  629. package/dist/core/consumers/scan.js +46 -0
  630. package/dist/core/consumers/scan.js.map +1 -0
  631. package/dist/core/consumers/state.js +27 -0
  632. package/dist/core/consumers/state.js.map +1 -0
  633. package/dist/core/delta/claims.js +73 -0
  634. package/dist/core/delta/claims.js.map +1 -0
  635. package/dist/core/delta/delta.js +341 -0
  636. package/dist/core/delta/delta.js.map +1 -0
  637. package/dist/core/delta/document.js +177 -0
  638. package/dist/core/delta/document.js.map +1 -0
  639. package/dist/core/delta/scope.js +48 -0
  640. package/dist/core/delta/scope.js.map +1 -0
  641. package/dist/core/delta/select.js +237 -0
  642. package/dist/core/delta/select.js.map +1 -0
  643. package/dist/core/dependencies/dependencies.js +141 -0
  644. package/dist/core/dependencies/dependencies.js.map +1 -0
  645. package/dist/core/dependencies/facts.js +165 -0
  646. package/dist/core/dependencies/facts.js.map +1 -0
  647. package/dist/core/dependencies/fanin.js +88 -0
  648. package/dist/core/dependencies/fanin.js.map +1 -0
  649. package/dist/core/dependencies/graph.js +106 -0
  650. package/dist/core/dependencies/graph.js.map +1 -0
  651. package/dist/core/deployment/delta.js +191 -0
  652. package/dist/core/deployment/delta.js.map +1 -0
  653. package/dist/core/deployment/objects.js +145 -0
  654. package/dist/core/deployment/objects.js.map +1 -0
  655. package/dist/core/diff/base-git.js +230 -0
  656. package/dist/core/diff/base-git.js.map +1 -0
  657. package/dist/core/diff/base-state.js +237 -0
  658. package/dist/core/diff/base-state.js.map +1 -0
  659. package/dist/core/diff/joins.js +136 -0
  660. package/dist/core/diff/joins.js.map +1 -0
  661. package/dist/core/diff/scope/changed-paths.js +204 -0
  662. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  663. package/dist/core/diff/scope/edges.js +82 -0
  664. package/dist/core/diff/scope/edges.js.map +1 -0
  665. package/dist/core/diff/semantic.js +312 -0
  666. package/dist/core/diff/semantic.js.map +1 -0
  667. package/dist/core/docs.js +37 -85
  668. package/dist/core/docs.js.map +1 -1
  669. package/dist/core/doctor/agents.js +238 -0
  670. package/dist/core/doctor/agents.js.map +1 -0
  671. package/dist/core/doctor/config.js +139 -0
  672. package/dist/core/doctor/config.js.map +1 -0
  673. package/dist/core/doctor/doctor.js +355 -0
  674. package/dist/core/doctor/doctor.js.map +1 -0
  675. package/dist/core/doctor/report.js +13 -0
  676. package/dist/core/doctor/report.js.map +1 -0
  677. package/dist/core/doctor/reports/scan.js +242 -0
  678. package/dist/core/doctor/reports/scan.js.map +1 -0
  679. package/dist/core/doctor/residue.js +110 -0
  680. package/dist/core/doctor/residue.js.map +1 -0
  681. package/dist/core/document/apply.js +224 -0
  682. package/dist/core/document/apply.js.map +1 -0
  683. package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
  684. package/dist/core/document/frontmatter.js.map +1 -0
  685. package/dist/core/document/grammar/directives.js +143 -0
  686. package/dist/core/document/grammar/directives.js.map +1 -0
  687. package/dist/core/document/parse.js +286 -0
  688. package/dist/core/document/parse.js.map +1 -0
  689. package/dist/core/document/scenarios.js +238 -0
  690. package/dist/core/document/scenarios.js.map +1 -0
  691. package/dist/core/document/spec.js +234 -0
  692. package/dist/core/document/spec.js.map +1 -0
  693. package/dist/core/{config.js → envelope/config.js} +89 -18
  694. package/dist/core/envelope/config.js.map +1 -0
  695. package/dist/core/envelope/json.js +209 -0
  696. package/dist/core/envelope/json.js.map +1 -0
  697. package/dist/core/{version.js → envelope/version.js} +3 -3
  698. package/dist/core/envelope/version.js.map +1 -0
  699. package/dist/core/explain/families.js +180 -0
  700. package/dist/core/explain/families.js.map +1 -0
  701. package/dist/core/explain/fix-tables.js +178 -0
  702. package/dist/core/explain/fix-tables.js.map +1 -0
  703. package/dist/core/explain/lookup.js +194 -0
  704. package/dist/core/explain/lookup.js.map +1 -0
  705. package/dist/core/explain/refusals.js +49 -0
  706. package/dist/core/explain/refusals.js.map +1 -0
  707. package/dist/core/explain/terms/documents.js +227 -0
  708. package/dist/core/explain/terms/documents.js.map +1 -0
  709. package/dist/core/explain/terms/done-check.js +144 -0
  710. package/dist/core/explain/terms/done-check.js.map +1 -0
  711. package/dist/core/explain/terms/entry.js +14 -0
  712. package/dist/core/explain/terms/entry.js.map +1 -0
  713. package/dist/core/explain/terms/stages.js +71 -0
  714. package/dist/core/explain/terms/stages.js.map +1 -0
  715. package/dist/core/explain/terms/tasks.js +97 -0
  716. package/dist/core/explain/terms/tasks.js.map +1 -0
  717. package/dist/core/explain/terms.js +103 -0
  718. package/dist/core/explain/terms.js.map +1 -0
  719. package/dist/core/explore/describe.js +105 -0
  720. package/dist/core/explore/describe.js.map +1 -0
  721. package/dist/core/explore/explore.js +204 -0
  722. package/dist/core/explore/explore.js.map +1 -0
  723. package/dist/core/fleet-context.js +174 -146
  724. package/dist/core/fleet-context.js.map +1 -1
  725. package/dist/core/gate/checks.js +208 -0
  726. package/dist/core/gate/checks.js.map +1 -0
  727. package/dist/core/gate/partners.js +246 -0
  728. package/dist/core/gate/partners.js.map +1 -0
  729. package/dist/core/gate/report.js +47 -0
  730. package/dist/core/gate/report.js.map +1 -0
  731. package/dist/core/gate/verification.js +176 -0
  732. package/dist/core/gate/verification.js.map +1 -0
  733. package/dist/core/gherkin/digest.js +60 -0
  734. package/dist/core/gherkin/digest.js.map +1 -0
  735. package/dist/core/gherkin/emit.js +177 -0
  736. package/dist/core/gherkin/emit.js.map +1 -0
  737. package/dist/core/gherkin/read.js +76 -0
  738. package/dist/core/gherkin/read.js.map +1 -0
  739. package/dist/core/gherkin/stale.js +210 -0
  740. package/dist/core/gherkin/stale.js.map +1 -0
  741. package/dist/core/gherkin/stamp.js +77 -0
  742. package/dist/core/gherkin/stamp.js.map +1 -0
  743. package/dist/core/gherkin/steps/catalogue.js +154 -0
  744. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  745. package/dist/core/gherkin/steps/inventory.js +98 -0
  746. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  747. package/dist/core/gherkin/steps/phrase.js +72 -0
  748. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  749. package/dist/core/glossary/delta.js +109 -0
  750. package/dist/core/glossary/delta.js.map +1 -0
  751. package/dist/core/glossary/tree.js +73 -0
  752. package/dist/core/glossary/tree.js.map +1 -0
  753. package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
  754. package/dist/core/kernel/concurrency.js.map +1 -0
  755. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  756. package/dist/core/kernel/document-bytes.js.map +1 -0
  757. package/dist/core/kernel/fences.js +42 -0
  758. package/dist/core/kernel/fences.js.map +1 -0
  759. package/dist/core/kernel/ids/capability.js +72 -0
  760. package/dist/core/kernel/ids/capability.js.map +1 -0
  761. package/dist/core/kernel/ids/dirs.js +33 -0
  762. package/dist/core/kernel/ids/dirs.js.map +1 -0
  763. package/dist/core/kernel/ids/feature.js +75 -0
  764. package/dist/core/kernel/ids/feature.js.map +1 -0
  765. package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
  766. package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
  767. package/dist/core/kernel/ids/service.js +156 -0
  768. package/dist/core/kernel/ids/service.js.map +1 -0
  769. package/dist/core/kernel/ids/subsystem.js +63 -0
  770. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  771. package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
  772. package/dist/core/kernel/path-safety.js.map +1 -0
  773. package/dist/core/{records.js → kernel/records.js} +11 -0
  774. package/dist/core/kernel/records.js.map +1 -0
  775. package/dist/core/links/backlinks.js +66 -0
  776. package/dist/core/links/backlinks.js.map +1 -0
  777. package/dist/core/links/case.js +74 -0
  778. package/dist/core/links/case.js.map +1 -0
  779. package/dist/core/links/corpus.js +118 -0
  780. package/dist/core/links/corpus.js.map +1 -0
  781. package/dist/core/links/findings.js +110 -0
  782. package/dist/core/links/findings.js.map +1 -0
  783. package/dist/core/links/parse.js +265 -0
  784. package/dist/core/links/parse.js.map +1 -0
  785. package/dist/core/mcp/argv.js +212 -0
  786. package/dist/core/mcp/argv.js.map +1 -0
  787. package/dist/core/mcp/author-tools.js +73 -0
  788. package/dist/core/mcp/author-tools.js.map +1 -0
  789. package/dist/core/mcp/framing.js +46 -0
  790. package/dist/core/mcp/framing.js.map +1 -0
  791. package/dist/core/mcp/protocol.js +280 -0
  792. package/dist/core/mcp/protocol.js.map +1 -0
  793. package/dist/core/mcp/tools.js +324 -0
  794. package/dist/core/mcp/tools.js.map +1 -0
  795. package/dist/core/obligations/obligations.js +106 -0
  796. package/dist/core/obligations/obligations.js.map +1 -0
  797. package/dist/core/openapi/baseline/gate.js +207 -0
  798. package/dist/core/openapi/baseline/gate.js.map +1 -0
  799. package/dist/core/openapi/baseline/plan.js +142 -0
  800. package/dist/core/openapi/baseline/plan.js.map +1 -0
  801. package/dist/core/openapi/baseline/record.js +174 -0
  802. package/dist/core/openapi/baseline/record.js.map +1 -0
  803. package/dist/core/openapi/contract-text.js +33 -0
  804. package/dist/core/openapi/contract-text.js.map +1 -0
  805. package/dist/core/openapi/contract-tree.js +301 -0
  806. package/dist/core/openapi/contract-tree.js.map +1 -0
  807. package/dist/core/openapi/depth.js +136 -0
  808. package/dist/core/openapi/depth.js.map +1 -0
  809. package/dist/core/openapi/digest.js +239 -0
  810. package/dist/core/openapi/digest.js.map +1 -0
  811. package/dist/core/{openapi.js → openapi/doc.js} +54 -108
  812. package/dist/core/openapi/doc.js.map +1 -0
  813. package/dist/core/openapi/merge/components.js +199 -0
  814. package/dist/core/openapi/merge/components.js.map +1 -0
  815. package/dist/core/openapi/merge/error.js +16 -0
  816. package/dist/core/openapi/merge/error.js.map +1 -0
  817. package/dist/core/openapi/merge/markers.js +204 -0
  818. package/dist/core/openapi/merge/markers.js.map +1 -0
  819. package/dist/core/openapi/merge/merge.js +232 -0
  820. package/dist/core/openapi/merge/merge.js.map +1 -0
  821. package/dist/core/openapi/merge/pin.js +110 -0
  822. package/dist/core/openapi/merge/pin.js.map +1 -0
  823. package/dist/core/openspec/decide/capabilities.js +244 -0
  824. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  825. package/dist/core/openspec/decide/dispositions.js +63 -0
  826. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  827. package/dist/core/openspec/decide/renames.js +179 -0
  828. package/dist/core/openspec/decide/renames.js.map +1 -0
  829. package/dist/core/openspec/decide/verdict.js +84 -0
  830. package/dist/core/openspec/decide/verdict.js.map +1 -0
  831. package/dist/core/openspec/inventory.js +220 -0
  832. package/dist/core/openspec/inventory.js.map +1 -0
  833. package/dist/core/openspec/model/mapping.js +78 -0
  834. package/dist/core/openspec/model/mapping.js.map +1 -0
  835. package/dist/core/openspec/model/model.js +70 -0
  836. package/dist/core/openspec/model/model.js.map +1 -0
  837. package/dist/core/openspec/scan/changes.js +241 -0
  838. package/dist/core/openspec/scan/changes.js.map +1 -0
  839. package/dist/core/openspec/scan/config.js +191 -0
  840. package/dist/core/openspec/scan/config.js.map +1 -0
  841. package/dist/core/openspec/scan/shape.js +304 -0
  842. package/dist/core/openspec/scan/shape.js.map +1 -0
  843. package/dist/core/openspec/scan/walk.js +116 -0
  844. package/dist/core/openspec/scan/walk.js.map +1 -0
  845. package/dist/core/openspec/scan/workspace.js +71 -0
  846. package/dist/core/openspec/scan/workspace.js.map +1 -0
  847. package/dist/core/owners/codeowners.js +141 -0
  848. package/dist/core/owners/codeowners.js.map +1 -0
  849. package/dist/core/pack/features.js +120 -0
  850. package/dist/core/pack/features.js.map +1 -0
  851. package/dist/core/pack/joins.js +112 -0
  852. package/dist/core/pack/joins.js.map +1 -0
  853. package/dist/core/pack/living.js +157 -0
  854. package/dist/core/pack/living.js.map +1 -0
  855. package/dist/core/pack/pack.js +120 -0
  856. package/dist/core/pack/pack.js.map +1 -0
  857. package/dist/core/permissions/permissions.js +87 -0
  858. package/dist/core/permissions/permissions.js.map +1 -0
  859. package/dist/core/projection/api.js +84 -0
  860. package/dist/core/projection/api.js.map +1 -0
  861. package/dist/core/projection/arch-slice.js +63 -0
  862. package/dist/core/projection/arch-slice.js.map +1 -0
  863. package/dist/core/projection/events.js +34 -0
  864. package/dist/core/projection/events.js.map +1 -0
  865. package/dist/core/projection/introduced.js +14 -0
  866. package/dist/core/projection/introduced.js.map +1 -0
  867. package/dist/core/provenance/findings.js +244 -0
  868. package/dist/core/provenance/findings.js.map +1 -0
  869. package/dist/core/provenance/git.js +201 -0
  870. package/dist/core/provenance/git.js.map +1 -0
  871. package/dist/core/provenance/gitq/moves.js +139 -0
  872. package/dist/core/provenance/gitq/moves.js.map +1 -0
  873. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  874. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  875. package/dist/core/provenance/sample/scope.js +238 -0
  876. package/dist/core/provenance/sample/scope.js.map +1 -0
  877. package/dist/core/provenance/sample/sections.js +61 -0
  878. package/dist/core/provenance/sample/sections.js.map +1 -0
  879. package/dist/core/provenance/sources.js +280 -0
  880. package/dist/core/provenance/sources.js.map +1 -0
  881. package/dist/core/provenance/stamp.js +220 -0
  882. package/dist/core/provenance/stamp.js.map +1 -0
  883. package/dist/core/provenance/walk.js +157 -0
  884. package/dist/core/provenance/walk.js.map +1 -0
  885. package/dist/core/repo/authored/paths.js +210 -0
  886. package/dist/core/repo/authored/paths.js.map +1 -0
  887. package/dist/core/repo/entries.js +126 -0
  888. package/dist/core/repo/entries.js.map +1 -0
  889. package/dist/core/repo/paths.js +322 -0
  890. package/dist/core/repo/paths.js.map +1 -0
  891. package/dist/core/repo/repo.js +308 -0
  892. package/dist/core/repo/repo.js.map +1 -0
  893. package/dist/core/repo/service-target.js +153 -0
  894. package/dist/core/repo/service-target.js.map +1 -0
  895. package/dist/core/repo/state.js +58 -0
  896. package/dist/core/repo/state.js.map +1 -0
  897. package/dist/core/repo/tree/find.js +61 -0
  898. package/dist/core/repo/tree/find.js.map +1 -0
  899. package/dist/core/repo/tree/fs.js +90 -0
  900. package/dist/core/repo/tree/fs.js.map +1 -0
  901. package/dist/core/repo/tree/marker.js +61 -0
  902. package/dist/core/repo/tree/marker.js.map +1 -0
  903. package/dist/core/repo/tree/render/body.js +258 -0
  904. package/dist/core/repo/tree/render/body.js.map +1 -0
  905. package/dist/core/repo/tree/render/projects.js +182 -0
  906. package/dist/core/repo/tree/render/projects.js.map +1 -0
  907. package/dist/core/repo/tree/render/service/header.js +125 -0
  908. package/dist/core/repo/tree/render/service/header.js.map +1 -0
  909. package/dist/core/repo/tree/render/service/peers.js +28 -0
  910. package/dist/core/repo/tree/render/service/peers.js.map +1 -0
  911. package/dist/core/repo/tree/render/service/view-id.js +67 -0
  912. package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
  913. package/dist/core/repo/tree/render/service/views.js +78 -0
  914. package/dist/core/repo/tree/render/service/views.js.map +1 -0
  915. package/dist/core/repo/tree/render/stale.js +42 -0
  916. package/dist/core/repo/tree/render/stale.js.map +1 -0
  917. package/dist/core/repo/tree/render/text.js +84 -0
  918. package/dist/core/repo/tree/render/text.js.map +1 -0
  919. package/dist/core/repo/tree/render/views.js +293 -0
  920. package/dist/core/repo/tree/render/views.js.map +1 -0
  921. package/dist/core/repo/tree/walk.js +255 -0
  922. package/dist/core/repo/tree/walk.js.map +1 -0
  923. package/dist/core/results.js +146 -14
  924. package/dist/core/results.js.map +1 -1
  925. package/dist/core/scaffold/landscape.js +239 -0
  926. package/dist/core/scaffold/landscape.js.map +1 -0
  927. package/dist/core/scaffold/legacy.js +271 -0
  928. package/dist/core/scaffold/legacy.js.map +1 -0
  929. package/dist/core/scaffold/readme.js +84 -0
  930. package/dist/core/scaffold/readme.js.map +1 -0
  931. package/dist/core/staging/commit.js +252 -0
  932. package/dist/core/staging/commit.js.map +1 -0
  933. package/dist/core/staging/interrupted.js +96 -0
  934. package/dist/core/staging/interrupted.js.map +1 -0
  935. package/dist/core/staging/lock.js +268 -0
  936. package/dist/core/staging/lock.js.map +1 -0
  937. package/dist/core/staging/recovery/finding.js +35 -0
  938. package/dist/core/staging/recovery/finding.js.map +1 -0
  939. package/dist/core/staging/recovery/intent.js +95 -0
  940. package/dist/core/staging/recovery/intent.js.map +1 -0
  941. package/dist/core/staging/recovery/recover.js +204 -0
  942. package/dist/core/staging/recovery/recover.js.map +1 -0
  943. package/dist/core/staging/recovery/residue.js +62 -0
  944. package/dist/core/staging/recovery/residue.js.map +1 -0
  945. package/dist/core/staging/snapshot/manifest.js +188 -0
  946. package/dist/core/staging/snapshot/manifest.js.map +1 -0
  947. package/dist/core/staging/snapshot/snapshot.js +196 -0
  948. package/dist/core/staging/snapshot/snapshot.js.map +1 -0
  949. package/dist/core/staging/txn/forward.js +181 -0
  950. package/dist/core/staging/txn/forward.js.map +1 -0
  951. package/dist/core/staging/txn/journal.js +139 -0
  952. package/dist/core/staging/txn/journal.js.map +1 -0
  953. package/dist/core/staging/txn/transaction.js +75 -0
  954. package/dist/core/staging/txn/transaction.js.map +1 -0
  955. package/dist/core/staging/writes.js +113 -0
  956. package/dist/core/staging/writes.js.map +1 -0
  957. package/dist/core/status/actions/execution.js +60 -0
  958. package/dist/core/status/actions/execution.js.map +1 -0
  959. package/dist/core/status/contracts.js +126 -0
  960. package/dist/core/status/contracts.js.map +1 -0
  961. package/dist/core/status/feature/artifacts.js +196 -0
  962. package/dist/core/status/feature/artifacts.js.map +1 -0
  963. package/dist/core/status/feature/feature.js +214 -0
  964. package/dist/core/status/feature/feature.js.map +1 -0
  965. package/dist/core/status/feature/next.js +163 -0
  966. package/dist/core/status/feature/next.js.map +1 -0
  967. package/dist/core/status/feature/state.js +21 -0
  968. package/dist/core/status/feature/state.js.map +1 -0
  969. package/dist/core/status/feature/words.js +96 -0
  970. package/dist/core/status/feature/words.js.map +1 -0
  971. package/dist/core/status/fleet/fleet.js +216 -0
  972. package/dist/core/status/fleet/fleet.js.map +1 -0
  973. package/dist/core/status/fleet/next.js +302 -0
  974. package/dist/core/status/fleet/next.js.map +1 -0
  975. package/dist/core/status/interrupted.js +97 -0
  976. package/dist/core/status/interrupted.js.map +1 -0
  977. package/dist/core/status/report.js +31 -0
  978. package/dist/core/status/report.js.map +1 -0
  979. package/dist/core/status/scan.js +41 -0
  980. package/dist/core/status/scan.js.map +1 -0
  981. package/dist/core/status/verification.js +216 -0
  982. package/dist/core/status/verification.js.map +1 -0
  983. package/dist/core/tasks/packet.js +199 -0
  984. package/dist/core/tasks/packet.js.map +1 -0
  985. package/dist/core/tasks/record.js +43 -0
  986. package/dist/core/tasks/record.js.map +1 -0
  987. package/dist/core/tasks/sources.js +181 -0
  988. package/dist/core/tasks/sources.js.map +1 -0
  989. package/dist/core/tasks/stamps.js +76 -0
  990. package/dist/core/tasks/stamps.js.map +1 -0
  991. package/dist/core/tasks/unit.js +0 -0
  992. package/dist/core/tasks/unit.js.map +1 -0
  993. package/dist/core/usecases/capability.js +166 -0
  994. package/dist/core/usecases/capability.js.map +1 -0
  995. package/dist/core/usecases/delta/claims.js +140 -0
  996. package/dist/core/usecases/delta/claims.js.map +1 -0
  997. package/dist/core/usecases/delta/flows.js +101 -0
  998. package/dist/core/usecases/delta/flows.js.map +1 -0
  999. package/dist/core/usecases/delta/modified.js +315 -0
  1000. package/dist/core/usecases/delta/modified.js.map +1 -0
  1001. package/dist/core/usecases/delta/overlay.js +76 -0
  1002. package/dist/core/usecases/delta/overlay.js.map +1 -0
  1003. package/dist/core/usecases/fleet.js +296 -0
  1004. package/dist/core/usecases/fleet.js.map +1 -0
  1005. package/dist/core/usecases/grade/capability-tag.js +93 -0
  1006. package/dist/core/usecases/grade/capability-tag.js.map +1 -0
  1007. package/dist/core/usecases/grade/feature.js +88 -0
  1008. package/dist/core/usecases/grade/feature.js.map +1 -0
  1009. package/dist/core/usecases/grade/requirement-tag.js +94 -0
  1010. package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
  1011. package/dist/core/usecases/grade/steps.js +266 -0
  1012. package/dist/core/usecases/grade/steps.js.map +1 -0
  1013. package/dist/core/usecases/grade/usecases.js +112 -0
  1014. package/dist/core/usecases/grade/usecases.js.map +1 -0
  1015. package/dist/core/usecases/operations.js +123 -0
  1016. package/dist/core/usecases/operations.js.map +1 -0
  1017. package/dist/core/usecases/place.js +44 -0
  1018. package/dist/core/usecases/place.js.map +1 -0
  1019. package/dist/core/usecases/service/exclude.js +119 -0
  1020. package/dist/core/usecases/service/exclude.js.map +1 -0
  1021. package/dist/core/usecases/service/flows.js +164 -0
  1022. package/dist/core/usecases/service/flows.js.map +1 -0
  1023. package/dist/core/usecases/suites/participants.js +83 -0
  1024. package/dist/core/usecases/suites/participants.js.map +1 -0
  1025. package/dist/core/usecases/suites/suites.js +45 -0
  1026. package/dist/core/usecases/suites/suites.js.map +1 -0
  1027. package/dist/core/usecases/touch.js +101 -0
  1028. package/dist/core/usecases/touch.js.map +1 -0
  1029. package/dist/core/verify/answers.js +180 -0
  1030. package/dist/core/verify/answers.js.map +1 -0
  1031. package/dist/core/verify/build.js +170 -0
  1032. package/dist/core/verify/build.js.map +1 -0
  1033. package/dist/core/verify/checklist.js +259 -0
  1034. package/dist/core/verify/checklist.js.map +1 -0
  1035. package/dist/core/verify/claims/identity.js +61 -0
  1036. package/dist/core/verify/claims/identity.js.map +1 -0
  1037. package/dist/core/verify/cross/diff.js +97 -0
  1038. package/dist/core/verify/cross/diff.js.map +1 -0
  1039. package/dist/core/verify/evidence/contract.js +169 -0
  1040. package/dist/core/verify/evidence/contract.js.map +1 -0
  1041. package/dist/core/verify/location.js +67 -0
  1042. package/dist/core/verify/location.js.map +1 -0
  1043. package/dist/core/verify/pins/lint.js +158 -0
  1044. package/dist/core/verify/pins/lint.js.map +1 -0
  1045. package/dist/core/verify/pins/pin.js +95 -0
  1046. package/dist/core/verify/pins/pin.js.map +1 -0
  1047. package/dist/core/verify/read/file.js +224 -0
  1048. package/dist/core/verify/read/file.js.map +1 -0
  1049. package/dist/core/verify/read/shape.js +169 -0
  1050. package/dist/core/verify/read/shape.js.map +1 -0
  1051. package/dist/core/verify/read/union.js +105 -0
  1052. package/dist/core/verify/read/union.js.map +1 -0
  1053. package/dist/core/verify/record.js +165 -0
  1054. package/dist/core/verify/record.js.map +1 -0
  1055. package/dist/core/verify/store/commit.js +99 -0
  1056. package/dist/core/verify/store/commit.js.map +1 -0
  1057. package/dist/core/verify/store/render.js +61 -0
  1058. package/dist/core/verify/store/render.js.map +1 -0
  1059. package/dist/core/vocabulary/health.js +91 -0
  1060. package/dist/core/vocabulary/health.js.map +1 -0
  1061. package/dist/core/vocabulary/issue.js +59 -0
  1062. package/dist/core/vocabulary/issue.js.map +1 -0
  1063. package/dist/core/vocabulary/maturity.js +216 -0
  1064. package/dist/core/vocabulary/maturity.js.map +1 -0
  1065. package/dist/core/vocabulary/report.js +90 -0
  1066. package/dist/core/vocabulary/report.js.map +1 -0
  1067. package/dist/core/vocabulary/steps.js +266 -0
  1068. package/dist/core/vocabulary/steps.js.map +1 -0
  1069. package/dist/core/workspace/discover.js +239 -0
  1070. package/dist/core/workspace/discover.js.map +1 -0
  1071. package/dist/core/workspace/render.js +52 -0
  1072. package/dist/core/workspace/render.js.map +1 -0
  1073. package/examples/README.md +232 -0
  1074. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  1075. package/examples/docs/architecture/capabilities.yaml +31 -0
  1076. package/examples/docs/architecture/landscape.likec4 +336 -0
  1077. package/examples/docs/architecture/obligations.yaml +23 -0
  1078. package/examples/docs/architecture/permissions.yaml +50 -0
  1079. package/examples/docs/architecture/services.likec4 +70 -0
  1080. package/examples/docs/architecture/subsystems.likec4 +18 -0
  1081. package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
  1082. package/examples/docs/capabilities/checkout/spec.md +55 -0
  1083. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  1084. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  1085. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  1086. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  1087. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  1088. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  1089. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
  1090. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  1091. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  1092. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  1093. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  1094. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  1095. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
  1096. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  1097. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  1098. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  1099. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  1100. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  1101. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  1102. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  1103. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  1104. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  1105. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  1106. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
  1107. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  1108. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  1109. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  1110. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  1111. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  1112. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  1113. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  1114. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  1115. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  1116. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  1117. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  1118. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  1119. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  1120. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  1121. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  1122. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  1123. package/examples/docs/glossary/order.md +15 -0
  1124. package/examples/docs/glossary/payments/authorization.md +14 -0
  1125. package/examples/docs/likec4.config.json +8 -0
  1126. package/examples/docs/loam.json +3 -0
  1127. package/examples/docs/services/checkout-web/model.likec4 +92 -0
  1128. package/examples/docs/services/checkout-web/spec.md +91 -0
  1129. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  1130. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  1131. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  1132. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  1133. package/examples/docs/services/order-service/arch.spec.md +134 -0
  1134. package/examples/docs/services/order-service/asyncapi.yaml +109 -0
  1135. package/examples/docs/services/order-service/health.yaml +57 -0
  1136. package/examples/docs/services/order-service/model.likec4 +126 -0
  1137. package/examples/docs/services/order-service/openapi.yaml +257 -0
  1138. package/examples/docs/services/order-service/runbook.md +62 -0
  1139. package/examples/docs/services/order-service/spec.md +134 -0
  1140. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  1141. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  1142. package/examples/docs/services/payment-service/arch.spec.md +76 -0
  1143. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  1144. package/examples/docs/services/payment-service/health.yaml +39 -0
  1145. package/examples/docs/services/payment-service/model.likec4 +68 -0
  1146. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  1147. package/examples/docs/services/payment-service/runbook.md +37 -0
  1148. package/examples/docs/services/payment-service/spec.md +88 -0
  1149. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  1150. package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
  1151. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  1152. package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
  1153. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  1154. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  1155. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  1156. package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
  1157. package/examples/docs/services/platform/notification-service/health.yaml +40 -0
  1158. package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
  1159. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  1160. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  1161. package/examples/docs/services/platform/subsystem.yaml +2 -0
  1162. package/examples/fleet.yaml +57 -0
  1163. package/package.json +19 -6
  1164. package/dist/commands/adopt.js +0 -240
  1165. package/dist/commands/adopt.js.map +0 -1
  1166. package/dist/commands/archive.js +0 -1313
  1167. package/dist/commands/archive.js.map +0 -1
  1168. package/dist/commands/delta.js +0 -388
  1169. package/dist/commands/delta.js.map +0 -1
  1170. package/dist/commands/docs-repo-gate.js.map +0 -1
  1171. package/dist/commands/format.js +0 -17
  1172. package/dist/commands/format.js.map +0 -1
  1173. package/dist/commands/gherkin.js +0 -309
  1174. package/dist/commands/gherkin.js.map +0 -1
  1175. package/dist/commands/init.js.map +0 -1
  1176. package/dist/commands/list.js +0 -295
  1177. package/dist/commands/list.js.map +0 -1
  1178. package/dist/commands/migrate-openspec.js +0 -950
  1179. package/dist/commands/migrate-openspec.js.map +0 -1
  1180. package/dist/commands/new.js +0 -413
  1181. package/dist/commands/new.js.map +0 -1
  1182. package/dist/commands/rebase.js +0 -356
  1183. package/dist/commands/rebase.js.map +0 -1
  1184. package/dist/commands/show.js +0 -320
  1185. package/dist/commands/show.js.map +0 -1
  1186. package/dist/commands/status.js +0 -262
  1187. package/dist/commands/status.js.map +0 -1
  1188. package/dist/commands/unarchive.js +0 -317
  1189. package/dist/commands/unarchive.js.map +0 -1
  1190. package/dist/commands/validate.js +0 -1773
  1191. package/dist/commands/validate.js.map +0 -1
  1192. package/dist/commands/verify.js +0 -775
  1193. package/dist/commands/verify.js.map +0 -1
  1194. package/dist/commands/vouch.js +0 -421
  1195. package/dist/commands/vouch.js.map +0 -1
  1196. package/dist/core/agent.js +0 -2173
  1197. package/dist/core/agent.js.map +0 -1
  1198. package/dist/core/agents-stamp.js.map +0 -1
  1199. package/dist/core/arch.js +0 -130
  1200. package/dist/core/arch.js.map +0 -1
  1201. package/dist/core/asyncapi.js +0 -253
  1202. package/dist/core/asyncapi.js.map +0 -1
  1203. package/dist/core/brief.js +0 -755
  1204. package/dist/core/brief.js.map +0 -1
  1205. package/dist/core/coherence.js +0 -577
  1206. package/dist/core/coherence.js.map +0 -1
  1207. package/dist/core/concurrency.js.map +0 -1
  1208. package/dist/core/config.js.map +0 -1
  1209. package/dist/core/delta.js +0 -476
  1210. package/dist/core/delta.js.map +0 -1
  1211. package/dist/core/dependencies.js +0 -356
  1212. package/dist/core/dependencies.js.map +0 -1
  1213. package/dist/core/doctor.js +0 -596
  1214. package/dist/core/doctor.js.map +0 -1
  1215. package/dist/core/document-bytes.js.map +0 -1
  1216. package/dist/core/explore.js +0 -225
  1217. package/dist/core/explore.js.map +0 -1
  1218. package/dist/core/frontmatter.js.map +0 -1
  1219. package/dist/core/gherkin.js +0 -463
  1220. package/dist/core/gherkin.js.map +0 -1
  1221. package/dist/core/health.js +0 -67
  1222. package/dist/core/health.js.map +0 -1
  1223. package/dist/core/ids.js +0 -122
  1224. package/dist/core/ids.js.map +0 -1
  1225. package/dist/core/issue.js +0 -9
  1226. package/dist/core/issue.js.map +0 -1
  1227. package/dist/core/json.js +0 -74
  1228. package/dist/core/json.js.map +0 -1
  1229. package/dist/core/likec4.js +0 -489
  1230. package/dist/core/likec4.js.map +0 -1
  1231. package/dist/core/maturity.js +0 -66
  1232. package/dist/core/maturity.js.map +0 -1
  1233. package/dist/core/openapi-merge.js +0 -552
  1234. package/dist/core/openapi-merge.js.map +0 -1
  1235. package/dist/core/openapi.js.map +0 -1
  1236. package/dist/core/openspec-inventory.js +0 -1440
  1237. package/dist/core/openspec-inventory.js.map +0 -1
  1238. package/dist/core/path-safety.js.map +0 -1
  1239. package/dist/core/provenance.js +0 -787
  1240. package/dist/core/provenance.js.map +0 -1
  1241. package/dist/core/records.js.map +0 -1
  1242. package/dist/core/repo.js +0 -438
  1243. package/dist/core/repo.js.map +0 -1
  1244. package/dist/core/report.js +0 -47
  1245. package/dist/core/report.js.map +0 -1
  1246. package/dist/core/spec.js +0 -505
  1247. package/dist/core/spec.js.map +0 -1
  1248. package/dist/core/staging.js +0 -890
  1249. package/dist/core/staging.js.map +0 -1
  1250. package/dist/core/status.js +0 -1132
  1251. package/dist/core/status.js.map +0 -1
  1252. package/dist/core/steps.js +0 -72
  1253. package/dist/core/steps.js.map +0 -1
  1254. package/dist/core/verify.js +0 -807
  1255. package/dist/core/verify.js.map +0 -1
  1256. package/dist/core/version.js.map +0 -1
@@ -0,0 +1,278 @@
1
+ /**
2
+ * The four ways a service's `model.likec4` and the renderer's project files can
3
+ * disagree, graded as one warning per service on the fleet target — plus the
4
+ * one way the same root config can hide the fleet MAP, graded once for the
5
+ * fleet (`landscape.excluded`, at the foot of this module).
6
+ *
7
+ * They are one walk because they are one question — "can the renderer actually
8
+ * show what this model says?" — asked of the two shapes a model has. A model
9
+ * that STANDS ALONE (declares its own element kinds) is parsed alone: it needs a
10
+ * project file of its own, and the root project must exclude its directory. A
11
+ * model that EXTENDS the fleet map declares no kinds and lives IN the root
12
+ * project: it must NOT be excluded, and a project file beside it TAKES it out of
13
+ * there — measured at the 1.59.2 pin, the nested project claims the model, which
14
+ * then does not resolve (the map's kinds are not in there with it) and the fleet
15
+ * project loses the service's interior. Each shape therefore owes the opposite of
16
+ * the other, and each of the four codes below is one half of one of those pairs:
17
+ *
18
+ * - `service.likec4-config-missing` — standalone, no project file.
19
+ * - `service.likec4-config-stray` — extending, project file present.
20
+ * - `service.model-excluded` — extending, root `exclude` covers it. Two
21
+ * questions, not one: the DIRECTORY (`excludingEntry`, which `subsystem sync`
22
+ * can repair) and, where that says no, the model FILE (`excludingPath`, which
23
+ * it cannot — the message says so).
24
+ * - `service.model-unexcluded` — standalone, root `exclude` does not.
25
+ *
26
+ * `landscape.excluded` is the fifth, and it is the same question asked one
27
+ * level up: the root `exclude` covering `architecture/landscape.likec4` itself.
28
+ *
29
+ * WHY WARNINGS. Every fact loam grades about a model — its parse, its bindings,
30
+ * its edges into the spine — holds exactly as it did in all five states, so
31
+ * nothing here may gate. The fifth is only true because the architecture loader
32
+ * keeps the map whatever the root `exclude` says (`core/c4/project/architecture.ts`);
33
+ * before it did, an excluded map blanked every cross-service grade in the run. ROADMAP's clause that rendering "must stay outside
34
+ * validation so view computation cannot slow or change the gate" is about
35
+ * computing views; this check computes nothing: one `existsSync` per service and
36
+ * one read of the root config. And the sibling that grades the ROOT file's
37
+ * absence (`doctor.likec4-config-missing`, `core/doctor/doctor.ts`) calls a repo
38
+ * without it "only unrenderable" and warns; these are the same condition one
39
+ * directory down and earn the same severity.
40
+ *
41
+ * WHY `validate --all` AND NOT `doctor`. `doctor` is the step-0 preflight of the
42
+ * adopt protocol — wiring, the config, the fleet map's readability — and the
43
+ * protocol's step 5 is the `validate --all` run whose findings the agent
44
+ * branches on. The report that motivated the first of these codes had its own
45
+ * `doctor --json` answer `healthy: true` with 0 findings on a tree where every
46
+ * adopted model was unrenderable from the root: the model is written in step 3,
47
+ * so its renderability is a fact that first exists at step 5, and a preflight
48
+ * that ran before the model did could not have said otherwise. Never in
49
+ * `validate --service`, `status` or `doctor`: the writer is a fleet verb
50
+ * (`subsystem sync`) and the findings belong beside the files that verb owns.
51
+ *
52
+ * WHY PER SERVICE. `subject` is the service id so a `--json` worklist filters by
53
+ * team the way `landscape.service-unmodelled` already lets it — one fleet
54
+ * finding listing every gap would have to be re-parsed to find out whose it is.
55
+ * The `scope` location is the service's tree path, through `serviceTreePath` on
56
+ * the ENTRY the survey hands back — never a join by id: these grades are emitted
57
+ * before the map's early returns precisely so they hold on a broken tree, and a
58
+ * tree with two services sharing a leaf name under different subsystems
59
+ * (`subsystem.name-collision`) is exactly such a tree, still enumerated in full.
60
+ * Joined by id, both findings named the first directory while `subsystem sync`
61
+ * wrote both files at the right paths.
62
+ *
63
+ * WHY THE ROOT GATE, and it does double duty. Semantically: `subsystem sync`
64
+ * writes nothing — no per-service file, no rewritten `exclude` — until the root
65
+ * `likec4.config.json` exists (the docs root is then a LikeC4 workspace and a
66
+ * nested project is registered inside it — measured at the 1.59.2 pin), so a
67
+ * repo without the root file has `doctor` telling it to write that first and
68
+ * nothing to sync into; grading a gap the writer would not fill is a loop no
69
+ * command can clear. The same rule silences a directory whose name is not a
70
+ * legal service id: the survey skips it (`render/projects.ts` says why),
71
+ * `service.id-invalid` already names it, and a warning here would advertise a
72
+ * repair `sync` refuses to perform. Fixture-wise: `makeProject` writes NO root
73
+ * file, so every existing fixture stays silent under this gate, and the suites
74
+ * that pin a fleet's warning set exactly (`test/examples.test.ts`,
75
+ * `test/self-model.test.ts`) ship the files their shapes call for and keep their
76
+ * counts.
77
+ *
78
+ * The exclude half has a SECOND gate, inside `readRootExclude`: a root config
79
+ * loam cannot read an `exclude` list out of answers `null`, and both grades that
80
+ * read it stay silent. loam does not know what the renderer will do with a file
81
+ * it could not parse, and asserting an exclusion on evidence it does not have is
82
+ * worse than saying nothing.
83
+ */
84
+ import { existsSync } from "node:fs";
85
+ import { relative, resolve } from "node:path";
86
+ import { excludingEntry, excludingPath, readRootExclude } from "../../../../core/c4/root-project/exclude.js";
87
+ import { serviceTreePath } from "../../../../core/kernel/ids/dirs.js";
88
+ import { ARTIFACT_FILES, landscapePath, LIKEC4_PROJECT_FILENAME, rootProjectPath, serviceRenderPaths } from "../../../../core/repo/paths.js";
89
+ import { surveyProjects } from "../../../../core/repo/tree/render/projects.js";
90
+ /**
91
+ * `entries` is the fleet enumeration at whatever depth each service lives, and
92
+ * `shapes` is the shape of every model in it, keyed by resolved path
93
+ * (`FleetContext.modelShapes`). The shape map is built over the FULL enumeration
94
+ * rather than a `--base` narrowing: a model missing from it would read as
95
+ * standalone, which is the wrong half of every pair above.
96
+ *
97
+ * The predicate handed into the survey is the ONE spelling of "has a model,
98
+ * lacks a project file" that `subsystem sync` also fills, so the grader can
99
+ * never name a gap the writer would leave.
100
+ */
101
+ export async function projectFindings(docsDir, entries, shapes) {
102
+ // No root project file, no root project — and no `exclude` list either, so the
103
+ // map is not excluded by anything loam can see. `false` here is a fact, not a
104
+ // default: `readRootExclude` would answer `null` one line down and every grade
105
+ // below it stays silent for the same reason.
106
+ if (!existsSync(rootProjectPath(docsDir)))
107
+ return { findings: [], mapExcluded: false };
108
+ const survey = surveyProjects(entries, serviceRenderPaths, (model) => shapes.get(resolve(model)) !== "extending");
109
+ const exclude = await readRootExclude(docsDir);
110
+ const findings = [];
111
+ // The ONE derivation. The boolean is read off the finding rather than computed
112
+ // beside it, so a fleet where `c4.fleet-project-invalid` is suspended is by
113
+ // construction a fleet where `landscape.excluded` says why.
114
+ const excluded = mapExcluded(docsDir, exclude);
115
+ findings.push(...excluded);
116
+ for (const model of survey.models) {
117
+ const tree = serviceTreePath(model.service);
118
+ // Everything the four share, so each push below is its code and its
119
+ // sentence and nothing else. `scope`, not `primary`: two of the four are
120
+ // about a file that does not exist yet, and the actionable place is the
121
+ // directory either way.
122
+ const at = {
123
+ severity: "warn",
124
+ subject: model.service.id,
125
+ locations: [{ path: tree, role: "scope" }],
126
+ };
127
+ if (model.standalone && !model.configured) {
128
+ findings.push({
129
+ ...at,
130
+ code: "service.likec4-config-missing",
131
+ message: `${model.service.id}: ${tree}/${ARTIFACT_FILES.model} exists and ${tree}/${LIKEC4_PROJECT_FILENAME} does not — ` +
132
+ "a model that stands alone (declares its own `specification`) renders only as a project of its own, " +
133
+ "and nothing renders it from the docs root now. Run `loam subsystem sync`; it writes the file (create-only) — never write it by hand.",
134
+ });
135
+ }
136
+ if (!model.standalone && model.configured) {
137
+ findings.push({
138
+ ...at,
139
+ code: "service.likec4-config-stray",
140
+ message: `${model.service.id}: ${tree}/${ARTIFACT_FILES.model} extends the fleet map and ${tree}/${LIKEC4_PROJECT_FILENAME} ` +
141
+ "sits beside it — the renderer registers that file as a project of its own rooted at that directory, so " +
142
+ "the docs root stops being a one-project workspace (`likec4 validate .` then refuses without `--project`), " +
143
+ "and wherever that nested project claims the model it parses alone, out of the root project where the " +
144
+ "map's kinds are: the model does not resolve and `export json --project fleet` loses this service's " +
145
+ "containers (measured, likec4 1.59.2 — which of the two happens depends on the workspace, and neither is " +
146
+ "a state this file buys anything in). Run `loam subsystem sync`; it deletes the file (or delete it " +
147
+ "yourself). loam never writes one beside an extending model",
148
+ });
149
+ }
150
+ // `excludingEntry` reports the entry VERBATIM because the repair is to
151
+ // delete or narrow THAT line, and a fleet that files its services under
152
+ // subsystems is excluded by `services/platform/**` rather than by anything
153
+ // naming the service — a message that did not quote the entry would send
154
+ // its reader looking for a line that is not there.
155
+ const entry = exclude === null ? null : excludingEntry(exclude, tree);
156
+ // THE SECOND QUESTION, and the state that was silent until it was asked:
157
+ // an entry shaped like a FILE hides the model without covering the
158
+ // directory. `services/**/model.likec4` and the bare `**/model.likec4` each
159
+ // took every extending model out of the renderer on `examples/docs` — 3
160
+ // source files of 8, five drill-down views gone from the export — with the
161
+ // whole run reporting 0 errors and not one line containing the word
162
+ // "exclude" (re-verification 2026-09-04, area C item 5). It is asked ONLY
163
+ // where the directory question said no, because that arm names an entry
164
+ // `subsystem sync` can take back and this one names an entry it cannot.
165
+ const fileEntry = exclude === null || entry !== null ? null : excludingPath(exclude, `${tree}/${ARTIFACT_FILES.model}`);
166
+ const hiding = entry ?? fileEntry;
167
+ if (exclude !== null && !model.standalone && hiding !== null) {
168
+ findings.push({
169
+ ...at,
170
+ code: "service.model-excluded",
171
+ message: `${model.service.id}: ${tree}/${ARTIFACT_FILES.model} extends the fleet map and the root ` +
172
+ `${LIKEC4_PROJECT_FILENAME} excludes it ('${hiding}') — the renderer never loads it, so the service is ` +
173
+ "a box with nothing inside it from the docs root. " +
174
+ (entry === null
175
+ ? // The repair is an EDIT, not a command, and saying otherwise is the
176
+ // loop `landscape.excluded` already refuses to open: sync recomputes
177
+ // only the `services/<tree>/**` entries and would report success
178
+ // having changed nothing.
179
+ "That entry hides the model file without covering " +
180
+ `${tree}/, so \`loam subsystem sync\` cannot repair it: sync maintains only the ` +
181
+ "`services/` directory entries and leaves every other line exactly as the team wrote it. Narrow that " +
182
+ "entry to the paths it was written for, or delete it"
183
+ : "Run `loam subsystem sync`: it rewrites the root project's `exclude` to cover exactly the models " +
184
+ "that stand alone"),
185
+ });
186
+ }
187
+ if (exclude !== null && model.standalone && entry === null) {
188
+ findings.push({
189
+ ...at,
190
+ code: "service.model-unexcluded",
191
+ message: `${model.service.id}: ${tree}/${ARTIFACT_FILES.model} stands alone (declares its own specification) and ` +
192
+ `the root ${LIKEC4_PROJECT_FILENAME} does not exclude ${tree}/ — the renderer merges it into the map ` +
193
+ "and reports every kind and element it declares as a duplicate, blanking the whole root project. " +
194
+ `Run \`loam subsystem sync\`: it adds ${tree}/** to the root project's \`exclude\``,
195
+ });
196
+ }
197
+ }
198
+ return { findings, mapExcluded: excluded.length > 0 };
199
+ }
200
+ /**
201
+ * `landscape.excluded` — the root `exclude` covers the fleet MAP itself.
202
+ *
203
+ * WHY IT EXISTS AT ALL, and why only now. The architecture loader used to apply
204
+ * the root `exclude` with no floor under it, so an entry covering
205
+ * `architecture/landscape.likec4` — an `architecture/*.likec4` written for a
206
+ * palette, say — left that project EMPTY, and an empty project parses with zero
207
+ * errors. Every reader downstream took that for "the map declares nothing":
208
+ * `landscape.service-unmodelled` on every service, `c4.invalid` on every
209
+ * extending model, `subsystem sync` cutting a good generated file back to a
210
+ * title (verification 2026-09-04, review C). The loader now keeps the map
211
+ * whatever the list says, so loam has stopped asserting those falsehoods — but
212
+ * the RENDERER still applies the entry, and it has no floor. Nothing told the
213
+ * author that the fleet map they are grading is a map nobody can open. This is
214
+ * that sentence, and it is the only finding in the run that names it.
215
+ *
216
+ * WARN, NEVER GATING, for the reason the module banner gives: with the loader's
217
+ * floor in place, every fact loam grades holds identically either way. The gap
218
+ * is a renderer gap, exactly like the four per-service grades above.
219
+ *
220
+ * THE SAME ROOT GATE covers it — the caller returns early with no root
221
+ * `likec4.config.json`, and a config loam cannot read an `exclude` list out of
222
+ * answers `null`, which says nothing rather than guessing. It is gated on the
223
+ * map EXISTING as well: with no file there, `landscape.missing` is the finding
224
+ * and an entry covering a path nobody wrote is not a repair anyone owes.
225
+ *
226
+ * `excludingPath`, not `excludingEntry`: the map is a FILE, and this must fire
227
+ * exactly when `architectureProjectDocuments` would have dropped it — same
228
+ * list, same matcher, same argument. Asking the directory question instead
229
+ * would answer for `architecture/` as a whole and miss `architecture/*.likec4`,
230
+ * which is the spelling that caused the defect.
231
+ *
232
+ * The repair is NOT `loam subsystem sync`, and the message says so where the
233
+ * four grades above name it: sync recomputes only the `services/<tree>/**`
234
+ * entries and leaves every other line in the order the team wrote it, so it
235
+ * would report success and change nothing. The four had a writer; this one has
236
+ * an author.
237
+ *
238
+ * AND IT SUSPENDS `c4.fleet-project-invalid`, which is the cascade discipline
239
+ * `permissions.invalid` and `capability.invalid` already state: a grade that
240
+ * RESOLVES against a document nobody loaded is not a diagnosis. That check
241
+ * builds the fleet project the way the renderer does — no floor under the map —
242
+ * so the very entry named here takes the map out of it and every `extend` in
243
+ * every extending model then resolves against nothing. Measured on
244
+ * `examples/docs` with `architecture/*.likec4` in the list: one
245
+ * `landscape.excluded` and **161** `c4.fleet-project-invalid`, all of them one
246
+ * line's fault. The message carries that clause so the reader knows the fleet
247
+ * project is unread rather than clean, and the caller reads the same fact off
248
+ * `ProjectGrade.mapExcluded` — see `./fleet-project.ts`'s `mapExcluded` gate.
249
+ */
250
+ function mapExcluded(docsDir, exclude) {
251
+ const map = landscapePath(docsDir);
252
+ if (exclude === null || !existsSync(map))
253
+ return [];
254
+ const rel = relative(docsDir, map).split(/[\\/]/).join("/");
255
+ const entry = excludingPath(exclude, rel);
256
+ if (entry === null)
257
+ return [];
258
+ return [
259
+ {
260
+ severity: "warn",
261
+ code: "landscape.excluded",
262
+ // Quoted VERBATIM, for `service.model-excluded`'s reason one level down:
263
+ // the repair is to edit THAT line, and an entry loam re-spelled is a line
264
+ // its author would go looking for and not find.
265
+ message: `landscape: the root ${LIKEC4_PROJECT_FILENAME}'s \`exclude\` covers ${rel} ('${entry}') — the renderer never ` +
266
+ "loads the fleet map, so it draws no map at all and every model that EXTENDS the map resolves against " +
267
+ "nothing in the root project, while loam goes on grading the map it reads from disk. `c4.fleet-project-invalid` " +
268
+ "is NOT graded while this entry stands: that check loads the fleet project the way the renderer does, so it " +
269
+ "would report the same one line as an unresolved reference in every extending model rather than as this. " +
270
+ "Remove that entry, or " +
271
+ `narrow it to the paths it was written for, and the fleet project is graded again. \`loam subsystem sync\` ` +
272
+ "will not do it: that command maintains " +
273
+ "only the `services/` entries in the list and leaves every other line exactly as the team wrote it",
274
+ locations: [{ path: rel, role: "primary" }],
275
+ },
276
+ ];
277
+ }
278
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../../../../src/commands/validate/fleet/views/projects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC7G,OAAO,EAAE,eAAe,EAAgB,MAAM,qCAAqC,CAAC;AAEpF,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,uBAAuB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAC7I,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAsB/E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAgB,EAChB,OAAgC,EAChC,MAAuC;IAEvC,+EAA+E;IAC/E,8EAA8E;IAC9E,+EAA+E;IAC/E,6CAA6C;IAC7C,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACvF,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,kBAAkB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC;IAClH,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,+EAA+E;IAC/E,4EAA4E;IAC5E,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/C,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5C,oEAAoE;QACpE,yEAAyE;QACzE,wEAAwE;QACxE,wBAAwB;QACxB,MAAM,EAAE,GAAG;YACT,QAAQ,EAAE,MAAe;YACzB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE;YACzB,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAgB,EAAE,CAAC;SACpD,CAAC;QACF,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;YAC1C,QAAQ,CAAC,IAAI,CAAC;gBACZ,GAAG,EAAE;gBACL,IAAI,EAAE,+BAA+B;gBACrC,OAAO,EACL,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,IAAI,IAAI,cAAc,CAAC,KAAK,eAAe,IAAI,IAAI,uBAAuB,cAAc;oBAChH,qGAAqG;oBACrG,sIAAsI;aACzI,CAAC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YAC1C,QAAQ,CAAC,IAAI,CAAC;gBACZ,GAAG,EAAE;gBACL,IAAI,EAAE,6BAA6B;gBACnC,OAAO,EACL,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,IAAI,IAAI,cAAc,CAAC,KAAK,8BAA8B,IAAI,IAAI,uBAAuB,GAAG;oBACpH,yGAAyG;oBACzG,4GAA4G;oBAC5G,uGAAuG;oBACvG,qGAAqG;oBACrG,0GAA0G;oBAC1G,oGAAoG;oBACpG,4DAA4D;aAC/D,CAAC,CAAC;QACL,CAAC;QACD,uEAAuE;QACvE,wEAAwE;QACxE,2EAA2E;QAC3E,yEAAyE;QACzE,mDAAmD;QACnD,MAAM,KAAK,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACtE,yEAAyE;QACzE,mEAAmE;QACnE,4EAA4E;QAC5E,wEAAwE;QACxE,2EAA2E;QAC3E,oEAAoE;QACpE,0EAA0E;QAC1E,wEAAwE;QACxE,wEAAwE;QACxE,MAAM,SAAS,GACb,OAAO,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC;QACxG,MAAM,MAAM,GAAG,KAAK,IAAI,SAAS,CAAC;QAClC,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAC7D,QAAQ,CAAC,IAAI,CAAC;gBACZ,GAAG,EAAE;gBACL,IAAI,EAAE,wBAAwB;gBAC9B,OAAO,EACL,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,IAAI,IAAI,cAAc,CAAC,KAAK,sCAAsC;oBAC1F,GAAG,uBAAuB,kBAAkB,MAAM,sDAAsD;oBACxG,mDAAmD;oBACnD,CAAC,KAAK,KAAK,IAAI;wBACb,CAAC,CAAC,oEAAoE;4BACpE,qEAAqE;4BACrE,iEAAiE;4BACjE,0BAA0B;4BAC1B,mDAAmD;gCACnD,GAAG,IAAI,0EAA0E;gCACjF,sGAAsG;gCACtG,qDAAqD;wBACvD,CAAC,CAAC,kGAAkG;4BAClG,kBAAkB,CAAC;aAC1B,CAAC,CAAC;QACL,CAAC;QACD,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC3D,QAAQ,CAAC,IAAI,CAAC;gBACZ,GAAG,EAAE;gBACL,IAAI,EAAE,0BAA0B;gBAChC,OAAO,EACL,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,IAAI,IAAI,cAAc,CAAC,KAAK,qDAAqD;oBACzG,YAAY,uBAAuB,qBAAqB,IAAI,0CAA0C;oBACtG,kGAAkG;oBAClG,wCAAwC,IAAI,uCAAuC;aACtF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;AACxD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,SAAS,WAAW,CAAC,OAAgB,EAAE,OAAiC;IACtE,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC1C,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAC9B,OAAO;QACL;YACE,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,oBAAoB;YAC1B,yEAAyE;YACzE,0EAA0E;YAC1E,gDAAgD;YAChD,OAAO,EACL,uBAAuB,uBAAuB,yBAAyB,GAAG,MAAM,KAAK,0BAA0B;gBAC/G,uGAAuG;gBACvG,iHAAiH;gBACjH,6GAA6G;gBAC7G,0GAA0G;gBAC1G,wBAAwB;gBACxB,4GAA4G;gBAC5G,yCAAyC;gBACzC,mGAAmG;YACrG,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;SAC5C;KACF,CAAC;AACJ,CAAC","sourcesContent":["/**\n * The four ways a service's `model.likec4` and the renderer's project files can\n * disagree, graded as one warning per service on the fleet target — plus the\n * one way the same root config can hide the fleet MAP, graded once for the\n * fleet (`landscape.excluded`, at the foot of this module).\n *\n * They are one walk because they are one question — \"can the renderer actually\n * show what this model says?\" — asked of the two shapes a model has. A model\n * that STANDS ALONE (declares its own element kinds) is parsed alone: it needs a\n * project file of its own, and the root project must exclude its directory. A\n * model that EXTENDS the fleet map declares no kinds and lives IN the root\n * project: it must NOT be excluded, and a project file beside it TAKES it out of\n * there — measured at the 1.59.2 pin, the nested project claims the model, which\n * then does not resolve (the map's kinds are not in there with it) and the fleet\n * project loses the service's interior. Each shape therefore owes the opposite of\n * the other, and each of the four codes below is one half of one of those pairs:\n *\n * - `service.likec4-config-missing` — standalone, no project file.\n * - `service.likec4-config-stray` — extending, project file present.\n * - `service.model-excluded` — extending, root `exclude` covers it. Two\n * questions, not one: the DIRECTORY (`excludingEntry`, which `subsystem sync`\n * can repair) and, where that says no, the model FILE (`excludingPath`, which\n * it cannot — the message says so).\n * - `service.model-unexcluded` — standalone, root `exclude` does not.\n *\n * `landscape.excluded` is the fifth, and it is the same question asked one\n * level up: the root `exclude` covering `architecture/landscape.likec4` itself.\n *\n * WHY WARNINGS. Every fact loam grades about a model — its parse, its bindings,\n * its edges into the spine — holds exactly as it did in all five states, so\n * nothing here may gate. The fifth is only true because the architecture loader\n * keeps the map whatever the root `exclude` says (`core/c4/project/architecture.ts`);\n * before it did, an excluded map blanked every cross-service grade in the run. ROADMAP's clause that rendering \"must stay outside\n * validation so view computation cannot slow or change the gate\" is about\n * computing views; this check computes nothing: one `existsSync` per service and\n * one read of the root config. And the sibling that grades the ROOT file's\n * absence (`doctor.likec4-config-missing`, `core/doctor/doctor.ts`) calls a repo\n * without it \"only unrenderable\" and warns; these are the same condition one\n * directory down and earn the same severity.\n *\n * WHY `validate --all` AND NOT `doctor`. `doctor` is the step-0 preflight of the\n * adopt protocol — wiring, the config, the fleet map's readability — and the\n * protocol's step 5 is the `validate --all` run whose findings the agent\n * branches on. The report that motivated the first of these codes had its own\n * `doctor --json` answer `healthy: true` with 0 findings on a tree where every\n * adopted model was unrenderable from the root: the model is written in step 3,\n * so its renderability is a fact that first exists at step 5, and a preflight\n * that ran before the model did could not have said otherwise. Never in\n * `validate --service`, `status` or `doctor`: the writer is a fleet verb\n * (`subsystem sync`) and the findings belong beside the files that verb owns.\n *\n * WHY PER SERVICE. `subject` is the service id so a `--json` worklist filters by\n * team the way `landscape.service-unmodelled` already lets it — one fleet\n * finding listing every gap would have to be re-parsed to find out whose it is.\n * The `scope` location is the service's tree path, through `serviceTreePath` on\n * the ENTRY the survey hands back — never a join by id: these grades are emitted\n * before the map's early returns precisely so they hold on a broken tree, and a\n * tree with two services sharing a leaf name under different subsystems\n * (`subsystem.name-collision`) is exactly such a tree, still enumerated in full.\n * Joined by id, both findings named the first directory while `subsystem sync`\n * wrote both files at the right paths.\n *\n * WHY THE ROOT GATE, and it does double duty. Semantically: `subsystem sync`\n * writes nothing — no per-service file, no rewritten `exclude` — until the root\n * `likec4.config.json` exists (the docs root is then a LikeC4 workspace and a\n * nested project is registered inside it — measured at the 1.59.2 pin), so a\n * repo without the root file has `doctor` telling it to write that first and\n * nothing to sync into; grading a gap the writer would not fill is a loop no\n * command can clear. The same rule silences a directory whose name is not a\n * legal service id: the survey skips it (`render/projects.ts` says why),\n * `service.id-invalid` already names it, and a warning here would advertise a\n * repair `sync` refuses to perform. Fixture-wise: `makeProject` writes NO root\n * file, so every existing fixture stays silent under this gate, and the suites\n * that pin a fleet's warning set exactly (`test/examples.test.ts`,\n * `test/self-model.test.ts`) ship the files their shapes call for and keep their\n * counts.\n *\n * The exclude half has a SECOND gate, inside `readRootExclude`: a root config\n * loam cannot read an `exclude` list out of answers `null`, and both grades that\n * read it stay silent. loam does not know what the renderer will do with a file\n * it could not parse, and asserting an exclusion on evidence it does not have is\n * worse than saying nothing.\n */\nimport { existsSync } from \"node:fs\";\nimport { relative, resolve } from \"node:path\";\nimport type { ModelShape } from \"../../../../core/c4/service-model/shape.js\";\nimport { excludingEntry, excludingPath, readRootExclude } from \"../../../../core/c4/root-project/exclude.js\";\nimport { serviceTreePath, type DocsDir } from \"../../../../core/kernel/ids/dirs.js\";\nimport type { ServiceEntry } from \"../../../../core/repo/entries.js\";\nimport { ARTIFACT_FILES, landscapePath, LIKEC4_PROJECT_FILENAME, rootProjectPath, serviceRenderPaths } from \"../../../../core/repo/paths.js\";\nimport { surveyProjects } from \"../../../../core/repo/tree/render/projects.js\";\nimport type { Finding } from \"../../../../core/vocabulary/report.js\";\n\n/**\n * The five grades, and the one FACT out of them a second check has to branch on.\n *\n * `mapExcluded` is `landscape.excluded`'s own condition, handed out rather than\n * re-derived: `c4.fleet-project-invalid` loads the fleet project the way the\n * RENDERER does — without the architecture loader's floor under the map — so the\n * same entry that hides the map makes every extending model's `extend` fail to\n * resolve, and one bad line in `exclude` came back as 161 warnings on a\n * five-service fleet. Two spellings of \"is the map excluded\" would be two\n * chances for the cause and its cascade to disagree about whether they are\n * looking at the same state, which is exactly the pairing the boolean exists to\n * keep.\n */\nexport interface ProjectGrade {\n findings: Finding[];\n /** True when the root `exclude` covers `architecture/landscape.likec4` — see above. */\n mapExcluded: boolean;\n}\n\n/**\n * `entries` is the fleet enumeration at whatever depth each service lives, and\n * `shapes` is the shape of every model in it, keyed by resolved path\n * (`FleetContext.modelShapes`). The shape map is built over the FULL enumeration\n * rather than a `--base` narrowing: a model missing from it would read as\n * standalone, which is the wrong half of every pair above.\n *\n * The predicate handed into the survey is the ONE spelling of \"has a model,\n * lacks a project file\" that `subsystem sync` also fills, so the grader can\n * never name a gap the writer would leave.\n */\nexport async function projectFindings(\n docsDir: DocsDir,\n entries: readonly ServiceEntry[],\n shapes: ReadonlyMap<string, ModelShape>,\n): Promise<ProjectGrade> {\n // No root project file, no root project — and no `exclude` list either, so the\n // map is not excluded by anything loam can see. `false` here is a fact, not a\n // default: `readRootExclude` would answer `null` one line down and every grade\n // below it stays silent for the same reason.\n if (!existsSync(rootProjectPath(docsDir))) return { findings: [], mapExcluded: false };\n const survey = surveyProjects(entries, serviceRenderPaths, (model) => shapes.get(resolve(model)) !== \"extending\");\n const exclude = await readRootExclude(docsDir);\n const findings: Finding[] = [];\n // The ONE derivation. The boolean is read off the finding rather than computed\n // beside it, so a fleet where `c4.fleet-project-invalid` is suspended is by\n // construction a fleet where `landscape.excluded` says why.\n const excluded = mapExcluded(docsDir, exclude);\n findings.push(...excluded);\n for (const model of survey.models) {\n const tree = serviceTreePath(model.service);\n // Everything the four share, so each push below is its code and its\n // sentence and nothing else. `scope`, not `primary`: two of the four are\n // about a file that does not exist yet, and the actionable place is the\n // directory either way.\n const at = {\n severity: \"warn\" as const,\n subject: model.service.id,\n locations: [{ path: tree, role: \"scope\" as const }],\n };\n if (model.standalone && !model.configured) {\n findings.push({\n ...at,\n code: \"service.likec4-config-missing\",\n message:\n `${model.service.id}: ${tree}/${ARTIFACT_FILES.model} exists and ${tree}/${LIKEC4_PROJECT_FILENAME} does not — ` +\n \"a model that stands alone (declares its own `specification`) renders only as a project of its own, \" +\n \"and nothing renders it from the docs root now. Run `loam subsystem sync`; it writes the file (create-only) — never write it by hand.\",\n });\n }\n if (!model.standalone && model.configured) {\n findings.push({\n ...at,\n code: \"service.likec4-config-stray\",\n message:\n `${model.service.id}: ${tree}/${ARTIFACT_FILES.model} extends the fleet map and ${tree}/${LIKEC4_PROJECT_FILENAME} ` +\n \"sits beside it — the renderer registers that file as a project of its own rooted at that directory, so \" +\n \"the docs root stops being a one-project workspace (`likec4 validate .` then refuses without `--project`), \" +\n \"and wherever that nested project claims the model it parses alone, out of the root project where the \" +\n \"map's kinds are: the model does not resolve and `export json --project fleet` loses this service's \" +\n \"containers (measured, likec4 1.59.2 — which of the two happens depends on the workspace, and neither is \" +\n \"a state this file buys anything in). Run `loam subsystem sync`; it deletes the file (or delete it \" +\n \"yourself). loam never writes one beside an extending model\",\n });\n }\n // `excludingEntry` reports the entry VERBATIM because the repair is to\n // delete or narrow THAT line, and a fleet that files its services under\n // subsystems is excluded by `services/platform/**` rather than by anything\n // naming the service — a message that did not quote the entry would send\n // its reader looking for a line that is not there.\n const entry = exclude === null ? null : excludingEntry(exclude, tree);\n // THE SECOND QUESTION, and the state that was silent until it was asked:\n // an entry shaped like a FILE hides the model without covering the\n // directory. `services/**/model.likec4` and the bare `**/model.likec4` each\n // took every extending model out of the renderer on `examples/docs` — 3\n // source files of 8, five drill-down views gone from the export — with the\n // whole run reporting 0 errors and not one line containing the word\n // \"exclude\" (re-verification 2026-09-04, area C item 5). It is asked ONLY\n // where the directory question said no, because that arm names an entry\n // `subsystem sync` can take back and this one names an entry it cannot.\n const fileEntry =\n exclude === null || entry !== null ? null : excludingPath(exclude, `${tree}/${ARTIFACT_FILES.model}`);\n const hiding = entry ?? fileEntry;\n if (exclude !== null && !model.standalone && hiding !== null) {\n findings.push({\n ...at,\n code: \"service.model-excluded\",\n message:\n `${model.service.id}: ${tree}/${ARTIFACT_FILES.model} extends the fleet map and the root ` +\n `${LIKEC4_PROJECT_FILENAME} excludes it ('${hiding}') — the renderer never loads it, so the service is ` +\n \"a box with nothing inside it from the docs root. \" +\n (entry === null\n ? // The repair is an EDIT, not a command, and saying otherwise is the\n // loop `landscape.excluded` already refuses to open: sync recomputes\n // only the `services/<tree>/**` entries and would report success\n // having changed nothing.\n \"That entry hides the model file without covering \" +\n `${tree}/, so \\`loam subsystem sync\\` cannot repair it: sync maintains only the ` +\n \"`services/` directory entries and leaves every other line exactly as the team wrote it. Narrow that \" +\n \"entry to the paths it was written for, or delete it\"\n : \"Run `loam subsystem sync`: it rewrites the root project's `exclude` to cover exactly the models \" +\n \"that stand alone\"),\n });\n }\n if (exclude !== null && model.standalone && entry === null) {\n findings.push({\n ...at,\n code: \"service.model-unexcluded\",\n message:\n `${model.service.id}: ${tree}/${ARTIFACT_FILES.model} stands alone (declares its own specification) and ` +\n `the root ${LIKEC4_PROJECT_FILENAME} does not exclude ${tree}/ — the renderer merges it into the map ` +\n \"and reports every kind and element it declares as a duplicate, blanking the whole root project. \" +\n `Run \\`loam subsystem sync\\`: it adds ${tree}/** to the root project's \\`exclude\\``,\n });\n }\n }\n return { findings, mapExcluded: excluded.length > 0 };\n}\n\n/**\n * `landscape.excluded` — the root `exclude` covers the fleet MAP itself.\n *\n * WHY IT EXISTS AT ALL, and why only now. The architecture loader used to apply\n * the root `exclude` with no floor under it, so an entry covering\n * `architecture/landscape.likec4` — an `architecture/*.likec4` written for a\n * palette, say — left that project EMPTY, and an empty project parses with zero\n * errors. Every reader downstream took that for \"the map declares nothing\":\n * `landscape.service-unmodelled` on every service, `c4.invalid` on every\n * extending model, `subsystem sync` cutting a good generated file back to a\n * title (verification 2026-09-04, review C). The loader now keeps the map\n * whatever the list says, so loam has stopped asserting those falsehoods — but\n * the RENDERER still applies the entry, and it has no floor. Nothing told the\n * author that the fleet map they are grading is a map nobody can open. This is\n * that sentence, and it is the only finding in the run that names it.\n *\n * WARN, NEVER GATING, for the reason the module banner gives: with the loader's\n * floor in place, every fact loam grades holds identically either way. The gap\n * is a renderer gap, exactly like the four per-service grades above.\n *\n * THE SAME ROOT GATE covers it — the caller returns early with no root\n * `likec4.config.json`, and a config loam cannot read an `exclude` list out of\n * answers `null`, which says nothing rather than guessing. It is gated on the\n * map EXISTING as well: with no file there, `landscape.missing` is the finding\n * and an entry covering a path nobody wrote is not a repair anyone owes.\n *\n * `excludingPath`, not `excludingEntry`: the map is a FILE, and this must fire\n * exactly when `architectureProjectDocuments` would have dropped it — same\n * list, same matcher, same argument. Asking the directory question instead\n * would answer for `architecture/` as a whole and miss `architecture/*.likec4`,\n * which is the spelling that caused the defect.\n *\n * The repair is NOT `loam subsystem sync`, and the message says so where the\n * four grades above name it: sync recomputes only the `services/<tree>/**`\n * entries and leaves every other line in the order the team wrote it, so it\n * would report success and change nothing. The four had a writer; this one has\n * an author.\n *\n * AND IT SUSPENDS `c4.fleet-project-invalid`, which is the cascade discipline\n * `permissions.invalid` and `capability.invalid` already state: a grade that\n * RESOLVES against a document nobody loaded is not a diagnosis. That check\n * builds the fleet project the way the renderer does — no floor under the map —\n * so the very entry named here takes the map out of it and every `extend` in\n * every extending model then resolves against nothing. Measured on\n * `examples/docs` with `architecture/*.likec4` in the list: one\n * `landscape.excluded` and **161** `c4.fleet-project-invalid`, all of them one\n * line's fault. The message carries that clause so the reader knows the fleet\n * project is unread rather than clean, and the caller reads the same fact off\n * `ProjectGrade.mapExcluded` — see `./fleet-project.ts`'s `mapExcluded` gate.\n */\nfunction mapExcluded(docsDir: DocsDir, exclude: readonly string[] | null): Finding[] {\n const map = landscapePath(docsDir);\n if (exclude === null || !existsSync(map)) return [];\n const rel = relative(docsDir, map).split(/[\\\\/]/).join(\"/\");\n const entry = excludingPath(exclude, rel);\n if (entry === null) return [];\n return [\n {\n severity: \"warn\",\n code: \"landscape.excluded\",\n // Quoted VERBATIM, for `service.model-excluded`'s reason one level down:\n // the repair is to edit THAT line, and an entry loam re-spelled is a line\n // its author would go looking for and not find.\n message:\n `landscape: the root ${LIKEC4_PROJECT_FILENAME}'s \\`exclude\\` covers ${rel} ('${entry}') — the renderer never ` +\n \"loads the fleet map, so it draws no map at all and every model that EXTENDS the map resolves against \" +\n \"nothing in the root project, while loam goes on grading the map it reads from disk. `c4.fleet-project-invalid` \" +\n \"is NOT graded while this entry stands: that check loads the fleet project the way the renderer does, so it \" +\n \"would report the same one line as an unresolved reference in every extending model rather than as this. \" +\n \"Remove that entry, or \" +\n `narrow it to the paths it was written for, and the fleet project is graded again. \\`loam subsystem sync\\` ` +\n \"will not do it: that command maintains \" +\n \"only the `services/` entries in the list and leaves every other line exactly as the team wrote it\",\n locations: [{ path: rel, role: \"primary\" }],\n },\n ];\n}\n"]}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The documents the RENDERER's root project loads, enumerated the way the
3
+ * renderer enumerates them: everything under the docs root that the root
4
+ * `likec4.config.json` does not exclude.
5
+ *
6
+ * It exists because `./fleet-project.ts` used to build the set BY SHAPE — the
7
+ * `architecture/` project, each extending `model.likec4`, and every `.likec4`
8
+ * inside a service directory — and that is three roots, not a tree. A `.likec4`
9
+ * one directory ABOVE a service (`services/platform/notes.likec4`, the parent of
10
+ * service directories) was in none of them: `loam validate --all` came back
11
+ * byte-identical to baseline and never named the file, while `npx likec4
12
+ * validate --project fleet .` reported Invalid over nine files and thirteen
13
+ * errors (verification 2026-09-04, R2). The same file one directory lower was a
14
+ * loud error. SCHEMA, `loam-codes` and `explain` all said loam loads "every
15
+ * `.likec4` the root project reads"; this is that sentence, executed.
16
+ *
17
+ * FOUR THINGS COME OUT, and each is a rule rather than a filter of convenience:
18
+ *
19
+ * - Every GENERATED `architecture/` document — `subsystems.likec4` and
20
+ * `services.likec4`, taken from the ONE list every project read shares
21
+ * (`c4/project/architecture.ts`) — for `c4/project/documents.ts`'s reason:
22
+ * docs/DESIGN.md rule 26 makes their staleness a byte compare, and a stale
23
+ * one naming a removed element would blank this load and report a cascade
24
+ * whose repair is `loam subsystem sync`.
25
+ * - Anything the root `exclude` covers, read through `c4/root-project/exclude.ts`
26
+ * — the renderer does not load it, so grading it would be loam reporting a
27
+ * failure nobody can see. A root config loam cannot read an `exclude` list out
28
+ * of covers nothing: guessing an exclusion is worse than loading one document
29
+ * too many.
30
+ * - Every STANDALONE service directory. Such a model declares its own kinds, so
31
+ * the root project must exclude it and `service.model-unexcluded` is the grade
32
+ * for a root that does not — one finding naming the entry to add, rather than
33
+ * a duplicate-kind cascade under a second code.
34
+ * - `features/`. A feature's `delta.likec4` carries a `specification` block of
35
+ * its own and the directory is transient — the scaffolded root config excludes
36
+ * it for exactly that reason, and a fleet mid-feature would otherwise read as
37
+ * a fleet whose map is declared twice. loam drops it whether or not the entry
38
+ * is still there; `loam validate --feature` is where a delta is graded.
39
+ *
40
+ * Dot-directories and `node_modules` are not walked at all. Those are loam's own
41
+ * machinery and a package tree, never authored documents — the same thing the
42
+ * scaffold's own `node_modules` glob says. `.loam-before` is the case that
43
+ * proved it: a snapshot written before layout version 4 holds a verbatim copy
44
+ * of the landscape under its living name, which would read as the map declared
45
+ * twice. Version 4 suffixes every pre-image so the RENDERER cannot take one for
46
+ * a document either (`core/staging/snapshot/manifest.ts`), but the older
47
+ * snapshots are read forever and never migrated, so this walk keeps the rule.
48
+ */
49
+ import { relative, resolve, sep } from "node:path";
50
+ import { excludingPath, readRootExclude } from "../../../../core/c4/root-project/exclude.js";
51
+ import { generatedArchitectureDocuments } from "../../../../core/c4/project/architecture.js";
52
+ import { likec4DocumentsUnder } from "../../../../core/c4/project/documents.js";
53
+ /** The directory name loam never walks, beside every dot-directory. */
54
+ const PACKAGES = "node_modules";
55
+ /** The one subtree loam drops whatever the root config says — see the banner. */
56
+ const FEATURES = "features";
57
+ /**
58
+ * Every `.likec4` the renderer's root project reads and loam can grade, absolute
59
+ * and sorted. `standalone` is each standalone service's directory, absolute.
60
+ */
61
+ export async function rootProjectDocuments(docsDir, standalone) {
62
+ const exclude = await readRootExclude(docsDir);
63
+ const generated = new Set(generatedArchitectureDocuments(docsDir).map((path) => resolve(path)));
64
+ const excluded = standalone.map((dir) => `${resolve(dir)}${sep}`);
65
+ const root = resolve(docsDir);
66
+ const keeps = (path) => {
67
+ if (generated.has(resolve(path)))
68
+ return false;
69
+ if (excluded.some((dir) => resolve(path).startsWith(dir)))
70
+ return false;
71
+ const rel = relative(root, path).split(/[\\/]/);
72
+ if (rel[0] === FEATURES)
73
+ return false;
74
+ return exclude === null || excludingPath(exclude, rel.join("/")) === null;
75
+ };
76
+ // An unreadable directory contributes nothing — `likec4DocumentsUnder`
77
+ // records why a grade inside `validate --all` may never fail the run.
78
+ return likec4DocumentsUnder(root, {
79
+ enters: (name) => !name.startsWith(".") && name !== PACKAGES,
80
+ keeps,
81
+ });
82
+ }
83
+ //# sourceMappingURL=root-documents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-documents.js","sourceRoot":"","sources":["../../../../../src/commands/validate/fleet/views/root-documents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAE7F,OAAO,EAAE,8BAA8B,EAAE,MAAM,6CAA6C,CAAC;AAC7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAEhF,uEAAuE;AACvE,MAAM,QAAQ,GAAG,cAAc,CAAC;AAEhC,iFAAiF;AACjF,MAAM,QAAQ,GAAG,UAAU,CAAC;AAE5B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAgB,EAAE,UAA6B;IACxF,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,8BAA8B,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChG,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;IAClE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,CAAC,IAAY,EAAW,EAAE;QACtC,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAC/C,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACxE,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QACtC,OAAO,OAAO,KAAK,IAAI,IAAI,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC;IAC5E,CAAC,CAAC;IACF,uEAAuE;IACvE,sEAAsE;IACtE,OAAO,oBAAoB,CAAC,IAAI,EAAE;QAChC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,QAAQ;QAC5D,KAAK;KACN,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * The documents the RENDERER's root project loads, enumerated the way the\n * renderer enumerates them: everything under the docs root that the root\n * `likec4.config.json` does not exclude.\n *\n * It exists because `./fleet-project.ts` used to build the set BY SHAPE — the\n * `architecture/` project, each extending `model.likec4`, and every `.likec4`\n * inside a service directory — and that is three roots, not a tree. A `.likec4`\n * one directory ABOVE a service (`services/platform/notes.likec4`, the parent of\n * service directories) was in none of them: `loam validate --all` came back\n * byte-identical to baseline and never named the file, while `npx likec4\n * validate --project fleet .` reported Invalid over nine files and thirteen\n * errors (verification 2026-09-04, R2). The same file one directory lower was a\n * loud error. SCHEMA, `loam-codes` and `explain` all said loam loads \"every\n * `.likec4` the root project reads\"; this is that sentence, executed.\n *\n * FOUR THINGS COME OUT, and each is a rule rather than a filter of convenience:\n *\n * - Every GENERATED `architecture/` document — `subsystems.likec4` and\n * `services.likec4`, taken from the ONE list every project read shares\n * (`c4/project/architecture.ts`) — for `c4/project/documents.ts`'s reason:\n * docs/DESIGN.md rule 26 makes their staleness a byte compare, and a stale\n * one naming a removed element would blank this load and report a cascade\n * whose repair is `loam subsystem sync`.\n * - Anything the root `exclude` covers, read through `c4/root-project/exclude.ts`\n * — the renderer does not load it, so grading it would be loam reporting a\n * failure nobody can see. A root config loam cannot read an `exclude` list out\n * of covers nothing: guessing an exclusion is worse than loading one document\n * too many.\n * - Every STANDALONE service directory. Such a model declares its own kinds, so\n * the root project must exclude it and `service.model-unexcluded` is the grade\n * for a root that does not — one finding naming the entry to add, rather than\n * a duplicate-kind cascade under a second code.\n * - `features/`. A feature's `delta.likec4` carries a `specification` block of\n * its own and the directory is transient — the scaffolded root config excludes\n * it for exactly that reason, and a fleet mid-feature would otherwise read as\n * a fleet whose map is declared twice. loam drops it whether or not the entry\n * is still there; `loam validate --feature` is where a delta is graded.\n *\n * Dot-directories and `node_modules` are not walked at all. Those are loam's own\n * machinery and a package tree, never authored documents — the same thing the\n * scaffold's own `node_modules` glob says. `.loam-before` is the case that\n * proved it: a snapshot written before layout version 4 holds a verbatim copy\n * of the landscape under its living name, which would read as the map declared\n * twice. Version 4 suffixes every pre-image so the RENDERER cannot take one for\n * a document either (`core/staging/snapshot/manifest.ts`), but the older\n * snapshots are read forever and never migrated, so this walk keeps the rule.\n */\nimport { relative, resolve, sep } from \"node:path\";\nimport { excludingPath, readRootExclude } from \"../../../../core/c4/root-project/exclude.js\";\nimport type { DocsDir } from \"../../../../core/kernel/ids/dirs.js\";\nimport { generatedArchitectureDocuments } from \"../../../../core/c4/project/architecture.js\";\nimport { likec4DocumentsUnder } from \"../../../../core/c4/project/documents.js\";\n\n/** The directory name loam never walks, beside every dot-directory. */\nconst PACKAGES = \"node_modules\";\n\n/** The one subtree loam drops whatever the root config says — see the banner. */\nconst FEATURES = \"features\";\n\n/**\n * Every `.likec4` the renderer's root project reads and loam can grade, absolute\n * and sorted. `standalone` is each standalone service's directory, absolute.\n */\nexport async function rootProjectDocuments(docsDir: DocsDir, standalone: readonly string[]): Promise<string[]> {\n const exclude = await readRootExclude(docsDir);\n const generated = new Set(generatedArchitectureDocuments(docsDir).map((path) => resolve(path)));\n const excluded = standalone.map((dir) => `${resolve(dir)}${sep}`);\n const root = resolve(docsDir);\n const keeps = (path: string): boolean => {\n if (generated.has(resolve(path))) return false;\n if (excluded.some((dir) => resolve(path).startsWith(dir))) return false;\n const rel = relative(root, path).split(/[\\\\/]/);\n if (rel[0] === FEATURES) return false;\n return exclude === null || excludingPath(exclude, rel.join(\"/\")) === null;\n };\n // An unreadable directory contributes nothing — `likec4DocumentsUnder`\n // records why a grade inside `validate --all` may never fail the run.\n return likec4DocumentsUnder(root, {\n enters: (name) => !name.startsWith(\".\") && name !== PACKAGES,\n keeps,\n });\n}\n"]}
@@ -0,0 +1,52 @@
1
+ import { serviceViewsPath, subsystemViewsPath } from "../../../../core/repo/paths.js";
2
+ import { serviceViewsState, viewsState } from "../../../../core/repo/tree/render/stale.js";
3
+ export async function viewsStaleFindings(docsDir, tree, map) {
4
+ const subsystems = await viewsState(subsystemViewsPath(docsDir), tree, map);
5
+ const services = await serviceViewsState(serviceViewsPath(docsDir), tree, map);
6
+ return [
7
+ ...staleFinding(subsystems, {
8
+ file: "architecture/subsystems.likec4",
9
+ absent: "does not exist, but the tree has subsystems to mirror",
10
+ leftover: "exists, but the tree has no subsystems — the generated file must be absent",
11
+ what: "one view per subsystem, and every derived scope drawn from it is wrong until it agrees",
12
+ }),
13
+ ...staleFinding(services, {
14
+ file: "architecture/services.likec4",
15
+ absent: "does not exist, but the fleet map draws services this file must mirror",
16
+ leftover: "exists, but the fleet map draws none of the services under services/ — the generated file must be absent",
17
+ what: "one overview view per service the map draws, and every drill-down into a service goes through it, so a " +
18
+ "reader following the map lands on a picture that is wrong until it agrees",
19
+ }),
20
+ ];
21
+ }
22
+ /**
23
+ * One finding, or none — the shape both generated files share, spelled once so
24
+ * they cannot drift into two dialects of the same sentence.
25
+ */
26
+ function staleFinding(state, file) {
27
+ if (state.agrees)
28
+ return [];
29
+ const said = state.actual === null ? file.absent : state.expected === null ? file.leftover : "does not match the tree and the map";
30
+ return [
31
+ {
32
+ severity: "error",
33
+ code: "subsystem.views-stale",
34
+ subject: file.file,
35
+ // The file the message names, so an editor jumping to the finding lands
36
+ // on it. Without a location the report's fallback files this under the
37
+ // TARGET, which is the landscape — a reader was sent to
38
+ // architecture/landscape.likec4 to fix a file the sentence beside it
39
+ // named as architecture/subsystems.likec4. A file that does not exist
40
+ // yet cannot be `primary`: the actionable place is then the directory
41
+ // the regenerator will write into.
42
+ locations: [
43
+ state.actual === null
44
+ ? { path: "architecture", role: "scope" }
45
+ : { path: file.file, role: "primary" },
46
+ ],
47
+ message: `subsystems: ${file.file} ${said} — it is generated, ${file.what}. ` +
48
+ "Run `loam subsystem sync` to regenerate it; never edit it by hand.",
49
+ },
50
+ ];
51
+ }
52
+ //# sourceMappingURL=stale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale.js","sourceRoot":"","sources":["../../../../../src/commands/validate/fleet/views/stale.ts"],"names":[],"mappings":"AAmDA,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACtF,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAmB,MAAM,4CAA4C,CAAC;AAK5G,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAgB,EAAE,IAAe,EAAE,GAAa;IACvF,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IAC5E,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/E,OAAO;QACL,GAAG,YAAY,CAAC,UAAU,EAAE;YAC1B,IAAI,EAAE,gCAAgC;YACtC,MAAM,EAAE,uDAAuD;YAC/D,QAAQ,EAAE,4EAA4E;YACtF,IAAI,EAAE,wFAAwF;SAC/F,CAAC;QACF,GAAG,YAAY,CAAC,QAAQ,EAAE;YACxB,IAAI,EAAE,8BAA8B;YACpC,MAAM,EAAE,wEAAwE;YAChF,QAAQ,EACN,0GAA0G;YAC5G,IAAI,EACF,yGAAyG;gBACzG,2EAA2E;SAC9E,CAAC;KACH,CAAC;AACJ,CAAC;AAcD;;;GAGG;AACH,SAAS,YAAY,CAAC,KAAiB,EAAE,IAAe;IACtD,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAC5B,MAAM,IAAI,GACR,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,qCAAqC,CAAC;IACxH,OAAO;QACL;YACE,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,IAAI,CAAC,IAAI;YAClB,wEAAwE;YACxE,uEAAuE;YACvE,wDAAwD;YACxD,qEAAqE;YACrE,sEAAsE;YACtE,sEAAsE;YACtE,mCAAmC;YACnC,SAAS,EAAE;gBACT,KAAK,CAAC,MAAM,KAAK,IAAI;oBACnB,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,OAAgB,EAAE;oBAClD,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,SAAkB,EAAE;aAClD;YACD,OAAO,EACL,eAAe,IAAI,CAAC,IAAI,IAAI,IAAI,uBAAuB,IAAI,CAAC,IAAI,IAAI;gBACpE,oEAAoE;SACvE;KACF,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Staleness of the GENERATED documents under `architecture/` against the tree\n * and the map: ONE error per stale file, naming that file, repaired by exactly\n * one command (`loam subsystem sync`).\n *\n * TWO FILES, ONE CODE, and that is a decision rather than an omission.\n * `subsystems.likec4` (one view per subsystem) and `services.likec4` (one\n * overview view per service the map draws) are written by the same command in\n * the same commit, drift for overlapping reasons — a `subsystem move` restales\n * both, because a per-service view's title is `<subsystem path> / <service\n * id>` — and are repaired by the same run. A second code would buy a reader\n * nothing the `subject` and the message do not already say, and every code costs\n * a row in `core/agent/workflows/check.ts`, a `loam explain` entry and a place in\n * the vocabulary. What DOES have to stay apart is which file drifted, so the two\n * are graded separately and each finding carries its own path — folding them\n * into one finding would lose the only thing the message has to say.\n *\n * A content compare, deliberately — never a parse. A views-only document does\n * not parse standalone (its `include` lines reference elements the landscape\n * defines; the spike in `core/repo/tree/render/views.ts` records it), and no check\n * anywhere reads the file's MEANING: the file is a scoping convenience for\n * the LikeC4 renderer, so the only question loam owes it is \"is this what the\n * tree renders to\". Rule 26 leaves this untouched: what loam may\n * read is a `dynamic view`'s declared steps out of a document it already\n * parses — never a static view's `include` predicates, and never this\n * generated file at all. Absent counts as a state of its own: a fleet\n * with subsystems and no file is stale, and a fleet with NO subsystems and a\n * leftover file is stale too — the render contract says the file must then\n * not exist, or a group deleted months ago keeps a view forever.\n *\n * The compare is over CONTENT, not BYTES, and `viewsAgree` in\n * `core/repo/tree/render/views.ts` both performs it and records why: an ordinary\n * Windows clone hands this file back with CRLF and not one fact in it changed,\n * and under a byte compare the advertised repair is a loop rather than a\n * diagnosis. The rule lives beside the generator because the module that mints\n * the bytes is the one that owes an answer about them.\n *\n * Graded only when the landscape PARSED (the caller holds that gate): the\n * expected bytes resolve members through the landscape's element→service\n * join, and grading them against a map that is missing or unreadable would\n * cascade a second error behind `landscape.missing`/`landscape.invalid`,\n * pointing at a file whose repair command would only re-derive the same\n * incomplete answer.\n *\n * The map arrives as the parsed document's facts — its elements AND the\n * global style ids it declares — because the expected bytes now depend on\n * both: a view references `global style subsystems` exactly when the project\n * declares that id, so a fleet that declares it sees this finding once, until\n * the next `sync` writes the line.\n */\nimport type { DocsDir } from \"../../../../core/kernel/ids/dirs.js\";\nimport { serviceViewsPath, subsystemViewsPath } from \"../../../../core/repo/paths.js\";\nimport { serviceViewsState, viewsState, type ViewsState } from \"../../../../core/repo/tree/render/stale.js\";\nimport type { MapFacts } from \"../../../../core/repo/tree/render/views.js\";\nimport type { FleetTree } from \"../../../../core/repo/tree/walk.js\";\nimport type { Finding } from \"../../../../core/vocabulary/report.js\";\n\nexport async function viewsStaleFindings(docsDir: DocsDir, tree: FleetTree, map: MapFacts): Promise<Finding[]> {\n const subsystems = await viewsState(subsystemViewsPath(docsDir), tree, map);\n const services = await serviceViewsState(serviceViewsPath(docsDir), tree, map);\n return [\n ...staleFinding(subsystems, {\n file: \"architecture/subsystems.likec4\",\n absent: \"does not exist, but the tree has subsystems to mirror\",\n leftover: \"exists, but the tree has no subsystems — the generated file must be absent\",\n what: \"one view per subsystem, and every derived scope drawn from it is wrong until it agrees\",\n }),\n ...staleFinding(services, {\n file: \"architecture/services.likec4\",\n absent: \"does not exist, but the fleet map draws services this file must mirror\",\n leftover:\n \"exists, but the fleet map draws none of the services under services/ — the generated file must be absent\",\n what:\n \"one overview view per service the map draws, and every drill-down into a service goes through it, so a \" +\n \"reader following the map lands on a picture that is wrong until it agrees\",\n }),\n ];\n}\n\n/** The four sentences one file's finding differs by — the rest of it is shared. */\ninterface StaleFile {\n /** The docs-relative path, which is the subject, the location and the head of the message. */\n file: string;\n /** Why an absent file is stale. */\n absent: string;\n /** Why a present file that must not exist is stale. */\n leftover: string;\n /** What the file holds, and what is wrong while it disagrees. */\n what: string;\n}\n\n/**\n * One finding, or none — the shape both generated files share, spelled once so\n * they cannot drift into two dialects of the same sentence.\n */\nfunction staleFinding(state: ViewsState, file: StaleFile): Finding[] {\n if (state.agrees) return [];\n const said =\n state.actual === null ? file.absent : state.expected === null ? file.leftover : \"does not match the tree and the map\";\n return [\n {\n severity: \"error\",\n code: \"subsystem.views-stale\",\n subject: file.file,\n // The file the message names, so an editor jumping to the finding lands\n // on it. Without a location the report's fallback files this under the\n // TARGET, which is the landscape — a reader was sent to\n // architecture/landscape.likec4 to fix a file the sentence beside it\n // named as architecture/subsystems.likec4. A file that does not exist\n // yet cannot be `primary`: the actionable place is then the directory\n // the regenerator will write into.\n locations: [\n state.actual === null\n ? { path: \"architecture\", role: \"scope\" as const }\n : { path: file.file, role: \"primary\" as const },\n ],\n message:\n `subsystems: ${file.file} ${said} — it is generated, ${file.what}. ` +\n \"Run `loam subsystem sync` to regenerate it; never edit it by hand.\",\n },\n ];\n}\n"]}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Where each target's link findings are filed — the ORDER, not the rule.
3
+ *
4
+ * The rule lives in `core/links/`: extract the links, resolve them, name the
5
+ * ones that point at nothing. WHICH documents belong to a service, a feature or
6
+ * the fleet lives there too (`core/links/corpus.ts`), because the glossary's
7
+ * backlink index reads the same list and a second enumeration would be free to
8
+ * disagree with this one. What is left here is the part that belongs to
9
+ * `validate`: reading each document, deciding which target carries the finding,
10
+ * and refusing to let one unreadable file take a whole target down with it.
11
+ */
12
+ import { existsSync } from "node:fs";
13
+ import { pathCaseIndex } from "../../../core/links/case.js";
14
+ import { featureDocuments, fleetDocuments, serviceDocuments } from "../../../core/links/corpus.js";
15
+ import { unresolvedLinkFindings } from "../../../core/links/findings.js";
16
+ import { featureGlossaryOverlay } from "../../../core/glossary/delta.js";
17
+ import {} from "../../../core/repo/paths.js";
18
+ import { repoPath } from "../../../core/envelope/json.js";
19
+ import { FleetContext } from "../../../core/fleet-context.js";
20
+ import {} from "../../../core/vocabulary/report.js";
21
+ /** One service's documents, graded on the service target. */
22
+ export async function serviceLinkFindings(check, paths) {
23
+ return documentFindings(await serviceDocuments(paths), check);
24
+ }
25
+ /**
26
+ * One feature's documents, graded on the feature target — with the glossary
27
+ * terms it introduces treated as already living. See `LinkScope.overlay`: a
28
+ * feature cites the word it is adding at that word's future path, and an index
29
+ * built from the living tree alone would refuse the axis's own headline case.
30
+ */
31
+ export async function featureLinkFindings(check, featureDir) {
32
+ return documentFindings(await featureDocuments(featureDir, check.fleet), {
33
+ ...check,
34
+ overlay: await featureGlossaryOverlay(check.docsDir, featureDir),
35
+ });
36
+ }
37
+ /**
38
+ * The fleet's own documents — its ADRs, the living capability tree and the
39
+ * glossary — graded once on the landscape target. A single-target run says
40
+ * nothing about them, the rule `permissions.unenforced` already follows: a
41
+ * finding about the fleet repeated on every service target is the report.
42
+ */
43
+ export async function fleetLinkFindings(check) {
44
+ return documentFindings(await fleetDocuments(check.docsDir, check.fleet), check);
45
+ }
46
+ /**
47
+ * Grade a list of documents, skipping the ones that are not there.
48
+ *
49
+ * ABSENCE IS NOT THIS CHECK'S BUSINESS: `service.no-spec` already names a
50
+ * missing `spec.md`, and most services have no runbook and no ADRs at all.
51
+ *
52
+ * AN UNREADABLE DOCUMENT IS NAMED HERE RATHER THAN THROWN, and that is what
53
+ * `link.unreadable` is for. Every other reader of a service's documents is
54
+ * wrapped by `report.ts`'s `guarded`, which turns an IO failure into
55
+ * `service.unreadable` — "nothing about this service was checked". That verdict
56
+ * is right for `spec.md` and wrong for an ADR: this check is the first to read
57
+ * those files at all, and a runbook saved as UTF-16 must not be able to blank
58
+ * a service's entire report when the only thing that could not be graded is one
59
+ * document's links.
60
+ */
61
+ async function documentFindings(paths, check) {
62
+ const findings = [];
63
+ // One directory-listing memo for this target's whole corpus. Built here
64
+ // rather than per document because a service's ADRs all resolve through the
65
+ // same two or three directories, and rather than at module scope because a
66
+ // listing that outlived the command would answer for a tree that has moved.
67
+ const scope = { ...check, cases: pathCaseIndex() };
68
+ for (const path of paths) {
69
+ if (!existsSync(path))
70
+ continue;
71
+ let text;
72
+ try {
73
+ text = await check.fleet.readText(path);
74
+ }
75
+ catch (err) {
76
+ findings.push({
77
+ severity: "error",
78
+ code: "link.unreadable",
79
+ ...(check.subject === undefined ? {} : { subject: check.subject }),
80
+ message: `${repoPath(check.docsDir, path)} could not be read, so its links were not checked — ` +
81
+ `${err instanceof Error ? err.message : String(err)}`,
82
+ });
83
+ continue;
84
+ }
85
+ findings.push(...unresolvedLinkFindings({ path, text }, scope));
86
+ }
87
+ return findings;
88
+ }
89
+ //# sourceMappingURL=corpus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus.js","sourceRoot":"","sources":["../../../../src/commands/validate/links/corpus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACnG,OAAO,EAAE,sBAAsB,EAAkB,MAAM,iCAAiC,CAAC;AACzF,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAqB,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAgB,MAAM,oCAAoC,CAAC;AAalE,6DAA6D;AAC7D,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAgB,EAAE,KAAmB;IAC7E,OAAO,gBAAgB,CAAC,MAAM,gBAAgB,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;AAChE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAgB,EAAE,UAAsB;IAChF,OAAO,gBAAgB,CAAC,MAAM,gBAAgB,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;QACvE,GAAG,KAAK;QACR,OAAO,EAAE,MAAM,sBAAsB,CAAC,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC;KACjE,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAAgB;IACtD,OAAO,gBAAgB,CAAC,MAAM,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;AACnF,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,KAAK,UAAU,gBAAgB,CAAC,KAAe,EAAE,KAAgB;IAC/D,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,wEAAwE;IACxE,4EAA4E;IAC5E,2EAA2E;IAC3E,4EAA4E;IAC5E,MAAM,KAAK,GAAc,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,CAAC;IAC9D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAChC,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,OAAO;gBACjB,IAAI,EAAE,iBAAiB;gBACvB,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClE,OAAO,EACL,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,sDAAsD;oBACtF,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;aACxD,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["/**\n * Where each target's link findings are filed — the ORDER, not the rule.\n *\n * The rule lives in `core/links/`: extract the links, resolve them, name the\n * ones that point at nothing. WHICH documents belong to a service, a feature or\n * the fleet lives there too (`core/links/corpus.ts`), because the glossary's\n * backlink index reads the same list and a second enumeration would be free to\n * disagree with this one. What is left here is the part that belongs to\n * `validate`: reading each document, deciding which target carries the finding,\n * and refusing to let one unreadable file take a whole target down with it.\n */\nimport { existsSync } from \"node:fs\";\nimport { pathCaseIndex } from \"../../../core/links/case.js\";\nimport { featureDocuments, fleetDocuments, serviceDocuments } from \"../../../core/links/corpus.js\";\nimport { unresolvedLinkFindings, type LinkScope } from \"../../../core/links/findings.js\";\nimport { featureGlossaryOverlay } from \"../../../core/glossary/delta.js\";\nimport { type ServicePaths } from \"../../../core/repo/paths.js\";\nimport { repoPath } from \"../../../core/envelope/json.js\";\nimport { FleetContext } from \"../../../core/fleet-context.js\";\nimport { type Finding } from \"../../../core/vocabulary/report.js\";\nimport type { DocsDir, FeatureDir } from \"../../../core/kernel/ids/dirs.js\";\n\n/** Where the findings are filed, and how the documents are read. */\nexport interface LinkCheck {\n docsDir: DocsDir;\n /** The service or feature the report is about; absent at fleet scope. */\n subject?: string;\n fleet: FleetContext;\n /** Paths an in-flight feature will create — `LinkScope.overlay` says why. */\n overlay?: ReadonlySet<string>;\n}\n\n/** One service's documents, graded on the service target. */\nexport async function serviceLinkFindings(check: LinkCheck, paths: ServicePaths): Promise<Finding[]> {\n return documentFindings(await serviceDocuments(paths), check);\n}\n\n/**\n * One feature's documents, graded on the feature target — with the glossary\n * terms it introduces treated as already living. See `LinkScope.overlay`: a\n * feature cites the word it is adding at that word's future path, and an index\n * built from the living tree alone would refuse the axis's own headline case.\n */\nexport async function featureLinkFindings(check: LinkCheck, featureDir: FeatureDir): Promise<Finding[]> {\n return documentFindings(await featureDocuments(featureDir, check.fleet), {\n ...check,\n overlay: await featureGlossaryOverlay(check.docsDir, featureDir),\n });\n}\n\n/**\n * The fleet's own documents — its ADRs, the living capability tree and the\n * glossary — graded once on the landscape target. A single-target run says\n * nothing about them, the rule `permissions.unenforced` already follows: a\n * finding about the fleet repeated on every service target is the report.\n */\nexport async function fleetLinkFindings(check: LinkCheck): Promise<Finding[]> {\n return documentFindings(await fleetDocuments(check.docsDir, check.fleet), check);\n}\n\n/**\n * Grade a list of documents, skipping the ones that are not there.\n *\n * ABSENCE IS NOT THIS CHECK'S BUSINESS: `service.no-spec` already names a\n * missing `spec.md`, and most services have no runbook and no ADRs at all.\n *\n * AN UNREADABLE DOCUMENT IS NAMED HERE RATHER THAN THROWN, and that is what\n * `link.unreadable` is for. Every other reader of a service's documents is\n * wrapped by `report.ts`'s `guarded`, which turns an IO failure into\n * `service.unreadable` — \"nothing about this service was checked\". That verdict\n * is right for `spec.md` and wrong for an ADR: this check is the first to read\n * those files at all, and a runbook saved as UTF-16 must not be able to blank\n * a service's entire report when the only thing that could not be graded is one\n * document's links.\n */\nasync function documentFindings(paths: string[], check: LinkCheck): Promise<Finding[]> {\n const findings: Finding[] = [];\n // One directory-listing memo for this target's whole corpus. Built here\n // rather than per document because a service's ADRs all resolve through the\n // same two or three directories, and rather than at module scope because a\n // listing that outlived the command would answer for a tree that has moved.\n const scope: LinkScope = { ...check, cases: pathCaseIndex() };\n for (const path of paths) {\n if (!existsSync(path)) continue;\n let text: string;\n try {\n text = await check.fleet.readText(path);\n } catch (err) {\n findings.push({\n severity: \"error\",\n code: \"link.unreadable\",\n ...(check.subject === undefined ? {} : { subject: check.subject }),\n message:\n `${repoPath(check.docsDir, path)} could not be read, so its links were not checked — ` +\n `${err instanceof Error ? err.message : String(err)}`,\n });\n continue;\n }\n findings.push(...unresolvedLinkFindings({ path, text }, scope));\n }\n return findings;\n}\n"]}