@ybotok/loam 0.2.0-alpha.1 → 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 (901) hide show
  1. package/CHANGELOG.md +3448 -0
  2. package/COMPARISON.md +91 -3
  3. package/CONTRIBUTING.md +37 -0
  4. package/MIGRATING-from-OpenSpec.md +47 -23
  5. package/QUICKSTART.md +189 -12
  6. package/README.md +274 -65
  7. package/ROADMAP.md +572 -31
  8. package/SCHEMA.md +1709 -155
  9. package/WORKFLOW.md +298 -72
  10. package/dist/cli.js +26 -8
  11. package/dist/cli.js.map +1 -1
  12. package/dist/commands/adopt/adopt.js +5 -10
  13. package/dist/commands/adopt/adopt.js.map +1 -1
  14. package/dist/commands/adopt/render.js +50 -9
  15. package/dist/commands/adopt/render.js.map +1 -1
  16. package/dist/commands/archive/archive.js +16 -19
  17. package/dist/commands/archive/archive.js.map +1 -1
  18. package/dist/commands/archive/closing.js +42 -0
  19. package/dist/commands/archive/closing.js.map +1 -0
  20. package/dist/commands/archive/plan/contracts/asyncapi.js +36 -42
  21. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -1
  22. package/dist/commands/archive/plan/contracts/consumers.js +56 -0
  23. package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
  24. package/dist/commands/archive/plan/contracts/openapi.js +77 -43
  25. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -1
  26. package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
  27. package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
  28. package/dist/commands/archive/plan/document/head.js +151 -0
  29. package/dist/commands/archive/plan/document/head.js.map +1 -0
  30. package/dist/commands/archive/plan/document/links.js +284 -0
  31. package/dist/commands/archive/plan/document/links.js.map +1 -0
  32. package/dist/commands/archive/plan/document/run.js +136 -0
  33. package/dist/commands/archive/plan/document/run.js.map +1 -0
  34. package/dist/commands/archive/plan/gate.js +21 -19
  35. package/dist/commands/archive/plan/gate.js.map +1 -1
  36. package/dist/commands/archive/plan/landscape.js +167 -30
  37. package/dist/commands/archive/plan/landscape.js.map +1 -1
  38. package/dist/commands/archive/plan/model/extending.js +85 -0
  39. package/dist/commands/archive/plan/model/extending.js.map +1 -0
  40. package/dist/commands/archive/plan/refusal.js +14 -19
  41. package/dist/commands/archive/plan/refusal.js.map +1 -1
  42. package/dist/commands/archive/plan/specs.js +137 -56
  43. package/dist/commands/archive/plan/specs.js.map +1 -1
  44. package/dist/commands/archive/plan/state.js +3 -0
  45. package/dist/commands/archive/plan/state.js.map +1 -1
  46. package/dist/commands/archive/run.js +134 -30
  47. package/dist/commands/archive/run.js.map +1 -1
  48. package/dist/commands/archive/shipped.js +49 -0
  49. package/dist/commands/archive/shipped.js.map +1 -0
  50. package/dist/commands/context/context.js +85 -18
  51. package/dist/commands/context/context.js.map +1 -1
  52. package/dist/commands/context/print.js +29 -7
  53. package/dist/commands/context/print.js.map +1 -1
  54. package/dist/commands/delta/delta.js +102 -14
  55. package/dist/commands/delta/delta.js.map +1 -1
  56. package/dist/commands/delta/print.js +17 -1
  57. package/dist/commands/delta/print.js.map +1 -1
  58. package/dist/commands/dependencies.js +3 -7
  59. package/dist/commands/dependencies.js.map +1 -1
  60. package/dist/commands/diff/diff.js +20 -27
  61. package/dist/commands/diff/diff.js.map +1 -1
  62. package/dist/commands/doctor.js +60 -1
  63. package/dist/commands/doctor.js.map +1 -1
  64. package/dist/commands/explain/explain.js +89 -13
  65. package/dist/commands/explain/explain.js.map +1 -1
  66. package/dist/commands/explore.js +16 -10
  67. package/dist/commands/explore.js.map +1 -1
  68. package/dist/commands/gate/gate.js +45 -8
  69. package/dist/commands/gate/gate.js.map +1 -1
  70. package/dist/commands/gate/print.js +15 -3
  71. package/dist/commands/gate/print.js.map +1 -1
  72. package/dist/commands/gherkin/commit.js +13 -54
  73. package/dist/commands/gherkin/commit.js.map +1 -1
  74. package/dist/commands/gherkin/gherkin.js +36 -20
  75. package/dist/commands/gherkin/gherkin.js.map +1 -1
  76. package/dist/commands/gherkin/reconcile.js +10 -13
  77. package/dist/commands/gherkin/reconcile.js.map +1 -1
  78. package/dist/commands/init/first-hour.js +44 -0
  79. package/dist/commands/init/first-hour.js.map +1 -1
  80. package/dist/commands/init/init.js +18 -22
  81. package/dist/commands/init/init.js.map +1 -1
  82. package/dist/commands/list/campaign/campaign.js +4 -6
  83. package/dist/commands/list/campaign/campaign.js.map +1 -1
  84. package/dist/commands/list/json.js +5 -7
  85. package/dist/commands/list/json.js.map +1 -1
  86. package/dist/commands/list/list.js +44 -29
  87. package/dist/commands/list/list.js.map +1 -1
  88. package/dist/commands/list/print.js +52 -9
  89. package/dist/commands/list/print.js.map +1 -1
  90. package/dist/commands/list/suites/suites.js +140 -0
  91. package/dist/commands/list/suites/suites.js.map +1 -0
  92. package/dist/commands/list/views.js +37 -34
  93. package/dist/commands/list/views.js.map +1 -1
  94. package/dist/commands/mcp/dispatch.js +91 -36
  95. package/dist/commands/mcp/dispatch.js.map +1 -1
  96. package/dist/commands/mcp/mcp.js +56 -15
  97. package/dist/commands/mcp/mcp.js.map +1 -1
  98. package/dist/commands/mcp/serve.js.map +1 -1
  99. package/dist/commands/migrate-openspec/materialize/active.js +27 -22
  100. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -1
  101. package/dist/commands/migrate-openspec/materialize/stage.js +4 -3
  102. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -1
  103. package/dist/commands/migrate-openspec/materialize/target.js +2 -2
  104. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -1
  105. package/dist/commands/migrate-openspec/openspec/decisions.js +9 -14
  106. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -1
  107. package/dist/commands/migrate-openspec/openspec/error.js +7 -8
  108. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -1
  109. package/dist/commands/migrate-openspec/openspec/mapping.js +1 -9
  110. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -1
  111. package/dist/commands/migrate-openspec/openspec/paths.js +3 -6
  112. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -1
  113. package/dist/commands/new/capability-template.js +118 -0
  114. package/dist/commands/new/capability-template.js.map +1 -0
  115. package/dist/commands/new/commit.js +8 -22
  116. package/dist/commands/new/commit.js.map +1 -1
  117. package/dist/commands/new/modifies.js +206 -0
  118. package/dist/commands/new/modifies.js.map +1 -0
  119. package/dist/commands/new/new.js +59 -14
  120. package/dist/commands/new/new.js.map +1 -1
  121. package/dist/commands/new/templates.js +48 -124
  122. package/dist/commands/new/templates.js.map +1 -1
  123. package/dist/commands/open.js +3 -7
  124. package/dist/commands/open.js.map +1 -1
  125. package/dist/commands/policy/gate.js +27 -0
  126. package/dist/commands/policy/gate.js.map +1 -1
  127. package/dist/commands/rebase/plan.js +2 -2
  128. package/dist/commands/rebase/plan.js.map +1 -1
  129. package/dist/commands/rebase/rebase.js +60 -35
  130. package/dist/commands/rebase/rebase.js.map +1 -1
  131. package/dist/commands/seed/commit.js +55 -26
  132. package/dist/commands/seed/commit.js.map +1 -1
  133. package/dist/commands/seed/plan.js +158 -13
  134. package/dist/commands/seed/plan.js.map +1 -1
  135. package/dist/commands/seed/seed.js +13 -11
  136. package/dist/commands/seed/seed.js.map +1 -1
  137. package/dist/commands/show/feature.js +9 -5
  138. package/dist/commands/show/feature.js.map +1 -1
  139. package/dist/commands/show/introduced.js +157 -0
  140. package/dist/commands/show/introduced.js.map +1 -0
  141. package/dist/commands/show/marks.js +35 -6
  142. package/dist/commands/show/marks.js.map +1 -1
  143. package/dist/commands/show/service.js +41 -33
  144. package/dist/commands/show/service.js.map +1 -1
  145. package/dist/commands/show/show.js +17 -7
  146. package/dist/commands/show/show.js.map +1 -1
  147. package/dist/commands/status/fleet-next.js +90 -0
  148. package/dist/commands/status/fleet-next.js.map +1 -0
  149. package/dist/commands/status/json.js +2 -0
  150. package/dist/commands/status/json.js.map +1 -1
  151. package/dist/commands/status/print.js +89 -37
  152. package/dist/commands/status/print.js.map +1 -1
  153. package/dist/commands/status/status.js +3 -7
  154. package/dist/commands/status/status.js.map +1 -1
  155. package/dist/commands/steps/steps.js +103 -23
  156. package/dist/commands/steps/steps.js.map +1 -1
  157. package/dist/commands/subsystem/edit.js +7 -7
  158. package/dist/commands/subsystem/edit.js.map +1 -1
  159. package/dist/commands/subsystem/move.js +106 -46
  160. package/dist/commands/subsystem/move.js.map +1 -1
  161. package/dist/commands/subsystem/query.js +2 -4
  162. package/dist/commands/subsystem/query.js.map +1 -1
  163. package/dist/commands/subsystem/subsystem.js +4 -7
  164. package/dist/commands/subsystem/subsystem.js.map +1 -1
  165. package/dist/commands/subsystem/sync.js +289 -74
  166. package/dist/commands/subsystem/sync.js.map +1 -1
  167. package/dist/commands/subsystem/txn/exclude.js +132 -0
  168. package/dist/commands/subsystem/txn/exclude.js.map +1 -0
  169. package/dist/commands/subsystem/txn/links.js +128 -0
  170. package/dist/commands/subsystem/txn/links.js.map +1 -0
  171. package/dist/commands/subsystem/txn/report.js +174 -0
  172. package/dist/commands/subsystem/txn/report.js.map +1 -0
  173. package/dist/commands/subsystem/txn/txn.js +147 -45
  174. package/dist/commands/subsystem/txn/txn.js.map +1 -1
  175. package/dist/commands/subsystem/txn/views.js +200 -21
  176. package/dist/commands/subsystem/txn/views.js.map +1 -1
  177. package/dist/commands/tasks/actions.js +107 -0
  178. package/dist/commands/tasks/actions.js.map +1 -0
  179. package/dist/commands/tasks/render.js +253 -0
  180. package/dist/commands/tasks/render.js.map +1 -0
  181. package/dist/commands/tasks/tasks.js +119 -0
  182. package/dist/commands/tasks/tasks.js.map +1 -0
  183. package/dist/commands/unarchive/manifest.js +42 -26
  184. package/dist/commands/unarchive/manifest.js.map +1 -1
  185. package/dist/commands/unarchive/restore.js +83 -33
  186. package/dist/commands/unarchive/restore.js.map +1 -1
  187. package/dist/commands/unarchive/unarchive.js +22 -30
  188. package/dist/commands/unarchive/unarchive.js.map +1 -1
  189. package/dist/commands/validate/arch-coverage.js +78 -27
  190. package/dist/commands/validate/arch-coverage.js.map +1 -1
  191. package/dist/commands/validate/checks/fleet-shape.js +34 -126
  192. package/dist/commands/validate/checks/fleet-shape.js.map +1 -1
  193. package/dist/commands/validate/checks/health-deps.js +9 -6
  194. package/dist/commands/validate/checks/health-deps.js.map +1 -1
  195. package/dist/commands/validate/checks/introduced.js +102 -0
  196. package/dist/commands/validate/checks/introduced.js.map +1 -0
  197. package/dist/commands/validate/checks/requirements.js +18 -8
  198. package/dist/commands/validate/checks/requirements.js.map +1 -1
  199. package/dist/commands/validate/checks/sources.js +11 -2
  200. package/dist/commands/validate/checks/sources.js.map +1 -1
  201. package/dist/commands/validate/coverage/covers-after.js +105 -0
  202. package/dist/commands/validate/coverage/covers-after.js.map +1 -0
  203. package/dist/commands/validate/feature.js +26 -20
  204. package/dist/commands/validate/feature.js.map +1 -1
  205. package/dist/commands/validate/fleet/census.js +37 -13
  206. package/dist/commands/validate/fleet/census.js.map +1 -1
  207. package/dist/commands/validate/fleet/landscape.js +144 -126
  208. package/dist/commands/validate/fleet/landscape.js.map +1 -1
  209. package/dist/commands/validate/fleet/load.js +66 -0
  210. package/dist/commands/validate/fleet/load.js.map +1 -1
  211. package/dist/commands/validate/fleet/map/attest.js +98 -0
  212. package/dist/commands/validate/fleet/map/attest.js.map +1 -0
  213. package/dist/commands/validate/fleet/map/bindings.js +107 -0
  214. package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
  215. package/dist/commands/validate/fleet/map/consumers.js +244 -0
  216. package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
  217. package/dist/commands/validate/fleet/map/isolation.js +116 -0
  218. package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
  219. package/dist/commands/validate/fleet/map/usecases.js +54 -0
  220. package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
  221. package/dist/commands/validate/fleet/obligations.js +44 -14
  222. package/dist/commands/validate/fleet/obligations.js.map +1 -1
  223. package/dist/commands/validate/fleet/scorecard/print.js +10 -2
  224. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -1
  225. package/dist/commands/validate/fleet/scorecard/scorecard.js +17 -11
  226. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -1
  227. package/dist/commands/validate/fleet/usecases/place.js.map +1 -1
  228. package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
  229. package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
  230. package/dist/commands/validate/fleet/views/ids.js +50 -15
  231. package/dist/commands/validate/fleet/views/ids.js.map +1 -1
  232. package/dist/commands/validate/fleet/views/projects.js +278 -0
  233. package/dist/commands/validate/fleet/views/projects.js.map +1 -0
  234. package/dist/commands/validate/fleet/views/root-documents.js +83 -0
  235. package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
  236. package/dist/commands/validate/fleet/views/stale.js +40 -47
  237. package/dist/commands/validate/fleet/views/stale.js.map +1 -1
  238. package/dist/commands/validate/links/corpus.js +1 -4
  239. package/dist/commands/validate/links/corpus.js.map +1 -1
  240. package/dist/commands/validate/links/glossary.js.map +1 -1
  241. package/dist/commands/validate/render/repeats.js +63 -0
  242. package/dist/commands/validate/render/repeats.js.map +1 -0
  243. package/dist/commands/validate/render/rollups.js +115 -0
  244. package/dist/commands/validate/render/rollups.js.map +1 -0
  245. package/dist/commands/validate/render/text.js +199 -0
  246. package/dist/commands/validate/render/text.js.map +1 -0
  247. package/dist/commands/validate/report.js +36 -160
  248. package/dist/commands/validate/report.js.map +1 -1
  249. package/dist/commands/validate/scope.js +113 -0
  250. package/dist/commands/validate/scope.js.map +1 -0
  251. package/dist/commands/validate/service/api.js +21 -107
  252. package/dist/commands/validate/service/api.js.map +1 -1
  253. package/dist/commands/validate/service/contracts/generated.js +134 -0
  254. package/dist/commands/validate/service/contracts/generated.js.map +1 -0
  255. package/dist/commands/validate/service/events/events.js +36 -14
  256. package/dist/commands/validate/service/events/events.js.map +1 -1
  257. package/dist/commands/validate/service/events/message-producers.js +1 -1
  258. package/dist/commands/validate/service/events/message-producers.js.map +1 -1
  259. package/dist/commands/validate/service/evidence-pins.js +56 -10
  260. package/dist/commands/validate/service/evidence-pins.js.map +1 -1
  261. package/dist/commands/validate/service/model/diverged.js +226 -0
  262. package/dist/commands/validate/service/model/diverged.js.map +1 -0
  263. package/dist/commands/validate/service/model/grade.js +163 -0
  264. package/dist/commands/validate/service/model/grade.js.map +1 -0
  265. package/dist/commands/validate/service/service.js +121 -61
  266. package/dist/commands/validate/service/service.js.map +1 -1
  267. package/dist/commands/validate/service/specs.js +88 -28
  268. package/dist/commands/validate/service/specs.js.map +1 -1
  269. package/dist/commands/validate/service/spine.js +38 -3
  270. package/dist/commands/validate/service/spine.js.map +1 -1
  271. package/dist/commands/validate/service/usecases/tags.js +113 -0
  272. package/dist/commands/validate/service/usecases/tags.js.map +1 -0
  273. package/dist/commands/validate/service/usecases/usecases.js +209 -0
  274. package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
  275. package/dist/commands/validate/validate.js +85 -60
  276. package/dist/commands/validate/validate.js.map +1 -1
  277. package/dist/commands/verify/cross/diff.js +2 -6
  278. package/dist/commands/verify/cross/diff.js.map +1 -1
  279. package/dist/commands/verify/evidence/contract.js +1 -1
  280. package/dist/commands/verify/evidence/contract.js.map +1 -1
  281. package/dist/commands/verify/evidence/read.js +12 -3
  282. package/dist/commands/verify/evidence/read.js.map +1 -1
  283. package/dist/commands/verify/frozen.js +45 -23
  284. package/dist/commands/verify/frozen.js.map +1 -1
  285. package/dist/commands/verify/record.js +69 -17
  286. package/dist/commands/verify/record.js.map +1 -1
  287. package/dist/commands/verify/report.js +27 -44
  288. package/dist/commands/verify/report.js.map +1 -1
  289. package/dist/commands/verify/results.js +112 -30
  290. package/dist/commands/verify/results.js.map +1 -1
  291. package/dist/commands/verify/verify.js +55 -52
  292. package/dist/commands/verify/verify.js.map +1 -1
  293. package/dist/commands/vouch/pack/pack.js +2 -2
  294. package/dist/commands/vouch/pack/pack.js.map +1 -1
  295. package/dist/commands/vouch/pack/print.js +1 -6
  296. package/dist/commands/vouch/pack/print.js.map +1 -1
  297. package/dist/commands/vouch/pack/sections.js +1 -2
  298. package/dist/commands/vouch/pack/sections.js.map +1 -1
  299. package/dist/commands/vouch/run.js +26 -81
  300. package/dist/commands/vouch/run.js.map +1 -1
  301. package/dist/commands/vouch/sample/plan.js +20 -34
  302. package/dist/commands/vouch/sample/plan.js.map +1 -1
  303. package/dist/commands/vouch/vet/verify.js +39 -7
  304. package/dist/commands/vouch/vet/verify.js.map +1 -1
  305. package/dist/commands/vouch/vouch.js +10 -17
  306. package/dist/commands/vouch/vouch.js.map +1 -1
  307. package/dist/core/agent/agents-md/command-map.js +81 -106
  308. package/dist/core/agent/agents-md/command-map.js.map +1 -1
  309. package/dist/core/agent/agents-md/map/explain.js +21 -9
  310. package/dist/core/agent/agents-md/map/explain.js.map +1 -1
  311. package/dist/core/agent/agents-md/map/lenses/context.js +17 -8
  312. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -1
  313. package/dist/core/agent/agents-md/map/lenses/diff.js +33 -20
  314. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -1
  315. package/dist/core/agent/agents-md/map/lenses/gate.js +13 -5
  316. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -1
  317. package/dist/core/agent/agents-md/map/mcp.js +10 -7
  318. package/dist/core/agent/agents-md/map/mcp.js.map +1 -1
  319. package/dist/core/agent/agents-md/map/status.js +24 -8
  320. package/dist/core/agent/agents-md/map/status.js.map +1 -1
  321. package/dist/core/agent/agents-md/map/subsystem.js +80 -8
  322. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -1
  323. package/dist/core/agent/agents-md/map/usecases.js +88 -10
  324. package/dist/core/agent/agents-md/map/usecases.js.map +1 -1
  325. package/dist/core/agent/agents-md/refusals.js +49 -22
  326. package/dist/core/agent/agents-md/refusals.js.map +1 -1
  327. package/dist/core/agent/agents-md.js +39 -6
  328. package/dist/core/agent/agents-md.js.map +1 -1
  329. package/dist/core/agent/agents-stamp.js +10 -0
  330. package/dist/core/agent/agents-stamp.js.map +1 -1
  331. package/dist/core/agent/protocol.js +1 -1
  332. package/dist/core/agent/protocol.js.map +1 -1
  333. package/dist/core/agent/scaffold.js +10 -15
  334. package/dist/core/agent/scaffold.js.map +1 -1
  335. package/dist/core/agent/support/report.js +46 -5
  336. package/dist/core/agent/support/report.js.map +1 -1
  337. package/dist/core/agent/tools/dialects.js +1 -0
  338. package/dist/core/agent/tools/dialects.js.map +1 -1
  339. package/dist/core/agent/tools/registry.js +41 -76
  340. package/dist/core/agent/tools/registry.js.map +1 -1
  341. package/dist/core/agent/workflows/adopt.js +158 -11
  342. package/dist/core/agent/workflows/adopt.js.map +1 -1
  343. package/dist/core/agent/workflows/check.js +78 -39
  344. package/dist/core/agent/workflows/check.js.map +1 -1
  345. package/dist/core/agent/workflows/closing.js +88 -27
  346. package/dist/core/agent/workflows/closing.js.map +1 -1
  347. package/dist/core/agent/workflows/feature.js +128 -13
  348. package/dist/core/agent/workflows/feature.js.map +1 -1
  349. package/dist/core/agent/workflows/implement.js +96 -13
  350. package/dist/core/agent/workflows/implement.js.map +1 -1
  351. package/dist/core/agent/workflows/reference/authoring.js +106 -4
  352. package/dist/core/agent/workflows/reference/authoring.js.map +1 -1
  353. package/dist/core/agent/workflows/reference/codes.js +8 -6
  354. package/dist/core/agent/workflows/reference/codes.js.map +1 -1
  355. package/dist/core/agent/workflows/reference/done-check.js +37 -15
  356. package/dist/core/agent/workflows/reference/done-check.js.map +1 -1
  357. package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
  358. package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
  359. package/dist/core/agent/workflows/reference/reference.js +6 -3
  360. package/dist/core/agent/workflows/reference/reference.js.map +1 -1
  361. package/dist/core/agent/workflows/reference/spine.js +68 -27
  362. package/dist/core/agent/workflows/reference/spine.js.map +1 -1
  363. package/dist/core/asyncapi/baseline/plan.js +14 -81
  364. package/dist/core/asyncapi/baseline/plan.js.map +1 -1
  365. package/dist/core/asyncapi/digest.js +30 -25
  366. package/dist/core/asyncapi/digest.js.map +1 -1
  367. package/dist/core/asyncapi/merge/components.js +5 -4
  368. package/dist/core/asyncapi/merge/components.js.map +1 -1
  369. package/dist/core/asyncapi/merge/error.js +7 -2
  370. package/dist/core/asyncapi/merge/error.js.map +1 -1
  371. package/dist/core/asyncapi/merge/markers.js +32 -50
  372. package/dist/core/asyncapi/merge/markers.js.map +1 -1
  373. package/dist/core/asyncapi/merge/merge.js +33 -53
  374. package/dist/core/asyncapi/merge/merge.js.map +1 -1
  375. package/dist/core/asyncapi/merge/pin.js +12 -36
  376. package/dist/core/asyncapi/merge/pin.js.map +1 -1
  377. package/dist/core/asyncapi/model.js.map +1 -1
  378. package/dist/core/asyncapi/read.js +36 -12
  379. package/dist/core/asyncapi/read.js.map +1 -1
  380. package/dist/core/brief/brief.js +96 -36
  381. package/dist/core/brief/brief.js.map +1 -1
  382. package/dist/core/brief/checks.js +138 -3
  383. package/dist/core/brief/checks.js.map +1 -1
  384. package/dist/core/brief/landscape.js +209 -130
  385. package/dist/core/brief/landscape.js.map +1 -1
  386. package/dist/core/brief/map/extend.js +84 -0
  387. package/dist/core/brief/map/extend.js.map +1 -0
  388. package/dist/core/brief/map/owed.js +266 -0
  389. package/dist/core/brief/map/owed.js.map +1 -0
  390. package/dist/core/brief/targets.js +109 -31
  391. package/dist/core/brief/targets.js.map +1 -1
  392. package/dist/core/brief/unchecked.js +14 -3
  393. package/dist/core/brief/unchecked.js.map +1 -1
  394. package/dist/core/c4/arch.js +90 -182
  395. package/dist/core/c4/arch.js.map +1 -1
  396. package/dist/core/c4/direction/direction.js +114 -0
  397. package/dist/core/c4/direction/direction.js.map +1 -0
  398. package/dist/core/c4/likec4.js +169 -14
  399. package/dist/core/c4/likec4.js.map +1 -1
  400. package/dist/core/c4/locate/unlocated.js +150 -0
  401. package/dist/core/c4/locate/unlocated.js.map +1 -0
  402. package/dist/core/c4/parsed/deployment.js +160 -0
  403. package/dist/core/c4/parsed/deployment.js.map +1 -0
  404. package/dist/core/c4/parsed/dynamic-views.js.map +1 -1
  405. package/dist/core/c4/parsed/values.js +54 -1
  406. package/dist/core/c4/parsed/values.js.map +1 -1
  407. package/dist/core/c4/parsed/view-ids.js +39 -1
  408. package/dist/core/c4/parsed/view-ids.js.map +1 -1
  409. package/dist/core/c4/prefetch/fleet.js +134 -0
  410. package/dist/core/c4/prefetch/fleet.js.map +1 -0
  411. package/dist/core/c4/project/architecture.js +123 -7
  412. package/dist/core/c4/project/architecture.js.map +1 -1
  413. package/dist/core/c4/project/batch.js +140 -0
  414. package/dist/core/c4/project/batch.js.map +1 -0
  415. package/dist/core/c4/project/documents.js +43 -12
  416. package/dist/core/c4/project/documents.js.map +1 -1
  417. package/dist/core/c4/project/load.js +79 -43
  418. package/dist/core/c4/project/load.js.map +1 -1
  419. package/dist/core/c4/project/staged.js +277 -0
  420. package/dist/core/c4/project/staged.js.map +1 -0
  421. package/dist/core/c4/resolve/attested.js +0 -0
  422. package/dist/core/c4/resolve/attested.js.map +1 -0
  423. package/dist/core/c4/resolve/external.js +51 -0
  424. package/dist/core/c4/resolve/external.js.map +1 -0
  425. package/dist/core/c4/resolve/service.js +78 -17
  426. package/dist/core/c4/resolve/service.js.map +1 -1
  427. package/dist/core/c4/resolve/steps.js +290 -0
  428. package/dist/core/c4/resolve/steps.js.map +1 -0
  429. package/dist/core/c4/resolve/systems.js +154 -0
  430. package/dist/core/c4/resolve/systems.js.map +1 -0
  431. package/dist/core/c4/root-project/exclude.js +352 -0
  432. package/dist/core/c4/root-project/exclude.js.map +1 -0
  433. package/dist/core/c4/seed/template.js +65 -1
  434. package/dist/core/c4/seed/template.js.map +1 -1
  435. package/dist/core/c4/service-model/created/models.js +96 -0
  436. package/dist/core/c4/service-model/created/models.js.map +1 -0
  437. package/dist/core/c4/service-model/documents.js +47 -0
  438. package/dist/core/c4/service-model/documents.js.map +1 -0
  439. package/dist/core/c4/service-model/fleet/extending.js +82 -0
  440. package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
  441. package/dist/core/c4/service-model/load.js +165 -0
  442. package/dist/core/c4/service-model/load.js.map +1 -0
  443. package/dist/core/c4/service-model/renderer.js +128 -0
  444. package/dist/core/c4/service-model/renderer.js.map +1 -0
  445. package/dist/core/c4/service-model/shape.js +106 -0
  446. package/dist/core/c4/service-model/shape.js.map +1 -0
  447. package/dist/core/c4/service-model/slice.js +188 -0
  448. package/dist/core/c4/service-model/slice.js.map +1 -0
  449. package/dist/core/c4/source-mask.js +297 -10
  450. package/dist/core/c4/source-mask.js.map +1 -1
  451. package/dist/core/c4/source-scan.js +222 -141
  452. package/dist/core/c4/source-scan.js.map +1 -1
  453. package/dist/core/c4/splice/authored-source.js +79 -13
  454. package/dist/core/c4/splice/authored-source.js.map +1 -1
  455. package/dist/core/c4/splice/contract.js +20 -0
  456. package/dist/core/c4/splice/contract.js.map +1 -1
  457. package/dist/core/c4/splice/delta-blocks.js +20 -20
  458. package/dist/core/c4/splice/delta-blocks.js.map +1 -1
  459. package/dist/core/c4/splice/identity/declared.js +87 -0
  460. package/dist/core/c4/splice/identity/declared.js.map +1 -0
  461. package/dist/core/c4/splice/identity/edges.js +37 -0
  462. package/dist/core/c4/splice/identity/edges.js.map +1 -1
  463. package/dist/core/c4/splice/identity/existing.js +80 -0
  464. package/dist/core/c4/splice/identity/existing.js.map +1 -0
  465. package/dist/core/c4/splice/identity/interior.js +80 -0
  466. package/dist/core/c4/splice/identity/interior.js.map +1 -0
  467. package/dist/core/c4/splice/identity/owner.js +50 -0
  468. package/dist/core/c4/splice/identity/owner.js.map +1 -0
  469. package/dist/core/c4/splice/landscape-merge.js +182 -114
  470. package/dist/core/c4/splice/landscape-merge.js.map +1 -1
  471. package/dist/core/c4/splice/model/merge.js +151 -0
  472. package/dist/core/c4/splice/model/merge.js.map +1 -0
  473. package/dist/core/c4/splice/placement.js +160 -56
  474. package/dist/core/c4/splice/placement.js.map +1 -1
  475. package/dist/core/c4/splice/text/spot.js +131 -0
  476. package/dist/core/c4/splice/text/spot.js.map +1 -0
  477. package/dist/core/c4/workspace.js +13 -19
  478. package/dist/core/c4/workspace.js.map +1 -1
  479. package/dist/core/capabilities/capabilities.js +6 -6
  480. package/dist/core/capabilities/capabilities.js.map +1 -1
  481. package/dist/core/capabilities/delta/doc.js +7 -10
  482. package/dist/core/capabilities/delta/doc.js.map +1 -1
  483. package/dist/core/capabilities/delta/uncovered.js +2 -2
  484. package/dist/core/capabilities/delta/uncovered.js.map +1 -1
  485. package/dist/core/capabilities/findings.js +18 -22
  486. package/dist/core/capabilities/findings.js.map +1 -1
  487. package/dist/core/capabilities/realizes/findings.js +12 -19
  488. package/dist/core/capabilities/realizes/findings.js.map +1 -1
  489. package/dist/core/capabilities/realizes/join.js +0 -20
  490. package/dist/core/capabilities/realizes/join.js.map +1 -1
  491. package/dist/core/capabilities/rollup.js +6 -0
  492. package/dist/core/capabilities/rollup.js.map +1 -1
  493. package/dist/core/capabilities/tree.js +6 -28
  494. package/dist/core/capabilities/tree.js.map +1 -1
  495. package/dist/core/capabilities/usecase-join.js +3 -13
  496. package/dist/core/capabilities/usecase-join.js.map +1 -1
  497. package/dist/core/coherence/authoring/scaffold.js +11 -3
  498. package/dist/core/coherence/authoring/scaffold.js.map +1 -1
  499. package/dist/core/coherence/authoring/sentinels.js +2 -1
  500. package/dist/core/coherence/authoring/sentinels.js.map +1 -1
  501. package/dist/core/coherence/calls/called.js +52 -0
  502. package/dist/core/coherence/calls/called.js.map +1 -0
  503. package/dist/core/coherence/coherence.js +103 -22
  504. package/dist/core/coherence/coherence.js.map +1 -1
  505. package/dist/core/coherence/consumed/operations.js +70 -0
  506. package/dist/core/coherence/consumed/operations.js.map +1 -0
  507. package/dist/core/coherence/consumed/refusal.js +38 -0
  508. package/dist/core/coherence/consumed/refusal.js.map +1 -0
  509. package/dist/core/coherence/covers/health.js +85 -0
  510. package/dist/core/coherence/covers/health.js.map +1 -0
  511. package/dist/core/coherence/declared.js +60 -34
  512. package/dist/core/coherence/declared.js.map +1 -1
  513. package/dist/core/coherence/events/declared.js +44 -59
  514. package/dist/core/coherence/events/declared.js.map +1 -1
  515. package/dist/core/coherence/events/events.js +147 -16
  516. package/dist/core/coherence/events/events.js.map +1 -1
  517. package/dist/core/coherence/events/grades.js +31 -8
  518. package/dist/core/coherence/events/grades.js.map +1 -1
  519. package/dist/core/coherence/events/lookups.js +28 -87
  520. package/dist/core/coherence/events/lookups.js.map +1 -1
  521. package/dist/core/coherence/events/produced.js +100 -0
  522. package/dist/core/coherence/events/produced.js.map +1 -0
  523. package/dist/core/coherence/lookups.js +18 -78
  524. package/dist/core/coherence/lookups.js.map +1 -1
  525. package/dist/core/coherence/retired/archived.js +285 -0
  526. package/dist/core/coherence/retired/archived.js.map +1 -0
  527. package/dist/core/coherence/retired/event-pair.js +62 -0
  528. package/dist/core/coherence/retired/event-pair.js.map +1 -0
  529. package/dist/core/coherence/retired/merged.js +79 -0
  530. package/dist/core/coherence/retired/merged.js.map +1 -0
  531. package/dist/core/coherence/retired/retirement.js +49 -0
  532. package/dist/core/coherence/retired/retirement.js.map +1 -0
  533. package/dist/core/coherence/retired/revival/arrivals.js +131 -0
  534. package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
  535. package/dist/core/coherence/retired/revival/revived.js +297 -0
  536. package/dist/core/coherence/retired/revival/revived.js.map +1 -0
  537. package/dist/core/consumers/after.js +113 -0
  538. package/dist/core/consumers/after.js.map +1 -0
  539. package/dist/core/consumers/consumers.js +296 -0
  540. package/dist/core/consumers/consumers.js.map +1 -0
  541. package/dist/core/consumers/current.js +211 -0
  542. package/dist/core/consumers/current.js.map +1 -0
  543. package/dist/core/consumers/scan.js +46 -0
  544. package/dist/core/consumers/scan.js.map +1 -0
  545. package/dist/core/consumers/state.js +27 -0
  546. package/dist/core/consumers/state.js.map +1 -0
  547. package/dist/core/delta/delta.js +51 -6
  548. package/dist/core/delta/delta.js.map +1 -1
  549. package/dist/core/dependencies/fanin.js +2 -2
  550. package/dist/core/dependencies/fanin.js.map +1 -1
  551. package/dist/core/deployment/delta.js +191 -0
  552. package/dist/core/deployment/delta.js.map +1 -0
  553. package/dist/core/deployment/objects.js +145 -0
  554. package/dist/core/deployment/objects.js.map +1 -0
  555. package/dist/core/diff/base-git.js +94 -12
  556. package/dist/core/diff/base-git.js.map +1 -1
  557. package/dist/core/diff/base-state.js +49 -21
  558. package/dist/core/diff/base-state.js.map +1 -1
  559. package/dist/core/diff/joins.js +136 -0
  560. package/dist/core/diff/joins.js.map +1 -0
  561. package/dist/core/diff/scope/changed-paths.js +22 -6
  562. package/dist/core/diff/scope/changed-paths.js.map +1 -1
  563. package/dist/core/diff/scope/edges.js +82 -0
  564. package/dist/core/diff/scope/edges.js.map +1 -0
  565. package/dist/core/diff/semantic.js +100 -31
  566. package/dist/core/diff/semantic.js.map +1 -1
  567. package/dist/core/docs.js +31 -22
  568. package/dist/core/docs.js.map +1 -1
  569. package/dist/core/doctor/agents.js +34 -18
  570. package/dist/core/doctor/agents.js.map +1 -1
  571. package/dist/core/doctor/config.js +7 -3
  572. package/dist/core/doctor/config.js.map +1 -1
  573. package/dist/core/doctor/doctor.js +91 -11
  574. package/dist/core/doctor/doctor.js.map +1 -1
  575. package/dist/core/doctor/report.js.map +1 -1
  576. package/dist/core/doctor/reports/scan.js +242 -0
  577. package/dist/core/doctor/reports/scan.js.map +1 -0
  578. package/dist/core/document/apply.js +158 -11
  579. package/dist/core/document/apply.js.map +1 -1
  580. package/dist/core/document/frontmatter.js +55 -0
  581. package/dist/core/document/frontmatter.js.map +1 -1
  582. package/dist/core/document/parse.js +29 -6
  583. package/dist/core/document/parse.js.map +1 -1
  584. package/dist/core/document/scenarios.js +17 -0
  585. package/dist/core/document/scenarios.js.map +1 -1
  586. package/dist/core/document/spec.js +4 -11
  587. package/dist/core/document/spec.js.map +1 -1
  588. package/dist/core/envelope/config.js +10 -0
  589. package/dist/core/envelope/config.js.map +1 -1
  590. package/dist/core/envelope/json.js +34 -0
  591. package/dist/core/envelope/json.js.map +1 -1
  592. package/dist/core/explain/families.js +26 -21
  593. package/dist/core/explain/families.js.map +1 -1
  594. package/dist/core/explain/lookup.js +14 -1
  595. package/dist/core/explain/lookup.js.map +1 -1
  596. package/dist/core/explain/refusals.js +5 -5
  597. package/dist/core/explain/refusals.js.map +1 -1
  598. package/dist/core/explain/terms/documents.js +227 -0
  599. package/dist/core/explain/terms/documents.js.map +1 -0
  600. package/dist/core/explain/terms/done-check.js +144 -0
  601. package/dist/core/explain/terms/done-check.js.map +1 -0
  602. package/dist/core/explain/terms/entry.js +14 -0
  603. package/dist/core/explain/terms/entry.js.map +1 -0
  604. package/dist/core/explain/terms/stages.js +71 -0
  605. package/dist/core/explain/terms/stages.js.map +1 -0
  606. package/dist/core/explain/terms/tasks.js +97 -0
  607. package/dist/core/explain/terms/tasks.js.map +1 -0
  608. package/dist/core/explain/terms.js +68 -109
  609. package/dist/core/explain/terms.js.map +1 -1
  610. package/dist/core/explore/explore.js +40 -10
  611. package/dist/core/explore/explore.js.map +1 -1
  612. package/dist/core/fleet-context.js +81 -95
  613. package/dist/core/fleet-context.js.map +1 -1
  614. package/dist/core/gate/checks.js +11 -4
  615. package/dist/core/gate/checks.js.map +1 -1
  616. package/dist/core/gate/partners.js +69 -28
  617. package/dist/core/gate/partners.js.map +1 -1
  618. package/dist/core/gate/report.js.map +1 -1
  619. package/dist/core/gate/verification.js +75 -12
  620. package/dist/core/gate/verification.js.map +1 -1
  621. package/dist/core/gherkin/stale.js +13 -37
  622. package/dist/core/gherkin/stale.js.map +1 -1
  623. package/dist/core/glossary/delta.js +10 -7
  624. package/dist/core/glossary/delta.js.map +1 -1
  625. package/dist/core/glossary/tree.js +6 -19
  626. package/dist/core/glossary/tree.js.map +1 -1
  627. package/dist/core/kernel/concurrency.js +19 -0
  628. package/dist/core/kernel/concurrency.js.map +1 -1
  629. package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
  630. package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
  631. package/dist/core/kernel/path-safety.js +38 -0
  632. package/dist/core/kernel/path-safety.js.map +1 -1
  633. package/dist/core/kernel/records.js +11 -0
  634. package/dist/core/kernel/records.js.map +1 -1
  635. package/dist/core/links/backlinks.js +1 -3
  636. package/dist/core/links/backlinks.js.map +1 -1
  637. package/dist/core/links/corpus.js +51 -37
  638. package/dist/core/links/corpus.js.map +1 -1
  639. package/dist/core/links/findings.js.map +1 -1
  640. package/dist/core/links/parse.js +38 -9
  641. package/dist/core/links/parse.js.map +1 -1
  642. package/dist/core/mcp/argv.js +101 -0
  643. package/dist/core/mcp/argv.js.map +1 -1
  644. package/dist/core/mcp/author-tools.js +2 -1
  645. package/dist/core/mcp/author-tools.js.map +1 -1
  646. package/dist/core/mcp/protocol.js +2 -2
  647. package/dist/core/mcp/protocol.js.map +1 -1
  648. package/dist/core/mcp/tools.js +43 -33
  649. package/dist/core/mcp/tools.js.map +1 -1
  650. package/dist/core/openapi/baseline/gate.js +53 -12
  651. package/dist/core/openapi/baseline/gate.js.map +1 -1
  652. package/dist/core/openapi/baseline/plan.js +40 -10
  653. package/dist/core/openapi/baseline/plan.js.map +1 -1
  654. package/dist/core/openapi/baseline/record.js +0 -1
  655. package/dist/core/openapi/baseline/record.js.map +1 -1
  656. package/dist/core/openapi/contract-text.js +33 -0
  657. package/dist/core/openapi/contract-text.js.map +1 -0
  658. package/dist/core/openapi/contract-tree.js +301 -0
  659. package/dist/core/openapi/contract-tree.js.map +1 -0
  660. package/dist/core/openapi/depth.js +38 -24
  661. package/dist/core/openapi/depth.js.map +1 -1
  662. package/dist/core/openapi/digest.js +52 -2
  663. package/dist/core/openapi/digest.js.map +1 -1
  664. package/dist/core/openapi/doc.js +12 -4
  665. package/dist/core/openapi/doc.js.map +1 -1
  666. package/dist/core/openapi/merge/components.js +25 -60
  667. package/dist/core/openapi/merge/components.js.map +1 -1
  668. package/dist/core/openapi/merge/error.js +3 -13
  669. package/dist/core/openapi/merge/error.js.map +1 -1
  670. package/dist/core/openapi/merge/markers.js +26 -30
  671. package/dist/core/openapi/merge/markers.js.map +1 -1
  672. package/dist/core/openapi/merge/merge.js +28 -52
  673. package/dist/core/openapi/merge/merge.js.map +1 -1
  674. package/dist/core/openapi/merge/pin.js +17 -35
  675. package/dist/core/openapi/merge/pin.js.map +1 -1
  676. package/dist/core/openspec/decide/verdict.js.map +1 -1
  677. package/dist/core/openspec/inventory.js +4 -5
  678. package/dist/core/openspec/inventory.js.map +1 -1
  679. package/dist/core/openspec/model/mapping.js +30 -28
  680. package/dist/core/openspec/model/mapping.js.map +1 -1
  681. package/dist/core/openspec/model/model.js +12 -7
  682. package/dist/core/openspec/model/model.js.map +1 -1
  683. package/dist/core/openspec/scan/changes.js +10 -4
  684. package/dist/core/openspec/scan/changes.js.map +1 -1
  685. package/dist/core/openspec/scan/config.js +7 -16
  686. package/dist/core/openspec/scan/config.js.map +1 -1
  687. package/dist/core/openspec/scan/shape.js +63 -19
  688. package/dist/core/openspec/scan/shape.js.map +1 -1
  689. package/dist/core/openspec/scan/walk.js +21 -38
  690. package/dist/core/openspec/scan/walk.js.map +1 -1
  691. package/dist/core/pack/living.js +43 -4
  692. package/dist/core/pack/living.js.map +1 -1
  693. package/dist/core/pack/pack.js +50 -6
  694. package/dist/core/pack/pack.js.map +1 -1
  695. package/dist/core/projection/arch-slice.js +2 -2
  696. package/dist/core/projection/arch-slice.js.map +1 -1
  697. package/dist/core/projection/introduced.js +14 -0
  698. package/dist/core/projection/introduced.js.map +1 -0
  699. package/dist/core/provenance/findings.js +48 -12
  700. package/dist/core/provenance/findings.js.map +1 -1
  701. package/dist/core/provenance/git.js +33 -57
  702. package/dist/core/provenance/git.js.map +1 -1
  703. package/dist/core/provenance/gitq/moves.js +71 -114
  704. package/dist/core/provenance/gitq/moves.js.map +1 -1
  705. package/dist/core/provenance/gitq/vouched-ancestor.js +2 -2
  706. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -1
  707. package/dist/core/provenance/sources.js +23 -6
  708. package/dist/core/provenance/sources.js.map +1 -1
  709. package/dist/core/provenance/stamp.js +5 -17
  710. package/dist/core/provenance/stamp.js.map +1 -1
  711. package/dist/core/repo/authored/paths.js +18 -0
  712. package/dist/core/repo/authored/paths.js.map +1 -1
  713. package/dist/core/repo/entries.js.map +1 -1
  714. package/dist/core/repo/paths.js +92 -6
  715. package/dist/core/repo/paths.js.map +1 -1
  716. package/dist/core/repo/repo.js +74 -14
  717. package/dist/core/repo/repo.js.map +1 -1
  718. package/dist/core/repo/tree/find.js +12 -3
  719. package/dist/core/repo/tree/find.js.map +1 -1
  720. package/dist/core/repo/tree/fs.js +27 -1
  721. package/dist/core/repo/tree/fs.js.map +1 -1
  722. package/dist/core/repo/tree/render/body.js +258 -0
  723. package/dist/core/repo/tree/render/body.js.map +1 -0
  724. package/dist/core/repo/tree/render/projects.js +182 -0
  725. package/dist/core/repo/tree/render/projects.js.map +1 -0
  726. package/dist/core/repo/tree/render/service/header.js +125 -0
  727. package/dist/core/repo/tree/render/service/header.js.map +1 -0
  728. package/dist/core/repo/tree/render/service/peers.js +28 -0
  729. package/dist/core/repo/tree/render/service/peers.js.map +1 -0
  730. package/dist/core/repo/tree/render/service/view-id.js +67 -0
  731. package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
  732. package/dist/core/repo/tree/render/service/views.js +78 -0
  733. package/dist/core/repo/tree/render/service/views.js.map +1 -0
  734. package/dist/core/repo/tree/render/stale.js +42 -0
  735. package/dist/core/repo/tree/render/stale.js.map +1 -0
  736. package/dist/core/repo/tree/render/text.js +84 -0
  737. package/dist/core/repo/tree/render/text.js.map +1 -0
  738. package/dist/core/repo/tree/render/views.js +293 -0
  739. package/dist/core/repo/tree/render/views.js.map +1 -0
  740. package/dist/core/repo/tree/walk.js +53 -32
  741. package/dist/core/repo/tree/walk.js.map +1 -1
  742. package/dist/core/results.js +47 -12
  743. package/dist/core/results.js.map +1 -1
  744. package/dist/core/scaffold/landscape.js +121 -13
  745. package/dist/core/scaffold/landscape.js.map +1 -1
  746. package/dist/core/scaffold/legacy.js +271 -0
  747. package/dist/core/scaffold/legacy.js.map +1 -0
  748. package/dist/core/staging/commit.js +26 -15
  749. package/dist/core/staging/commit.js.map +1 -1
  750. package/dist/core/staging/lock.js +74 -12
  751. package/dist/core/staging/lock.js.map +1 -1
  752. package/dist/core/staging/recovery/intent.js +2 -5
  753. package/dist/core/staging/recovery/intent.js.map +1 -1
  754. package/dist/core/staging/recovery/recover.js +84 -6
  755. package/dist/core/staging/recovery/recover.js.map +1 -1
  756. package/dist/core/staging/snapshot/manifest.js +188 -0
  757. package/dist/core/staging/snapshot/manifest.js.map +1 -0
  758. package/dist/core/staging/{snapshot.js → snapshot/snapshot.js} +39 -45
  759. package/dist/core/staging/snapshot/snapshot.js.map +1 -0
  760. package/dist/core/staging/txn/forward.js +24 -14
  761. package/dist/core/staging/txn/forward.js.map +1 -1
  762. package/dist/core/staging/writes.js.map +1 -1
  763. package/dist/core/status/actions/execution.js +11 -0
  764. package/dist/core/status/actions/execution.js.map +1 -1
  765. package/dist/core/status/contracts.js +39 -15
  766. package/dist/core/status/contracts.js.map +1 -1
  767. package/dist/core/status/feature/artifacts.js +33 -8
  768. package/dist/core/status/feature/artifacts.js.map +1 -1
  769. package/dist/core/status/feature/feature.js +24 -17
  770. package/dist/core/status/feature/feature.js.map +1 -1
  771. package/dist/core/status/feature/next.js +20 -7
  772. package/dist/core/status/feature/next.js.map +1 -1
  773. package/dist/core/status/feature/words.js +96 -0
  774. package/dist/core/status/feature/words.js.map +1 -0
  775. package/dist/core/status/fleet/fleet.js +43 -14
  776. package/dist/core/status/fleet/fleet.js.map +1 -1
  777. package/dist/core/status/fleet/next.js +153 -58
  778. package/dist/core/status/fleet/next.js.map +1 -1
  779. package/dist/core/status/report.js.map +1 -1
  780. package/dist/core/status/scan.js.map +1 -1
  781. package/dist/core/status/verification.js +30 -15
  782. package/dist/core/status/verification.js.map +1 -1
  783. package/dist/core/tasks/packet.js +199 -0
  784. package/dist/core/tasks/packet.js.map +1 -0
  785. package/dist/core/tasks/record.js +43 -0
  786. package/dist/core/tasks/record.js.map +1 -0
  787. package/dist/core/tasks/sources.js +181 -0
  788. package/dist/core/tasks/sources.js.map +1 -0
  789. package/dist/core/tasks/stamps.js +76 -0
  790. package/dist/core/tasks/stamps.js.map +1 -0
  791. package/dist/core/tasks/unit.js +0 -0
  792. package/dist/core/tasks/unit.js.map +1 -0
  793. package/dist/core/usecases/capability.js +11 -14
  794. package/dist/core/usecases/capability.js.map +1 -1
  795. package/dist/core/usecases/delta/claims.js +31 -7
  796. package/dist/core/usecases/delta/claims.js.map +1 -1
  797. package/dist/core/usecases/delta/flows.js +5 -7
  798. package/dist/core/usecases/delta/flows.js.map +1 -1
  799. package/dist/core/usecases/delta/modified.js +315 -0
  800. package/dist/core/usecases/delta/modified.js.map +1 -0
  801. package/dist/core/usecases/delta/overlay.js +32 -191
  802. package/dist/core/usecases/delta/overlay.js.map +1 -1
  803. package/dist/core/usecases/fleet.js +195 -36
  804. package/dist/core/usecases/fleet.js.map +1 -1
  805. package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/capability-tag.js +8 -9
  806. package/dist/core/usecases/grade/capability-tag.js.map +1 -0
  807. package/dist/core/usecases/grade/feature.js +88 -0
  808. package/dist/core/usecases/grade/feature.js.map +1 -0
  809. package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/requirement-tag.js +3 -4
  810. package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
  811. package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/steps.js +102 -33
  812. package/dist/core/usecases/grade/steps.js.map +1 -0
  813. package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/usecases.js +23 -10
  814. package/dist/core/usecases/grade/usecases.js.map +1 -0
  815. package/dist/core/usecases/operations.js +26 -14
  816. package/dist/core/usecases/operations.js.map +1 -1
  817. package/dist/core/usecases/place.js.map +1 -1
  818. package/dist/core/usecases/service/exclude.js +119 -0
  819. package/dist/core/usecases/service/exclude.js.map +1 -0
  820. package/dist/core/usecases/service/flows.js +164 -0
  821. package/dist/core/usecases/service/flows.js.map +1 -0
  822. package/dist/core/usecases/suites/participants.js +83 -0
  823. package/dist/core/usecases/suites/participants.js.map +1 -0
  824. package/dist/core/usecases/suites/suites.js +45 -0
  825. package/dist/core/usecases/suites/suites.js.map +1 -0
  826. package/dist/core/verify/answers.js +12 -5
  827. package/dist/core/verify/answers.js.map +1 -1
  828. package/dist/core/verify/build.js +102 -82
  829. package/dist/core/verify/build.js.map +1 -1
  830. package/dist/core/verify/checklist.js +70 -12
  831. package/dist/core/verify/checklist.js.map +1 -1
  832. package/dist/core/verify/location.js +67 -0
  833. package/dist/core/verify/location.js.map +1 -0
  834. package/dist/core/verify/pins/lint.js +3 -2
  835. package/dist/core/verify/pins/lint.js.map +1 -1
  836. package/dist/core/verify/pins/pin.js +1 -1
  837. package/dist/core/verify/pins/pin.js.map +1 -1
  838. package/dist/core/verify/read/file.js +224 -0
  839. package/dist/core/verify/read/file.js.map +1 -0
  840. package/dist/core/verify/{file.js → read/shape.js} +16 -104
  841. package/dist/core/verify/read/shape.js.map +1 -0
  842. package/dist/core/verify/read/union.js +105 -0
  843. package/dist/core/verify/read/union.js.map +1 -0
  844. package/dist/core/verify/record.js +35 -12
  845. package/dist/core/verify/record.js.map +1 -1
  846. package/dist/core/verify/store/commit.js +40 -30
  847. package/dist/core/verify/store/commit.js.map +1 -1
  848. package/dist/core/verify/store/render.js +8 -4
  849. package/dist/core/verify/store/render.js.map +1 -1
  850. package/dist/core/vocabulary/issue.js +4 -0
  851. package/dist/core/vocabulary/issue.js.map +1 -1
  852. package/dist/core/vocabulary/maturity.js +75 -4
  853. package/dist/core/vocabulary/maturity.js.map +1 -1
  854. package/dist/core/vocabulary/report.js +16 -1
  855. package/dist/core/vocabulary/report.js.map +1 -1
  856. package/examples/README.md +54 -11
  857. package/examples/docs/architecture/landscape.likec4 +62 -6
  858. package/examples/docs/architecture/services.likec4 +70 -0
  859. package/examples/docs/architecture/subsystems.likec4 +7 -0
  860. package/examples/docs/architecture/usecases/order-notification.likec4 +16 -7
  861. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +11 -8
  862. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +6 -6
  863. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +4 -1
  864. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +13 -10
  865. package/examples/docs/likec4.config.json +0 -1
  866. package/examples/docs/services/checkout-web/model.likec4 +39 -56
  867. package/examples/docs/services/order-service/arch.spec.md +13 -6
  868. package/examples/docs/services/order-service/asyncapi.yaml +3 -2
  869. package/examples/docs/services/order-service/model.likec4 +58 -70
  870. package/examples/docs/services/payment-service/arch.spec.md +7 -4
  871. package/examples/docs/services/payment-service/model.likec4 +38 -37
  872. package/examples/docs/services/platform/identity-service/arch.spec.md +7 -4
  873. package/examples/docs/services/platform/identity-service/model.likec4 +35 -37
  874. package/examples/docs/services/platform/notification-service/asyncapi.yaml +2 -1
  875. package/examples/docs/services/platform/notification-service/health.yaml +8 -3
  876. package/examples/docs/services/platform/notification-service/model.likec4 +43 -64
  877. package/package.json +1 -1
  878. package/dist/commands/validate/checks/vocabulary.js +0 -31
  879. package/dist/commands/validate/checks/vocabulary.js.map +0 -1
  880. package/dist/commands/validate/fleet/usecases/capability-tag.js.map +0 -1
  881. package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +0 -1
  882. package/dist/commands/validate/fleet/usecases/steps.js.map +0 -1
  883. package/dist/commands/validate/fleet/usecases/usecases.js.map +0 -1
  884. package/dist/core/agent/agents-md/artifacts.js +0 -220
  885. package/dist/core/agent/agents-md/artifacts.js.map +0 -1
  886. package/dist/core/agent/agents-md/cycle.js +0 -165
  887. package/dist/core/agent/agents-md/cycle.js.map +0 -1
  888. package/dist/core/agent/agents-md/shipped/archive-gate.js +0 -98
  889. package/dist/core/agent/agents-md/shipped/archive-gate.js.map +0 -1
  890. package/dist/core/agent/agents-md/spine.js +0 -40
  891. package/dist/core/agent/agents-md/spine.js.map +0 -1
  892. package/dist/core/coherence/events/merged.js +0 -40
  893. package/dist/core/coherence/events/merged.js.map +0 -1
  894. package/dist/core/diff/current-state.js +0 -96
  895. package/dist/core/diff/current-state.js.map +0 -1
  896. package/dist/core/diff/victims.js +0 -247
  897. package/dist/core/diff/victims.js.map +0 -1
  898. package/dist/core/repo/tree/views.js +0 -172
  899. package/dist/core/repo/tree/views.js.map +0 -1
  900. package/dist/core/staging/snapshot.js.map +0 -1
  901. package/dist/core/verify/file.js.map +0 -1
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Which of the two shapes a `model.likec4` has, decided by a byte scan of the
3
+ * file itself.
4
+ *
5
+ * A STANDALONE model declares at least one `element <kind>` inside a top-level
6
+ * `specification { }` block. It is parsed ALONE, exactly as every model was
7
+ * before this axis: it may re-declare the partners it talks to, and it renders
8
+ * only as a project of its own. An EXTENDING model declares no element kind —
9
+ * it takes the map's — and says what is inside the service with
10
+ * `extend <fqn> { … }`; it is parsed INSIDE the fleet's `architecture/`
11
+ * project, beside the map that declares those kinds.
12
+ *
13
+ * THE FILE'S OWN GRAMMAR DECIDES, never a config key, and that is the whole
14
+ * design of this module. A flag in `loam.json` would be a second authority on a
15
+ * fact the document already states, free to disagree with it — and the
16
+ * disagreement is not a warning but a parse: a model read the wrong way is
17
+ * either eleven `c4.invalid` errors (an extending model parsed alone: measured,
18
+ * deleting a model's `specification` under the old loader) or a pile of
19
+ * duplicate-declaration errors blamed on BOTH files (a standalone model staged
20
+ * beside the landscape). Nothing about a model has to be migrated for loam to
21
+ * read it correctly; the bytes say which it is.
22
+ *
23
+ * Every other answer is `extending`, and each of those is legal on purpose: a
24
+ * tags-only `specification { tag req-X }` (measured legal inside one project,
25
+ * and it lands the tag in the project's specification), a bare `model {}`, an
26
+ * empty file, a file that is only `views { }`. The conservative direction is
27
+ * therefore towards `extending` — which is why an unreadable file is NOT
28
+ * classified here at all (see `FleetContext.serviceModel`): absence is a
29
+ * question for the reader that establishes the file exists, not for a scanner
30
+ * looking at bytes it does not have.
31
+ */
32
+ import { readFile } from "node:fs/promises";
33
+ import { resolve } from "node:path";
34
+ import { inOrder } from "../../kernel/concurrency.js";
35
+ import { maskSource, topLevelBlocks } from "../source-mask.js";
36
+ /**
37
+ * A kind declaration inside a specification block — `element service`,
38
+ * `element softwareSystem`. Deliberately only `element`: `tag`,
39
+ * `relationship`, `deploymentNode` and `color` declare no ELEMENT kind, and a
40
+ * model whose specification holds only those still takes every element kind it
41
+ * uses from the map, which is exactly what makes it extending.
42
+ */
43
+ const ELEMENT_KIND = /\belement\s+[A-Za-z_][\w-]*/;
44
+ /**
45
+ * The shape of a model, from its source text.
46
+ *
47
+ * The scan runs over MASKED source (`../source-mask.ts`), so a comment or a
48
+ * string containing `specification { element x }` counts for nothing — and that
49
+ * is not a hypothetical: the brief loam writes for an adopted service explains
50
+ * the other shape in a comment, so an authored model can easily carry those
51
+ * exact words in prose. Reading them as a declaration would flip a whole
52
+ * service to the wrong loader.
53
+ *
54
+ * Only TOP-LEVEL blocks are considered — depth zero in the masked source — for
55
+ * the same reason: `specification` nested inside another block is not a
56
+ * declaration LikeC4 would honour, so loam must not honour it either.
57
+ *
58
+ * An unbalanced block (no closing brace) is read to end of file and still
59
+ * answers `standalone` when it declares a kind. That file does not parse at
60
+ * all, and both loaders will say so; answering `standalone` sends the reader to
61
+ * the one whose errors name only this file, which is the honest half of a
62
+ * broken document.
63
+ */
64
+ export function modelShape(text) {
65
+ const { code } = maskSource(text);
66
+ // Built per call rather than hoisted to module scope: a `/g` regex carries
67
+ // `lastIndex`, which is mutable state a second caller would inherit — the
68
+ // module-level-state hazard AGENTS.md names, arriving through a constant that
69
+ // looks immutable.
70
+ const specification = /\bspecification\s*\{/g;
71
+ for (const { body } of topLevelBlocks(code, specification)) {
72
+ if (ELEMENT_KIND.test(body))
73
+ return "standalone";
74
+ }
75
+ return "extending";
76
+ }
77
+ /**
78
+ * One model's shape, from its bytes — the shape of a file that cannot be read
79
+ * is `standalone`.
80
+ *
81
+ * That is the conservative arm rather than a guess. The standalone path hands
82
+ * the model to the per-file loader, so a caller asking about a file that is not
83
+ * there (or is not readable) gets today's exact error — `c4.invalid`, naming
84
+ * that file — instead of a slice of the fleet map, which is what the extending
85
+ * path would answer about a document nobody could open.
86
+ */
87
+ export async function readModelShape(path) {
88
+ return readFile(path, "utf8").then(modelShape, () => "standalone");
89
+ }
90
+ /**
91
+ * Many models' shapes at once, keyed by RESOLVED path.
92
+ *
93
+ * The fleet needs this list before it can do anything else: which models are
94
+ * batched as projects and which as documents, which directories are owed a
95
+ * per-service `likec4.config.json` and which must not have one. Every one of
96
+ * those questions is asked over the FULL service enumeration rather than over
97
+ * whatever subset a run is grading, so the read is a bulk one through the
98
+ * shared pool — a fleet of 56 models is 56 small reads, and the pool is what
99
+ * keeps them from being 56 sequential round-trips on a network-mounted docs
100
+ * repo.
101
+ */
102
+ export async function readModelShapes(paths) {
103
+ const entries = await inOrder(paths, async (path) => [resolve(path), await readModelShape(path)]);
104
+ return new Map(entries);
105
+ }
106
+ //# sourceMappingURL=shape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shape.js","sourceRoot":"","sources":["../../../../src/core/c4/service-model/shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAI/D;;;;;;GAMG;AACH,MAAM,YAAY,GAAG,6BAA6B,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAClC,2EAA2E;IAC3E,0EAA0E;IAC1E,8EAA8E;IAC9E,mBAAmB;IACnB,MAAM,aAAa,GAAG,uBAAuB,CAAC;IAC9C,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,CAAC;QAC3D,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,YAAY,CAAC;IACnD,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,GAAe,EAAE,CAAC,YAAY,CAAC,CAAC;AACjF,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAwB;IAC5D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,cAAc,CAAC,IAAI,CAAC,CAAU,CAAC,CAAC;IAC3G,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;AAC1B,CAAC","sourcesContent":["/**\n * Which of the two shapes a `model.likec4` has, decided by a byte scan of the\n * file itself.\n *\n * A STANDALONE model declares at least one `element <kind>` inside a top-level\n * `specification { }` block. It is parsed ALONE, exactly as every model was\n * before this axis: it may re-declare the partners it talks to, and it renders\n * only as a project of its own. An EXTENDING model declares no element kind —\n * it takes the map's — and says what is inside the service with\n * `extend <fqn> { … }`; it is parsed INSIDE the fleet's `architecture/`\n * project, beside the map that declares those kinds.\n *\n * THE FILE'S OWN GRAMMAR DECIDES, never a config key, and that is the whole\n * design of this module. A flag in `loam.json` would be a second authority on a\n * fact the document already states, free to disagree with it — and the\n * disagreement is not a warning but a parse: a model read the wrong way is\n * either eleven `c4.invalid` errors (an extending model parsed alone: measured,\n * deleting a model's `specification` under the old loader) or a pile of\n * duplicate-declaration errors blamed on BOTH files (a standalone model staged\n * beside the landscape). Nothing about a model has to be migrated for loam to\n * read it correctly; the bytes say which it is.\n *\n * Every other answer is `extending`, and each of those is legal on purpose: a\n * tags-only `specification { tag req-X }` (measured legal inside one project,\n * and it lands the tag in the project's specification), a bare `model {}`, an\n * empty file, a file that is only `views { }`. The conservative direction is\n * therefore towards `extending` — which is why an unreadable file is NOT\n * classified here at all (see `FleetContext.serviceModel`): absence is a\n * question for the reader that establishes the file exists, not for a scanner\n * looking at bytes it does not have.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { inOrder } from \"../../kernel/concurrency.js\";\nimport { maskSource, topLevelBlocks } from \"../source-mask.js\";\n\nexport type ModelShape = \"standalone\" | \"extending\";\n\n/**\n * A kind declaration inside a specification block — `element service`,\n * `element softwareSystem`. Deliberately only `element`: `tag`,\n * `relationship`, `deploymentNode` and `color` declare no ELEMENT kind, and a\n * model whose specification holds only those still takes every element kind it\n * uses from the map, which is exactly what makes it extending.\n */\nconst ELEMENT_KIND = /\\belement\\s+[A-Za-z_][\\w-]*/;\n\n/**\n * The shape of a model, from its source text.\n *\n * The scan runs over MASKED source (`../source-mask.ts`), so a comment or a\n * string containing `specification { element x }` counts for nothing — and that\n * is not a hypothetical: the brief loam writes for an adopted service explains\n * the other shape in a comment, so an authored model can easily carry those\n * exact words in prose. Reading them as a declaration would flip a whole\n * service to the wrong loader.\n *\n * Only TOP-LEVEL blocks are considered — depth zero in the masked source — for\n * the same reason: `specification` nested inside another block is not a\n * declaration LikeC4 would honour, so loam must not honour it either.\n *\n * An unbalanced block (no closing brace) is read to end of file and still\n * answers `standalone` when it declares a kind. That file does not parse at\n * all, and both loaders will say so; answering `standalone` sends the reader to\n * the one whose errors name only this file, which is the honest half of a\n * broken document.\n */\nexport function modelShape(text: string): ModelShape {\n const { code } = maskSource(text);\n // Built per call rather than hoisted to module scope: a `/g` regex carries\n // `lastIndex`, which is mutable state a second caller would inherit — the\n // module-level-state hazard AGENTS.md names, arriving through a constant that\n // looks immutable.\n const specification = /\\bspecification\\s*\\{/g;\n for (const { body } of topLevelBlocks(code, specification)) {\n if (ELEMENT_KIND.test(body)) return \"standalone\";\n }\n return \"extending\";\n}\n\n/**\n * One model's shape, from its bytes — the shape of a file that cannot be read\n * is `standalone`.\n *\n * That is the conservative arm rather than a guess. The standalone path hands\n * the model to the per-file loader, so a caller asking about a file that is not\n * there (or is not readable) gets today's exact error — `c4.invalid`, naming\n * that file — instead of a slice of the fleet map, which is what the extending\n * path would answer about a document nobody could open.\n */\nexport async function readModelShape(path: string): Promise<ModelShape> {\n return readFile(path, \"utf8\").then(modelShape, (): ModelShape => \"standalone\");\n}\n\n/**\n * Many models' shapes at once, keyed by RESOLVED path.\n *\n * The fleet needs this list before it can do anything else: which models are\n * batched as projects and which as documents, which directories are owed a\n * per-service `likec4.config.json` and which must not have one. Every one of\n * those questions is asked over the FULL service enumeration rather than over\n * whatever subset a run is grading, so the read is a bulk one through the\n * shared pool — a fleet of 56 models is 56 small reads, and the pool is what\n * keeps them from being 56 sequential round-trips on a network-mounted docs\n * repo.\n */\nexport async function readModelShapes(paths: readonly string[]): Promise<Map<string, ModelShape>> {\n const entries = await inOrder(paths, async (path) => [resolve(path), await readModelShape(path)] as const);\n return new Map(entries);\n}\n"]}
@@ -0,0 +1,188 @@
1
+ /**
2
+ * The service's OWN part of a per-service project — derived, because LikeC4
3
+ * does not record it.
4
+ *
5
+ * Measured at the 1.59.2 pin: `$data.views[id]` carries a `sourcePath` and
6
+ * `$data.elements[fqn]` carries NO source-document field at all. So after the
7
+ * map and one extending model have been parsed together there is nothing in the
8
+ * parse output that says which of the two files declared a given element. The
9
+ * answer has to be reconstructed, and this module is the reconstruction: DIFF
10
+ * the project against the architecture-alone load, and resolve what is left
11
+ * through the same element→service resolver every fleet check already joins on.
12
+ *
13
+ * Why it matters that this is exact rather than approximate: every model-
14
+ * dependent check reads the slice as if it were the standalone file it used to
15
+ * read — `c4.no-relationships`, `health.dependency-unmodelled`, `Covers:`
16
+ * resolution, the attested-call scan. Too WIDE and a service is graded against
17
+ * the whole fleet map (every service would suddenly have relationships, and
18
+ * every dependency would resolve). Too NARROW and a service that models its
19
+ * partners correctly is told it models nothing.
20
+ */
21
+ import { properAncestorIds } from "../../kernel/ids/fqn/ancestors.js";
22
+ import { serviceResolver } from "../resolve/service.js";
23
+ /**
24
+ * A relationship's identity for the DIFF, and every field of it is one loam
25
+ * already reads somewhere.
26
+ *
27
+ * There is no id to join on: LikeC4 mints relationship ids per parse, so the
28
+ * same edge in two loads of overlapping document sets is two different ids.
29
+ * Endpoints alone are not enough either — a fleet may draw two edges between
30
+ * the same pair (`api -> kafka 'publishes'` and `api -> kafka 'consumes'`), and
31
+ * collapsing them would let a model silently inherit one of the map's. So the
32
+ * key is everything a check can branch on: the endpoints, the label, and the
33
+ * three metadata keys plus the tag set, sorted because tag order is authoring
34
+ * order and means nothing.
35
+ */
36
+ function relKey(rel) {
37
+ return JSON.stringify([
38
+ rel.source,
39
+ rel.target,
40
+ rel.title ?? "",
41
+ rel.op ?? "",
42
+ rel.publishes ?? "",
43
+ rel.consumes ?? "",
44
+ [...rel.tags].sort(),
45
+ ]);
46
+ }
47
+ /**
48
+ * The service's own slice of a per-service project.
49
+ *
50
+ * OWN is resolution PLUS NESTING, and the second half is not a widening for
51
+ * convenience — it is the only thing that keeps a model's own file from being
52
+ * filtered against it.
53
+ *
54
+ * Resolution first: every project element whose id resolves to this service,
55
+ * whether the model added it or the map already declared it. The bound element
56
+ * itself has to be in — a standalone model declared it, and every check that
57
+ * reads "the service's elements" expects it.
58
+ *
59
+ * Then nesting, because resolution alone ejects a child the author wrote INSIDE
60
+ * their own `extend` block. `serviceResolver`'s second rung answers with the
61
+ * nearest ancestor whose TITLE names a real `services/<id>/` directory, and that
62
+ * rung sees the child before it sees the parent: a container written as
63
+ * `store = database 'db'` under `extend svcA { … }` resolves to a service called
64
+ * `db` the moment some other team has adopted one, and svcA's own element is
65
+ * bound by title only. The model then reported one element fewer than it
66
+ * declares, a `Covers: svcA.store` line was convicted as a typo, and
67
+ * `c4.element-unowned` told the author their own container belonged in somebody
68
+ * else's model. A standalone model was never filtered against its own file at
69
+ * all, so every one of those is a regression the second shape introduced.
70
+ *
71
+ * So: an OWN ROOT is an own element none of whose proper ancestors is own — the
72
+ * element the author actually extended — and everything nested under one is own
73
+ * too. Id nesting under the extended element is evidence nobody had to guess at,
74
+ * and it outranks a title guess. It does NOT outrank an explicit
75
+ * `metadata { service '…' }` binding, which is a claim somebody wrote down: a
76
+ * map that nests one service's element inside another's keeps both on the right
77
+ * side of the line.
78
+ *
79
+ * OWN RELATIONSHIPS are the diff: the project's edges minus the ones the
80
+ * architecture documents already have. Resolution cannot decide this one, and
81
+ * the reason is the whole point of the fleet map: the map is where cross-service
82
+ * edges live, so `checkoutWeb -> paymentService` resolves to this service at one
83
+ * end and must NOT become part of the model's own relationships — otherwise
84
+ * every service would be graded as declaring calls it never wrote, and
85
+ * `landscape.service-isolated` (which asks whether the map's edges and the
86
+ * model's agree) would be answering about itself.
87
+ *
88
+ * The diff is a MULTISET difference, not a set one, and that distinction is the
89
+ * whole grade for a model that agrees with the map. A model may legitimately
90
+ * draw an edge the map also draws, spelled identically —
91
+ * `marketplace.paymentService -> stripe 'Authorizes cards'` — and under a set
92
+ * difference every such edge would vanish from the model's own list. Then
93
+ * `attestedCalls` finds no attested call, `landscape.service-isolated` reports a
94
+ * service that talks to nobody, the adopt brief's `landscape.attested` list
95
+ * comes back empty and `c4.no-relationships` fires on a model full of edges. So
96
+ * each structural key drops `min(architecture, project)` occurrences and the
97
+ * rest are the model's: one copy in the map cancels exactly one copy here.
98
+ *
99
+ * PARTNERS are the endpoints of the model's own edges that lie outside the
100
+ * service, AND every ancestor of such an endpoint that the project holds. The
101
+ * ancestors are not tidiness: a standalone model had to declare `kafka` in order
102
+ * to draw an edge at `kafka.orderEvents`, and health.yaml names the dependency
103
+ * `kafka`. Dropping the ancestor would turn a fleet's dependency declarations
104
+ * into `health.dependency-unmodelled` findings the day it migrated its models,
105
+ * with nothing in the docs having changed.
106
+ *
107
+ * UNOWNED is what the model added outside its own element — present in the
108
+ * project, absent from the architecture load, and resolving to somebody else. A
109
+ * new top-level element (`ledger` beside the map's systems) and a child added
110
+ * under another service's element both land here, and both are things the map
111
+ * or the other service should be declaring instead.
112
+ */
113
+ export function sliceForService(input) {
114
+ const resolve = serviceResolver(input.project.elements, input.known);
115
+ const byId = new Map(input.project.elements.map((e) => [e.id, e]));
116
+ const ownIds = new Set(input.project.elements.filter((e) => resolve(e.id) === input.service).map((e) => e.id));
117
+ // The elements the author extended: own, with nothing own above them. Frozen
118
+ // before the loop below adds anything, so a child pulled in by nesting cannot
119
+ // itself become a root and widen the set a second time.
120
+ const roots = [...ownIds].filter((id) => !properAncestorIds(id).some((up) => ownIds.has(up)));
121
+ for (const element of input.project.elements) {
122
+ if (ownIds.has(element.id))
123
+ continue;
124
+ if (!roots.some((root) => element.id.startsWith(`${root}.`)))
125
+ continue;
126
+ // The one thing nesting does not outrank. An explicit binding anywhere at or
127
+ // above this element names its service outright, and a map that files one
128
+ // service's element under another's would otherwise hand the outer service
129
+ // every element of the inner one.
130
+ if (boundServiceOf(element.id, byId) !== undefined)
131
+ continue;
132
+ ownIds.add(element.id);
133
+ }
134
+ // One budget per structural key: the map's copies cancel the project's, one
135
+ // for one, and what the budget does not cover is the model's own.
136
+ const budget = new Map();
137
+ for (const rel of input.architecture.relationships) {
138
+ const k = relKey(rel);
139
+ budget.set(k, (budget.get(k) ?? 0) + 1);
140
+ }
141
+ const relationships = input.project.relationships.filter((rel) => {
142
+ const k = relKey(rel);
143
+ const left = budget.get(k) ?? 0;
144
+ if (left === 0)
145
+ return true;
146
+ budget.set(k, left - 1);
147
+ return false;
148
+ });
149
+ const partnerIds = new Set();
150
+ for (const rel of relationships) {
151
+ for (const endpoint of [rel.source, rel.target]) {
152
+ if (ownIds.has(endpoint))
153
+ continue;
154
+ for (const id of [endpoint, ...properAncestorIds(endpoint)]) {
155
+ if (byId.has(id) && !ownIds.has(id))
156
+ partnerIds.add(id);
157
+ }
158
+ }
159
+ }
160
+ // Project order for both lists, never the order ids happened to be
161
+ // discovered in: the elements of a service are printed, counted and diffed,
162
+ // and a set that reorders itself between two runs of the same command is a
163
+ // diff nobody can read.
164
+ const archElementIds = new Set(input.architecture.elements.map((e) => e.id));
165
+ return {
166
+ elements: input.project.elements.filter((e) => ownIds.has(e.id) || partnerIds.has(e.id)),
167
+ relationships,
168
+ unowned: input.project.elements.filter((e) => !archElementIds.has(e.id) && !ownIds.has(e.id)),
169
+ };
170
+ }
171
+ /**
172
+ * The nearest explicit `metadata { service '…' }` binding at or above an id, or
173
+ * undefined when nothing on the chain declares one.
174
+ *
175
+ * `serviceResolver`'s first rung, asked on its own — because the caller above
176
+ * needs to tell that rung's answer apart from the two guesses below it, and the
177
+ * resolver returns one `DeclaredService` for all three. A binding is a claim
178
+ * somebody wrote down; a title match is evidence, and a bare title is a guess.
179
+ */
180
+ function boundServiceOf(id, byId) {
181
+ for (const candidate of [id, ...properAncestorIds(id)]) {
182
+ const bound = byId.get(candidate)?.service;
183
+ if (bound !== undefined)
184
+ return bound;
185
+ }
186
+ return undefined;
187
+ }
188
+ //# sourceMappingURL=slice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slice.js","sourceRoot":"","sources":["../../../../src/core/c4/service-model/slice.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAuBxD;;;;;;;;;;;;GAYG;AACH,SAAS,MAAM,CAAC,GAAQ;IACtB,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,GAAG,CAAC,MAAM;QACV,GAAG,CAAC,MAAM;QACV,GAAG,CAAC,KAAK,IAAI,EAAE;QACf,GAAG,CAAC,EAAE,IAAI,EAAE;QACZ,GAAG,CAAC,SAAS,IAAI,EAAE;QACnB,GAAG,CAAC,QAAQ,IAAI,EAAE;QAClB,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE;KACrB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACrE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,MAAM,GAAG,IAAI,GAAG,CACpB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACvF,CAAC;IACF,6EAA6E;IAC7E,8EAA8E;IAC9E,wDAAwD;IACxD,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9F,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC7C,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAAE,SAAS;QACrC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;YAAE,SAAS;QACvE,6EAA6E;QAC7E,0EAA0E;QAC1E,2EAA2E;QAC3E,kCAAkC;QAClC,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,SAAS;YAAE,SAAS;QAC7D,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IAED,4EAA4E;IAC5E,kEAAkE;IAClE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;QACnD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;QAC/D,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAChD,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAAE,SAAS;YACnC,KAAK,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;gBAC5D,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;oBAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,4EAA4E;IAC5E,2EAA2E;IAC3E,wBAAwB;IACxB,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7E,OAAO;QACL,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxF,aAAa;QACb,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC9F,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,cAAc,CAAC,EAAU,EAAE,IAA+B;IACjE,KAAK,MAAM,SAAS,IAAI,CAAC,EAAE,EAAE,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACvD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAC3C,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;IACxC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["/**\n * The service's OWN part of a per-service project — derived, because LikeC4\n * does not record it.\n *\n * Measured at the 1.59.2 pin: `$data.views[id]` carries a `sourcePath` and\n * `$data.elements[fqn]` carries NO source-document field at all. So after the\n * map and one extending model have been parsed together there is nothing in the\n * parse output that says which of the two files declared a given element. The\n * answer has to be reconstructed, and this module is the reconstruction: DIFF\n * the project against the architecture-alone load, and resolve what is left\n * through the same element→service resolver every fleet check already joins on.\n *\n * Why it matters that this is exact rather than approximate: every model-\n * dependent check reads the slice as if it were the standalone file it used to\n * read — `c4.no-relationships`, `health.dependency-unmodelled`, `Covers:`\n * resolution, the attested-call scan. Too WIDE and a service is graded against\n * the whole fleet map (every service would suddenly have relationships, and\n * every dependency would resolve). Too NARROW and a service that models its\n * partners correctly is told it models nothing.\n */\nimport { properAncestorIds } from \"../../kernel/ids/fqn/ancestors.js\";\nimport type { Elem, LoadedDoc, Rel } from \"../likec4.js\";\nimport { serviceResolver } from \"../resolve/service.js\";\n\n/** What one service owns inside a project that also holds the fleet map. */\nexport interface OwnSlice {\n /** The service's own elements, plus the partner elements its own edges point at. */\n elements: Elem[];\n /** Only the relationships this model added — the project's, minus the map's. */\n relationships: Rel[];\n /** Elements this model added OUTSIDE its own element: the `c4.element-unowned` set. */\n unowned: Elem[];\n}\n\nexport interface SliceRequest {\n /** The per-service project: the architecture documents and this model, parsed together. */\n project: LoadedDoc;\n /** The same architecture documents parsed WITHOUT the model — the diff's other half. */\n architecture: LoadedDoc;\n /** The `services/<…>/<id>` directory name this model belongs to. */\n service: string;\n /** Every service directory that exists, so an edge into a modelled container resolves to its owner. */\n known: ReadonlySet<string>;\n}\n\n/**\n * A relationship's identity for the DIFF, and every field of it is one loam\n * already reads somewhere.\n *\n * There is no id to join on: LikeC4 mints relationship ids per parse, so the\n * same edge in two loads of overlapping document sets is two different ids.\n * Endpoints alone are not enough either — a fleet may draw two edges between\n * the same pair (`api -> kafka 'publishes'` and `api -> kafka 'consumes'`), and\n * collapsing them would let a model silently inherit one of the map's. So the\n * key is everything a check can branch on: the endpoints, the label, and the\n * three metadata keys plus the tag set, sorted because tag order is authoring\n * order and means nothing.\n */\nfunction relKey(rel: Rel): string {\n return JSON.stringify([\n rel.source,\n rel.target,\n rel.title ?? \"\",\n rel.op ?? \"\",\n rel.publishes ?? \"\",\n rel.consumes ?? \"\",\n [...rel.tags].sort(),\n ]);\n}\n\n/**\n * The service's own slice of a per-service project.\n *\n * OWN is resolution PLUS NESTING, and the second half is not a widening for\n * convenience — it is the only thing that keeps a model's own file from being\n * filtered against it.\n *\n * Resolution first: every project element whose id resolves to this service,\n * whether the model added it or the map already declared it. The bound element\n * itself has to be in — a standalone model declared it, and every check that\n * reads \"the service's elements\" expects it.\n *\n * Then nesting, because resolution alone ejects a child the author wrote INSIDE\n * their own `extend` block. `serviceResolver`'s second rung answers with the\n * nearest ancestor whose TITLE names a real `services/<id>/` directory, and that\n * rung sees the child before it sees the parent: a container written as\n * `store = database 'db'` under `extend svcA { … }` resolves to a service called\n * `db` the moment some other team has adopted one, and svcA's own element is\n * bound by title only. The model then reported one element fewer than it\n * declares, a `Covers: svcA.store` line was convicted as a typo, and\n * `c4.element-unowned` told the author their own container belonged in somebody\n * else's model. A standalone model was never filtered against its own file at\n * all, so every one of those is a regression the second shape introduced.\n *\n * So: an OWN ROOT is an own element none of whose proper ancestors is own — the\n * element the author actually extended — and everything nested under one is own\n * too. Id nesting under the extended element is evidence nobody had to guess at,\n * and it outranks a title guess. It does NOT outrank an explicit\n * `metadata { service '…' }` binding, which is a claim somebody wrote down: a\n * map that nests one service's element inside another's keeps both on the right\n * side of the line.\n *\n * OWN RELATIONSHIPS are the diff: the project's edges minus the ones the\n * architecture documents already have. Resolution cannot decide this one, and\n * the reason is the whole point of the fleet map: the map is where cross-service\n * edges live, so `checkoutWeb -> paymentService` resolves to this service at one\n * end and must NOT become part of the model's own relationships — otherwise\n * every service would be graded as declaring calls it never wrote, and\n * `landscape.service-isolated` (which asks whether the map's edges and the\n * model's agree) would be answering about itself.\n *\n * The diff is a MULTISET difference, not a set one, and that distinction is the\n * whole grade for a model that agrees with the map. A model may legitimately\n * draw an edge the map also draws, spelled identically —\n * `marketplace.paymentService -> stripe 'Authorizes cards'` — and under a set\n * difference every such edge would vanish from the model's own list. Then\n * `attestedCalls` finds no attested call, `landscape.service-isolated` reports a\n * service that talks to nobody, the adopt brief's `landscape.attested` list\n * comes back empty and `c4.no-relationships` fires on a model full of edges. So\n * each structural key drops `min(architecture, project)` occurrences and the\n * rest are the model's: one copy in the map cancels exactly one copy here.\n *\n * PARTNERS are the endpoints of the model's own edges that lie outside the\n * service, AND every ancestor of such an endpoint that the project holds. The\n * ancestors are not tidiness: a standalone model had to declare `kafka` in order\n * to draw an edge at `kafka.orderEvents`, and health.yaml names the dependency\n * `kafka`. Dropping the ancestor would turn a fleet's dependency declarations\n * into `health.dependency-unmodelled` findings the day it migrated its models,\n * with nothing in the docs having changed.\n *\n * UNOWNED is what the model added outside its own element — present in the\n * project, absent from the architecture load, and resolving to somebody else. A\n * new top-level element (`ledger` beside the map's systems) and a child added\n * under another service's element both land here, and both are things the map\n * or the other service should be declaring instead.\n */\nexport function sliceForService(input: SliceRequest): OwnSlice {\n const resolve = serviceResolver(input.project.elements, input.known);\n const byId = new Map(input.project.elements.map((e) => [e.id, e]));\n const ownIds = new Set(\n input.project.elements.filter((e) => resolve(e.id) === input.service).map((e) => e.id),\n );\n // The elements the author extended: own, with nothing own above them. Frozen\n // before the loop below adds anything, so a child pulled in by nesting cannot\n // itself become a root and widen the set a second time.\n const roots = [...ownIds].filter((id) => !properAncestorIds(id).some((up) => ownIds.has(up)));\n for (const element of input.project.elements) {\n if (ownIds.has(element.id)) continue;\n if (!roots.some((root) => element.id.startsWith(`${root}.`))) continue;\n // The one thing nesting does not outrank. An explicit binding anywhere at or\n // above this element names its service outright, and a map that files one\n // service's element under another's would otherwise hand the outer service\n // every element of the inner one.\n if (boundServiceOf(element.id, byId) !== undefined) continue;\n ownIds.add(element.id);\n }\n\n // One budget per structural key: the map's copies cancel the project's, one\n // for one, and what the budget does not cover is the model's own.\n const budget = new Map<string, number>();\n for (const rel of input.architecture.relationships) {\n const k = relKey(rel);\n budget.set(k, (budget.get(k) ?? 0) + 1);\n }\n const relationships = input.project.relationships.filter((rel) => {\n const k = relKey(rel);\n const left = budget.get(k) ?? 0;\n if (left === 0) return true;\n budget.set(k, left - 1);\n return false;\n });\n\n const partnerIds = new Set<string>();\n for (const rel of relationships) {\n for (const endpoint of [rel.source, rel.target]) {\n if (ownIds.has(endpoint)) continue;\n for (const id of [endpoint, ...properAncestorIds(endpoint)]) {\n if (byId.has(id) && !ownIds.has(id)) partnerIds.add(id);\n }\n }\n }\n\n // Project order for both lists, never the order ids happened to be\n // discovered in: the elements of a service are printed, counted and diffed,\n // and a set that reorders itself between two runs of the same command is a\n // diff nobody can read.\n const archElementIds = new Set(input.architecture.elements.map((e) => e.id));\n return {\n elements: input.project.elements.filter((e) => ownIds.has(e.id) || partnerIds.has(e.id)),\n relationships,\n unowned: input.project.elements.filter((e) => !archElementIds.has(e.id) && !ownIds.has(e.id)),\n };\n}\n\n/**\n * The nearest explicit `metadata { service '…' }` binding at or above an id, or\n * undefined when nothing on the chain declares one.\n *\n * `serviceResolver`'s first rung, asked on its own — because the caller above\n * needs to tell that rung's answer apart from the two guesses below it, and the\n * resolver returns one `DeclaredService` for all three. A binding is a claim\n * somebody wrote down; a title match is evidence, and a bare title is a guess.\n */\nfunction boundServiceOf(id: string, byId: ReadonlyMap<string, Elem>): string | undefined {\n for (const candidate of [id, ...properAncestorIds(id)]) {\n const bound = byId.get(candidate)?.service;\n if (bound !== undefined) return bound;\n }\n return undefined;\n}\n"]}