@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
@@ -1 +1 @@
1
- {"version":3,"file":"landscape-merge.js","sourceRoot":"","sources":["../../../../src/core/c4/splice/landscape-merge.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport { loadSource, type Elem, type Rel } from \"../likec4.js\";\nimport { elementService, serviceOf } from \"../resolve/service.js\";\nimport { scanModel, type ScannedElement, type ScannedModel, type ScannedRel } from \"../source-scan.js\";\nimport { spliceSource } from \"./authored-source.js\";\nimport { LandscapeSpliceError, type LandscapeMergeRequest, type LandscapePlan } from \"./contract.js\";\nimport { assertMergeableDelta } from \"./delta-blocks.js\";\nimport { relKey, relSortKey } from \"./identity/edges.js\";\nimport {\n elementSpot,\n nestedInsert,\n relSpot,\n topStatements,\n type ModelRegion,\n type Spot,\n} from \"./placement.js\";\n\n/* ------------------------------------------------------------------ */\n/* Merging */\n/* ------------------------------------------------------------------ */\n\n/**\n * Plan the merge of the feature's new elements + relationships into the living\n * landscape's `model { ... }` block (preserving the rest of the file).\n *\n * The additions are SPLICED from delta.likec4 as authored — byte for byte,\n * technology, style, icons, links, metadata, nested children and all — never\n * re-serialized from the parsed model: a rebuild keeps only the fields loam\n * models, and every field it forgets is authored detail destroyed. The one\n * edit on the way over is dropping the feature's own tag — the additions are\n * baseline now (SCHEMA.md documents the drop as why unarchive restores bytes\n * instead of recomputing) — and a construct the strip empties goes with it.\n *\n * Placement is deterministic and SERVICE-GROUPED (the spot* helpers in\n * placement.ts):\n * a top-level addition lands beside what already belongs to its service, so\n * two concurrent archives touching different services usually splice on\n * different lines and git merges their PRs — the single shared append point\n * every archive used to hit made two concurrent archives conflict BY\n * CONSTRUCTION. A NESTED element lands inside its parent's block — inside the\n * living parent when the landscape already has it, riding verbatim inside the\n * spliced parent when the parent is new from the same delta — never as a flat\n * dotted id at top level, which LikeC4 rejects. The additions carry no marker\n * comment: which archive added what is the git history's to say.\n *\n * Existence is checked semantically against the parsed landscape (by element\n * id/title and by edge identity), so re-archiving is idempotent and title\n * strings appearing elsewhere in the source cause no false skips. Assumes the\n * delta reuses the landscape's element identifiers for existing services. A\n * title match whose two sides are BOTH bound to different services is not an\n * existence hit but a collision, and refuses the archive (see the guard).\n *\n * Splicing is text surgery, so the computed result is PARSED before it is\n * returned: a merged landscape LikeC4 rejects refuses the archive at plan time\n * (merge-failed, nothing written — the unparseable-delta discipline) instead\n * of landing in the living docs.\n */\nexport async function planLandscapeMerge(merge: LandscapeMergeRequest): Promise<LandscapePlan> {\n const { landscapeText: text, deltaText, deltaElements, newEls, newRels, featureId } = merge;\n // First, and before the early return for \"nothing to add\": a block this merge\n // cannot carry is lost whether or not the delta also has tagged elements to\n // splice. See delta-blocks.ts.\n assertMergeableDelta(deltaText);\n const land = await loadSource(text);\n if (land.errors.length > 0) {\n throw new LandscapeSpliceError(`landscape.likec4 has ${land.errors.length} error(s) — fix it before archiving`);\n }\n const haveIds = new Set(land.elements.map((e) => e.id));\n // The title join needs the matched element back, not just membership: the\n // cross-service guard below compares service BINDINGS across the join.\n const byTitle = new Map<string, Elem[]>();\n const seeTitle = (el: Elem): void => {\n byTitle.set(el.title, [...(byTitle.get(el.title) ?? []), el]);\n };\n for (const el of land.elements) seeTitle(el);\n const addedEls: Elem[] = [];\n for (const e of newEls) {\n if (haveIds.has(e.id)) continue;\n const sameTitle = byTitle.get(e.title);\n if (sameTitle !== undefined) {\n // A title match is the id-less fallback join, and skipping on it is only\n // safe when the two sides could be the same box. When both sides carry an\n // explicit `metadata { service }` binding and every binding disagrees,\n // they are provably DIFFERENT services' boxes sharing a title ('API',\n // 'Database') — the skip would silently drop the addition, and any delta\n // edge into it would then refuse the whole archive at the parse net\n // below with a message about nothing. Refuse here instead, at plan time,\n // naming both sides.\n if (e.service !== undefined && sameTitle.every((m) => m.service !== undefined && m.service !== e.service)) {\n const m = sameTitle[0]!;\n throw new LandscapeSpliceError(\n `the delta's '${e.id}' (bound to service '${e.service}') shares the title '${e.title}' with '${m.id}' (bound to service '${m.service}') — a title join across services would silently drop the addition; ` +\n `retitle one of them, or reuse the id '${m.id}' if they really are the same element`,\n );\n }\n // KNOWN (narrowed by the guard above): with EITHER side unbound the title\n // join stays trusting — the unbound title-fallback is the legal legacy\n // pattern — so a cross-service collision hiding behind an unbound element\n // is still silently skipped here. Scoping titles per service is backlog.\n continue;\n }\n haveIds.add(e.id);\n seeTitle(e);\n addedEls.push(e);\n }\n\n // Edges are matched by COUNT, not by membership: two edges the model cannot tell\n // apart are still two edges, and dropping the second one silently loses a call\n // the author drew. An edge already in the landscape consumes one delta edge of\n // the same identity, which is what keeps re-archiving idempotent.\n const have = new Map<string, number>();\n for (const r of land.relationships) {\n const k = relKey(land.elements, r);\n have.set(k, (have.get(k) ?? 0) + 1);\n }\n const addedRels: Rel[] = [];\n for (const r of newRels) {\n const k = relKey(deltaElements, r);\n const n = have.get(k) ?? 0;\n if (n > 0) {\n have.set(k, n - 1);\n continue;\n }\n addedRels.push(r);\n }\n\n if (addedEls.length === 0 && addedRels.length === 0) return { content: null, addedEls, addedRels };\n\n const scan = scanModel(deltaText);\n if (scan === null) {\n throw new LandscapeSpliceError(\"delta.likec4 has no model block — nothing to splice the additions from\");\n }\n\n // Everything below either locates a declaration's authored bytes or refuses.\n // `spliced` remembers the delta ranges already carried over, so a child whose\n // parent is itself new is recognised as riding inside the parent's text and\n // is never inserted twice.\n const byId = new Map(scan.elements.map((e) => [e.id, e]));\n const spliced: Array<{ start: number; end: number }> = [];\n const rides = (start: number, end: number): boolean =>\n spliced.some((r) => start >= r.start && end <= r.end);\n\n // The living model, scanned on MASKED source (scanModel) and RE-SCANNED\n // after every splice: each addition lands in the text exactly as the\n // previous one left it, so an archive of N additions produces the same\n // bytes as N single-addition archives run back to back. Placement then\n // composes per statement — the unit the order-independence argument below\n // is stated in — instead of per archive, where a batch computed against a\n // stale layout could interleave with itself. Masking matters — a `model {`\n // spelled inside a comment or string above the real block must not capture\n // the match, or every top-level addition lands inside the comment (legal\n // LikeC4, so the parse net below would pass a landscape containing none of\n // the architecture).\n let content = text;\n // Service binding for placement: living elements first (they win a shared\n // id), the delta's after — a spliced statement's id resolves to its service\n // the moment its bytes land in the scan.\n const bindEls = [...land.elements, ...deltaElements.filter((d) => !land.elements.some((l) => l.id === d.id))];\n let livingScan = scanModel(content);\n let stmts = livingScan === null ? [] : topStatements(livingScan, bindEls);\n const rescan = (): void => {\n livingScan = scanModel(content);\n stmts = livingScan === null ? [] : topStatements(livingScan, bindEls);\n };\n const requireModel = (): ScannedModel => {\n if (livingScan === null) throw new LandscapeSpliceError(\"landscape.likec4 has no model block\");\n return livingScan;\n };\n // Built fresh at every use, never captured: `content` and `stmts` are rebound\n // by each rescan, and a region assembled before a splice describes a document\n // that no longer exists.\n const modelRegion = (): ModelRegion => ({ text: content, stmts, close: requireModel().close });\n const applyAt = (at: number, insert: string): void => {\n content = content.slice(0, at) + insert + content.slice(at);\n rescan();\n };\n const applyTop = (spot: Spot, block: string): void => {\n // A bare spot shares its line with other text (the closing brace, or a\n // statement the block displaces) — it brings its own newlines; a\n // line-start spot slots between lines.\n applyAt(spot.at, spot.bare ? `\\n${block}\\n` : `${block}\\n`);\n };\n\n // Placement walks the scanned statement layout, so a declaration the scan\n // cannot see is one placement would blindly splice around — LikeC4 accepts\n // two declarations on one line, but scanModel's statement head runs to the\n // end of the line, so the second rides invisibly inside the first: an\n // element bound to its service would miss its neighborhood, and a bodyless\n // parent gaining a body could wrap the wrong declaration. Refuse\n // mechanically (the parse-net discipline) instead of splicing blind.\n if (livingScan !== null) {\n const seen = new Set(livingScan.elements.map((e) => e.id));\n const invisible = land.elements.find((e) => !seen.has(e.id));\n if (invisible !== undefined) {\n throw new LandscapeSpliceError(\n `landscape.likec4 declares '${invisible.id}' in a form placement cannot locate — most often two declarations sharing one line; give each its own line, then re-run`,\n );\n }\n if (livingScan.rels.length < land.relationships.length) {\n throw new LandscapeSpliceError(\n `landscape.likec4 declares ${land.relationships.length} relationship(s) but placement can locate only ${livingScan.rels.length} — most often two statements sharing one line; give each its own line, then re-run`,\n );\n }\n }\n\n const livingParentOf = (parentId: string): ScannedElement | null => {\n if (livingScan === null) return null;\n const direct = livingScan.elements.find((e) => e.id === parentId);\n if (direct !== undefined) return direct;\n // The delta may spell an existing element under its own id; the title is\n // the stable cross-namespace name (the same rule the existence check uses).\n const title = deltaElements.find((e) => e.id === parentId)?.title;\n const livingId = title === undefined ? undefined : land.elements.find((e) => e.title === title)?.id;\n if (livingId === undefined) return null;\n return livingScan.elements.find((e) => e.id === livingId) ?? null;\n };\n\n // Ancestors first: a spliced parent covers its children before they are seen.\n const depth = (id: string): number => id.split(\".\").length;\n const sortedEls = [...addedEls].sort(\n (a, b) => depth(a.id) - depth(b.id) || (byId.get(a.id)?.start ?? 0) - (byId.get(b.id)?.start ?? 0),\n );\n for (const e of sortedEls) {\n const src = byId.get(e.id);\n if (src === undefined) {\n throw new LandscapeSpliceError(\n `cannot locate '${e.id}' in delta.likec4 — the landscape merge splices authored source, and this declaration was not found`,\n );\n }\n if (rides(src.start, src.end)) continue;\n const dot = e.id.lastIndexOf(\".\");\n if (dot === -1) {\n const spot = elementSpot(modelRegion(), e.id, elementService(e));\n applyTop(spot, spliceSource(deltaText, src, featureId, \" \"));\n spliced.push({ start: src.start, end: src.end });\n continue;\n }\n const parentId = e.id.slice(0, dot);\n const parent = livingParentOf(parentId);\n if (parent === null) {\n throw new LandscapeSpliceError(\n `'${e.id}' nests under '${parentId}', which is neither in the living landscape nor added by this delta — there is nowhere to insert it`,\n );\n }\n const nested = nestedInsert(content, parent, spliceSource(deltaText, src, featureId, parent.indent + \" \"));\n applyAt(nested.at, nested.insert);\n spliced.push({ start: src.start, end: src.end });\n }\n\n // Relationships: match each parsed addition back to its statement in the\n // delta source — full identity (endpoints, title, all three spine keys,\n // tags), consumed one statement per addition so duplicates stay duplicates.\n // The spine keys earn their place here the same way they do in `relKey`:\n // without them two additions differing only by `publishes` share one pool\n // entry, and `shift()` hands the second one the first one's authored bytes.\n const relKeyOf = (r: Rel | ScannedRel): string =>\n JSON.stringify([r.source, r.target, r.title ?? \"\", r.op ?? \"\", r.publishes ?? \"\", r.consumes ?? \"\", [...r.tags].sort()]);\n const pool = new Map<string, ScannedRel[]>();\n for (const s of scan.rels) {\n const k = relKeyOf(s);\n pool.set(k, [...(pool.get(k) ?? []), s]);\n }\n for (const r of addedRels) {\n const s = pool.get(relKeyOf(r))?.shift();\n if (s === undefined) {\n throw new LandscapeSpliceError(\n `cannot locate the '${r.source} -> ${r.target}' relationship in delta.likec4 — the landscape merge splices authored source, and no matching declaration was found`,\n );\n }\n if (rides(s.start, s.end)) continue;\n const key = relSortKey(deltaElements, r);\n // Deliberately no `known` fleet set: this resolves only the anchor a new\n // relationship lands after (placement.ts's reason — cosmetic grouping,\n // safety-netted by the re-parse below), never which service a check\n // grades.\n const spot = relSpot(modelRegion(), serviceOf(deltaElements, r.source), key);\n applyTop(spot, spliceSource(deltaText, s, featureId, \" \"));\n }\n\n // The safety net: prove the computed landscape parses before anything is\n // written. Splice bugs — and legal inputs the living document cannot absorb,\n // like a kind its specification never declares — refuse here, at plan time,\n // instead of corrupting the one file the whole fleet reads.\n const check = await loadSource(content);\n if (check.errors.length > 0) {\n const detail = check.errors\n .slice(0, 3)\n .map((e) => (typeof e.line === \"number\" ? `L${e.line}: ${e.message}` : e.message))\n .join(\"; \");\n throw new LandscapeSpliceError(\n `the merged landscape would not parse (${check.errors.length} error(s): ${detail}) — nothing was written. ` +\n `The delta's additions do not fit the living landscape as authored — most often an element kind or tag ` +\n `its specification block does not declare; fix the landscape's specification or the delta, then re-run`,\n );\n }\n\n return { content, addedEls, addedRels };\n}\n"]}
1
+ {"version":3,"file":"landscape-merge.js","sourceRoot":"","sources":["../../../../src/core/c4/splice/landscape-merge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAuB,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,SAAS,EAA2D,MAAM,mBAAmB,CAAC;AACtH,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GAKrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAoB,MAAM,gBAAgB,CAAC;AACvF,OAAO,EAAE,YAAY,EAAa,MAAM,gBAAgB,CAAC;AAEzD,wEAAwE;AACxE,yEAAyE;AACzE,wEAAwE;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAA4B;IACnE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC5F,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;IAClC,6EAA6E;IAC7E,iFAAiF;IACjF,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACrC,8EAA8E;IAC9E,4EAA4E;IAC5E,+BAA+B;IAC/B,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,oBAAoB,CAAC,wBAAwB,IAAI,CAAC,MAAM,CAAC,MAAM,qCAAqC,CAAC,CAAC;IAClH,CAAC;IACD,yEAAyE;IACzE,8EAA8E;IAC9E,gFAAgF;IAChF,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9G,+EAA+E;IAC/E,+EAA+E;IAC/E,MAAM,KAAK,GAAG,YAAY,CAAC;QACzB,SAAS,EAAE,IAAI,CAAC,QAAQ;QACxB,UAAU,EAAE,IAAI,CAAC,aAAa;QAC9B,OAAO;QACP,aAAa;QACb,UAAU,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE;QAC1C,MAAM;QACN,QAAQ;KACT,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC;QACnD,MAAM,IAAI,oBAAoB,CAC5B,gBAAgB,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC,OAAO,wBAAwB,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC,OAAO,sEAAsE;YACxM,yCAAyC,CAAC,CAAC,EAAE,uCAAuC,CACvF,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC;IAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;IAE7B,MAAM,KAAK,GAAG,OAAO,CAAC;QACpB,OAAO;QACP,MAAM,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/C,QAAQ,EAAE,KAAK,CAAC,WAAW;QAC3B,KAAK,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM;KACP,CAAC,CAAC;IACH,4EAA4E;IAC5E,0EAA0E;IAC1E,0EAA0E;IAC1E,0EAA0E;IAC1E,0EAA0E;IAC1E,2EAA2E;IAC3E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACpE,CAAC;IAED,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,oBAAoB,CAAC,wEAAwE,CAAC,CAAC;IAC3G,CAAC;IAED,6EAA6E;IAC7E,8EAA8E;IAC9E,4EAA4E;IAC5E,2BAA2B;IAC3B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,yEAAyE;IACzE,2EAA2E;IAC3E,uEAAuE;IACvE,4EAA4E;IAC5E,8EAA8E;IAC9E,mFAAmF;IACnF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,SAAS,GAAG,aAAa,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IACjD,MAAM,IAAI,GAAG,CAAC,KAAqB,EAAkB,EAAE;QACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;QAC5C,MAAM,KAAK,GAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;QACrE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,MAAM;QAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAE/E,MAAM,MAAM,GAAW,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3B,2EAA2E;QAC3E,0EAA0E;QAC1E,4EAA4E;QAC5E,yEAAyE;QACzE,MAAM,IAAI,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChE,IAAI,IAAI,KAAK,OAAO;YAAE,SAAS;QAC/B,MAAM,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrE,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;;YACnC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,MAAM,OAAO,GAAU,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,yEAAyE;QACzE,mEAAmE;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACjD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACvF,2EAA2E;QAC3E,2EAA2E;QAC3E,2EAA2E;QAC3E,WAAW;QACX,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/F,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;;YACpC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAE3D,MAAM,OAAO,GAA0C,EAAE,CAAC;IAC1D,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,GAAW,EAAW,EAAE,CACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAExD,wEAAwE;IACxE,qEAAqE;IACrE,uEAAuE;IACvE,uEAAuE;IACvE,0EAA0E;IAC1E,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,yEAAyE;IACzE,2EAA2E;IAC3E,qBAAqB;IACrB,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,KAAK,GAAG,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,GAAG,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC,CAAC;IACF,MAAM,YAAY,GAAG,GAAiB,EAAE;QACtC,IAAI,UAAU,KAAK,IAAI;YAAE,MAAM,IAAI,oBAAoB,CAAC,qCAAqC,CAAC,CAAC;QAC/F,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;IACF,8EAA8E;IAC9E,8EAA8E;IAC9E,yBAAyB;IACzB,MAAM,WAAW,GAAG,GAAgB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IACjG,uEAAuE;IACvE,MAAM,OAAO,GAAG,CAAC,EAAU,EAAE,MAAc,EAAE,IAAY,EAAQ,EAAE;QACjE,MAAM,MAAM,GAAG,UAAU,CAAC;QAC1B,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5D,MAAM,EAAE,CAAC;QACT,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IAChD,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,CAAC,IAAU,EAAE,KAAa,EAAE,IAAY,EAAQ,EAAE;QACjE,uEAAuE;QACvE,iEAAiE;QACjE,uCAAuC;QACvC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC,CAAC;IAEF,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,sEAAsE;IACtE,2EAA2E;IAC3E,iEAAiE;IACjE,qEAAqE;IACrE,EAAE;IACF,yEAAyE;IACzE,8EAA8E;IAC9E,0EAA0E;IAC1E,sEAAsE;IACtE,0EAA0E;IAC1E,6EAA6E;IAC7E,iCAAiC;IACjC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QAC/G,IAAI,KAAK;YAAE,MAAM,IAAI,oBAAoB,CAAC,eAAe,CAAC,kBAAkB,EAAE,MAAM,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACzH,CAAC;IAED,MAAM,cAAc,GAAG,CAAC,QAAgB,EAAyB,EAAE;QACjE,IAAI,UAAU,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACrC,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;QAClE,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QACxC,yEAAyE;QACzE,4EAA4E;QAC5E,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,KAAK,CAAC;QAClE,MAAM,QAAQ,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,EAAE,CAAC;QACpG,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACxC,OAAO,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC;IACpE,CAAC,CAAC;IAEF,8EAA8E;IAC9E,MAAM,KAAK,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3D,MAAM,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAChC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CACnG,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,IAAI,oBAAoB,CAC5B,kBAAkB,CAAC,CAAC,EAAE,qGAAqG,CAC5H,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QACxC,gEAAgE;QAChE,wEAAwE;QACxE,2EAA2E;QAC3E,kCAAkC;QAClC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;QAC5B,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,WAAW,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;YACjE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YACtF,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;YACjD,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,MAAM,IAAI,oBAAoB,CAC5B,IAAI,CAAC,CAAC,EAAE,kBAAkB,QAAQ,qGAAqG,CACxI,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,YAAY,CACzB,OAAO,EACP,MAAM,EACN,YAAY,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,CAChF,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,2EAA2E;IAC3E,6DAA6D;IAC7D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QAChD,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACpB,MAAM,IAAI,oBAAoB,CAC5B,sBAAsB,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,MAAM,qHAAqH,CACnK,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC;YAAE,SAAS;QACpC,MAAM,GAAG,GAAG,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;QACzC,yEAAyE;QACzE,uEAAuE;QACvE,oEAAoE;QACpE,UAAU;QACV,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,EAAE,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;QAC7E,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACxG,CAAC;IAED,yEAAyE;IACzE,6EAA6E;IAC7E,4EAA4E;IAC5E,yEAAyE;IACzE,4EAA4E;IAC5E,2EAA2E;IAC3E,oDAAoD;IACpD,6EAA6E;IAC7E,4EAA4E;IAC5E,yBAAyB;IACzB,OAAO,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1C,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM;iBACxB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;iBACX,GAAG,CAAC,SAAS,CAAC;iBACd,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,MAAM,IAAI,oBAAoB,CAC5B,yCAAyC,KAAK,CAAC,MAAM,CAAC,MAAM,cAAc,MAAM,2BAA2B;gBACzG,wGAAwG;gBACxG,uGAAuG,CAC1G,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;AACtH,CAAC","sourcesContent":["\nimport { parentIdOf } from \"../../kernel/ids/fqn/ancestors.js\";\nimport { errorText, loadSource, type Elem, type Rel } from \"../likec4.js\";\nimport { firstUnlocated, unlocatedReason } from \"../locate/unlocated.js\";\nimport { elementService, serviceOf } from \"../resolve/service.js\";\nimport { kindsDeclared, scanModel, type ScannedElement, type ScannedModel, type ScannedRel } from \"../source-scan.js\";\nimport { matchLineEndings, spliceSource } from \"./authored-source.js\";\nimport {\n assertSpliceVisible,\n LandscapeSpliceError,\n type ExtendingModel,\n type LandscapeMergeRequest,\n type LandscapePlan,\n type ModelAdditions,\n} from \"./contract.js\";\nimport { assertMergeableDelta } from \"./delta-blocks.js\";\nimport { relSortKey, relStatementKey, scannedStatementKey } from \"./identity/edges.js\";\nimport { newAdditions } from \"./identity/existing.js\";\nimport { planInteriors } from \"./identity/interior.js\";\nimport { ownerOf } from \"./identity/owner.js\";\nimport { elementSpot, relSpot, topStatements, type ModelRegion } from \"./placement.js\";\nimport { nestedInsert, type Spot } from \"./text/spot.js\";\n\n/* ------------------------------------------------------------------ */\n/* Merging */\n/* ------------------------------------------------------------------ */\n\n/**\n * Plan the merge of the feature's new elements + relationships into the living\n * landscape's `model { ... }` block (preserving the rest of the file).\n *\n * The additions are SPLICED from delta.likec4 as authored — byte for byte,\n * technology, style, icons, links, metadata, nested children and all — never\n * re-serialized from the parsed model: a rebuild keeps only the fields loam\n * models, and every field it forgets is authored detail destroyed. The one\n * edit on the way over is dropping the feature's own tag — the additions are\n * baseline now (SCHEMA.md documents the drop as why unarchive restores bytes\n * instead of recomputing) — and a construct the strip empties goes with it.\n *\n * Placement is deterministic and SERVICE-GROUPED (the spot* helpers in\n * placement.ts):\n * a top-level addition lands beside what already belongs to its service, so\n * two concurrent archives touching different services usually splice on\n * different lines and git merges their PRs — the single shared append point\n * every archive used to hit made two concurrent archives conflict BY\n * CONSTRUCTION. A NESTED element lands inside its parent's block — inside the\n * living parent when the landscape already has it, riding verbatim inside the\n * spliced parent when the parent is new from the same delta — never as a flat\n * dotted id at top level, which LikeC4 rejects. The additions carry no marker\n * comment: which archive added what is the git history's to say.\n *\n * Existence is checked semantically against the parsed landscape AND against\n * every extending model the request carries (by element id/title and by edge\n * identity), so re-archiving is idempotent whichever document the additions\n * landed in — `./identity/existing.ts` holds that phase and its two joins, and\n * this function only turns the collision it reports into the refusal.\n *\n * Splicing is text surgery, so the computed result is PARSED before it is\n * returned: a merged landscape LikeC4 rejects refuses the archive at plan time\n * (merge-failed, nothing written — the unparseable-delta discipline) instead\n * of landing in the living docs.\n *\n * NOT EVERYTHING LANDS HERE. A service whose model EXTENDS this map owns its\n * own interior, and an addition nested under such a service is ROUTED to that\n * model instead (`./identity/owner.ts` decides, `./model/merge.ts` splices).\n * Until it was, a delta's container landed in the map and the service was\n * `c4.invalid` — a duplicate declaration — the moment its model wrote the same\n * container, which is exactly what the adopt brief tells it to do\n * (verification 2026-09-04, E1). With no extending models in the request this\n * function behaves as it always did.\n *\n * Routing per ADDITION is not the whole of it, because a service the feature\n * INTRODUCES carries its interior in one element's authored bytes and those\n * children carry no feature tag of their own. `./identity/interior.ts` decides, once\n * per such block, whether it hands that interior to the model — cut out of what\n * lands on the map — or rides whole; the routing below DEFERS to that decision\n * for everything written inside the block, which is what keeps the two from\n * placing the same child twice.\n */\nexport async function planLandscapeMerge(merge: LandscapeMergeRequest): Promise<LandscapePlan> {\n const { landscapeText: text, deltaText, deltaElements, newEls, newRels, featureId } = merge;\n const models = merge.models ?? [];\n // What every extending model borrows from this map: its kinds, without which\n // a model's scan reads `container outbox` and `a .delivers b` as property lines.\n const borrowed = kindsDeclared(text);\n // First, and before the early return for \"nothing to add\": a block this merge\n // cannot carry is lost whether or not the delta also has tagged elements to\n // splice. See delta-blocks.ts.\n assertMergeableDelta(deltaText);\n const land = await loadSource(text);\n if (land.errors.length > 0) {\n throw new LandscapeSpliceError(`landscape.likec4 has ${land.errors.length} error(s) — fix it before archiving`);\n }\n // Service binding for the existence joins AND for routing and placement:\n // living elements first (they win a shared id), the delta's after — a spliced\n // statement's id resolves to its service the moment its bytes land in the scan.\n const bindEls = [...land.elements, ...deltaElements.filter((d) => !land.elements.some((l) => l.id === d.id))];\n // What the living fleet already has — the map AND every extending model, by id\n // and by title. `./identity/existing.ts` holds both joins and their asymmetry.\n const added = newAdditions({\n livingEls: land.elements,\n livingRels: land.relationships,\n bindEls,\n deltaElements,\n candidates: { els: newEls, rels: newRels },\n models,\n borrowed,\n });\n if (added.collision !== undefined) {\n const { addition: e, living: m } = added.collision;\n throw new LandscapeSpliceError(\n `the delta's '${e.id}' (bound to service '${e.service}') shares the title '${e.title}' with '${m.id}' (bound to service '${m.service}') — a title join across services would silently drop the addition; ` +\n `retitle one of them, or reuse the id '${m.id}' if they really are the same element`,\n );\n }\n const addedEls = added.els;\n const addedRels = added.rels;\n\n const owner = ownerOf({\n bindEls,\n living: new Set(land.elements.map((e) => e.id)),\n declared: added.declaredIds,\n added: new Set(addedEls.map((e) => e.id)),\n models,\n });\n // Nothing to add: the same shape the merge returned before routing existed,\n // and the reason it is decided HERE rather than after the loops below — a\n // no-op archive must not have to scan the delta, nor answer the landscape\n // guards further down, which refuse documents this merge is not touching.\n // Equivalent to the old \"nothing reached the map and nothing was routed\":\n // every addition ends up in one of those two, so an empty pair means both.\n if (addedEls.length === 0 && addedRels.length === 0) {\n return { content: null, addedEls: [], addedRels: [], models: [] };\n }\n\n const scan = scanModel(deltaText);\n if (scan === null) {\n throw new LandscapeSpliceError(\"delta.likec4 has no model block — nothing to splice the additions from\");\n }\n\n // Everything below either locates a declaration's authored bytes or refuses.\n // `spliced` remembers the delta ranges already carried over, so a child whose\n // parent is itself new is recognised as riding inside the parent's text and\n // is never inserted twice.\n const byId = new Map(scan.elements.map((e) => [e.id, e]));\n // Relationships: match each parsed addition back to its statement in the\n // delta source — full identity (`relStatementKey`), consumed one statement\n // per addition so duplicates stay duplicates. Built before the routing\n // because routing has to know WHERE an edge was written: one drawn inside a\n // block that rides whole is already on the map. A statement is keyed with the\n // tags its kind gives it, which the parsed addition carries and its text does not.\n const pool = new Map<string, ScannedRel[]>();\n for (const s of scan.rels) {\n const k = scannedStatementKey(s, merge.deltaKindTags ?? {});\n pool.set(k, [...(pool.get(k) ?? []), s]);\n }\n\n const interiors = planInteriors({ scan, deltaElements, owner, addedEls });\n const routed = new Map<string, ModelAdditions>();\n const into = (model: ExtendingModel): ModelAdditions => {\n const existing = routed.get(model.path);\n if (existing !== undefined) return existing;\n const fresh: ModelAdditions = { model, els: [], rels: [], borrowed };\n routed.set(model.path, fresh);\n return fresh;\n };\n for (const share of interiors.routed) into(share.model).els.push(...share.els);\n\n const mapEls: Elem[] = [];\n for (const e of addedEls) {\n const src = byId.get(e.id);\n // Written inside a block that has already decided: a split block handed it\n // to the model with its siblings, and a whole one carries it onto the map\n // in the parent's own bytes, where the splice loop's `rides` finds it. Both\n // are placed exactly once, which is the point of asking the block first.\n const fate = src === undefined ? null : interiors.covering(src);\n if (fate === \"split\") continue;\n const model = fate === \"whole\" ? undefined : owner(parentIdOf(e.id));\n if (model === undefined) mapEls.push(e);\n else into(model).els.push(e);\n }\n const mapRels: Rel[] = [];\n for (const r of addedRels) {\n // An edge written inside a block that rides whole names its endpoints by\n // their LOCAL names and reads only there; it stays with its block.\n const stmts = pool.get(relStatementKey(r)) ?? [];\n const inBlock = stmts.length > 0 && stmts.every((s) => interiors.covering(s) !== null);\n // Otherwise the SOURCE decides: a call is drawn where the caller draws its\n // calls, and only when the source is not itself interior does the target's\n // owner get the edge. A service-level edge belongs to neither and stays on\n // the map.\n const model = inBlock ? undefined : owner(parentIdOf(r.source)) ?? owner(parentIdOf(r.target));\n if (model === undefined) mapRels.push(r);\n else into(model).rels.push(r);\n }\n const touchesMap = mapEls.length > 0 || mapRels.length > 0;\n\n const spliced: Array<{ start: number; end: number }> = [];\n const rides = (start: number, end: number): boolean =>\n spliced.some((r) => start >= r.start && end <= r.end);\n\n // The living model, scanned on MASKED source (scanModel) and RE-SCANNED\n // after every splice: each addition lands in the text exactly as the\n // previous one left it, so an archive of N additions produces the same\n // bytes as N single-addition archives run back to back. Placement then\n // composes per statement — the unit the order-independence argument below\n // is stated in — instead of per archive, where a batch computed against a\n // stale layout could interleave with itself. Masking matters — a `model {`\n // spelled inside a comment or string above the real block must not capture\n // the match, or every top-level addition lands inside the comment (legal\n // LikeC4, so the parse net below would pass a landscape containing none of\n // the architecture).\n let content = text;\n let livingScan = scanModel(content);\n let stmts = livingScan === null ? [] : topStatements(livingScan, bindEls);\n const rescan = (): void => {\n livingScan = scanModel(content);\n stmts = livingScan === null ? [] : topStatements(livingScan, bindEls);\n };\n const requireModel = (): ScannedModel => {\n if (livingScan === null) throw new LandscapeSpliceError(\"landscape.likec4 has no model block\");\n return livingScan;\n };\n // Built fresh at every use, never captured: `content` and `stmts` are rebound\n // by each rescan, and a region assembled before a splice describes a document\n // that no longer exists.\n const modelRegion = (): ModelRegion => ({ text: content, stmts, blocks: requireModel().blocks });\n // Every insert must be one the next scan sees (`assertSpliceVisible`).\n const applyAt = (at: number, insert: string, what: string): void => {\n const before = livingScan;\n content = content.slice(0, at) + insert + content.slice(at);\n rescan();\n assertSpliceVisible(before, livingScan, what);\n };\n const applyTop = (spot: Spot, block: string, what: string): void => {\n // A bare spot shares its line with other text (the closing brace, or a\n // statement the block displaces) — it brings its own newlines; a\n // line-start spot slots between lines.\n applyAt(spot.at, spot.bare ? `\\n${block}\\n` : `${block}\\n`, what);\n };\n\n // Placement walks the scanned statement layout, so a declaration the scan\n // cannot see is one placement would blindly splice around — LikeC4 accepts\n // two declarations on one line, but scanModel's statement head runs to the\n // end of the line, so the second rides invisibly inside the first: an\n // element bound to its service would miss its neighborhood, and a bodyless\n // parent gaining a body could wrap the wrong declaration. Refuse\n // mechanically (the parse-net discipline) instead of splicing blind.\n //\n // THAT something is unlocated is decided here, from the parse already in\n // hand; WHAT and why is `firstUnlocated`'s, at the price of a second parse on\n // this path alone. The message used to guess \"most often two declarations\n // sharing one line\" whatever the map held, and a fleet read it over a\n // declaration on a line of its own in a second `model { }` block the scan\n // did not read then (2026-10): it names LikeC4's line now, and a shared line\n // only when that line shows one.\n if (livingScan !== null) {\n const seen = new Set(livingScan.elements.map((e) => e.id));\n const blind = land.elements.some((e) => !seen.has(e.id)) || livingScan.rels.length < land.relationships.length;\n if (blind) throw new LandscapeSpliceError(unlocatedReason(\"landscape.likec4\", await firstUnlocated(text, livingScan)));\n }\n\n const livingParentOf = (parentId: string): ScannedElement | null => {\n if (livingScan === null) return null;\n const direct = livingScan.elements.find((e) => e.id === parentId);\n if (direct !== undefined) return direct;\n // The delta may spell an existing element under its own id; the title is\n // the stable cross-namespace name (the same rule the existence check uses).\n const title = deltaElements.find((e) => e.id === parentId)?.title;\n const livingId = title === undefined ? undefined : land.elements.find((e) => e.title === title)?.id;\n if (livingId === undefined) return null;\n return livingScan.elements.find((e) => e.id === livingId) ?? null;\n };\n\n // Ancestors first: a spliced parent covers its children before they are seen.\n const depth = (id: string): number => id.split(\".\").length;\n const sortedEls = [...mapEls].sort(\n (a, b) => depth(a.id) - depth(b.id) || (byId.get(a.id)?.start ?? 0) - (byId.get(b.id)?.start ?? 0),\n );\n for (const e of sortedEls) {\n const src = byId.get(e.id);\n if (src === undefined) {\n throw new LandscapeSpliceError(\n `cannot locate '${e.id}' in delta.likec4 — the landscape merge splices authored source, and this declaration was not found`,\n );\n }\n if (rides(src.start, src.end)) continue;\n // Every split block's children, whichever block they belong to:\n // `spliceSource` keeps only the ranges that fall inside the bytes it is\n // carrying, so a block riding inside ANOTHER new block still loses its own\n // interior on the way to the map.\n const omit = interiors.omit;\n const dot = e.id.lastIndexOf(\".\");\n if (dot === -1) {\n const spot = elementSpot(modelRegion(), e.id, elementService(e));\n applyTop(spot, spliceSource(deltaText, src, { featureId, indent: \" \", omit }), e.id);\n spliced.push({ start: src.start, end: src.end });\n continue;\n }\n const parentId = e.id.slice(0, dot);\n const parent = livingParentOf(parentId);\n if (parent === null) {\n throw new LandscapeSpliceError(\n `'${e.id}' nests under '${parentId}', which is neither in the living landscape nor added by this delta — there is nowhere to insert it`,\n );\n }\n const nested = nestedInsert(\n content,\n parent,\n spliceSource(deltaText, src, { featureId, indent: parent.indent + \" \", omit }),\n );\n applyAt(nested.at, nested.insert, e.id);\n spliced.push({ start: src.start, end: src.end });\n }\n\n // Each map-bound addition takes its statement out of the pool built above:\n // one statement per addition, so duplicates stay duplicates.\n for (const r of mapRels) {\n const s = pool.get(relStatementKey(r))?.shift();\n if (s === undefined) {\n throw new LandscapeSpliceError(\n `cannot locate the '${r.source} -> ${r.target}' relationship in delta.likec4 — the landscape merge splices authored source, and no matching declaration was found`,\n );\n }\n if (rides(s.start, s.end)) continue;\n const key = relSortKey(deltaElements, r);\n // Deliberately no `known` fleet set: this resolves only the anchor a new\n // relationship lands after (placement.ts's reason — cosmetic grouping,\n // safety-netted by the re-parse below), never which service a check\n // grades.\n const spot = relSpot(modelRegion(), serviceOf(deltaElements, r.source), key);\n applyTop(spot, spliceSource(deltaText, s, { featureId, indent: \" \" }), `${r.source} -> ${r.target}`);\n }\n\n // The safety net: prove the computed landscape parses before anything is\n // written. Splice bugs — and legal inputs the living document cannot absorb,\n // like a kind its specification never declares — refuse here, at plan time,\n // instead of corrupting the one file the whole fleet reads. Skipped when\n // every addition was routed away: the text is the one already parsed above,\n // and the models get their own net from the caller, which is the only side\n // that can stage a model beside the map it extends.\n // The splice composed bytes from two documents, and the delta's newlines are\n // not necessarily the map's. Corrected before the net, so what is proven is\n // what would be written.\n content = matchLineEndings(text, content);\n if (touchesMap) {\n const check = await loadSource(content);\n if (check.errors.length > 0) {\n const detail = check.errors\n .slice(0, 3)\n .map(errorText)\n .join(\"; \");\n throw new LandscapeSpliceError(\n `the merged landscape would not parse (${check.errors.length} error(s): ${detail}) — nothing was written. ` +\n `The delta's additions do not fit the living landscape as authored — most often an element kind or tag ` +\n `its specification block does not declare; fix the landscape's specification or the delta, then re-run`,\n );\n }\n }\n\n return { content: touchesMap ? content : null, addedEls: mapEls, addedRels: mapRels, models: [...routed.values()] };\n}\n"]}
@@ -0,0 +1,151 @@
1
+ import { scanModel } from "../../source-scan.js";
2
+ import { matchLineEndings, spliceSource } from "../authored-source.js";
3
+ import { assertSpliceVisible, LandscapeSpliceError } from "../contract.js";
4
+ import { relStatementKey, scannedStatementKey } from "../identity/edges.js";
5
+ import { HOME_BLOCK } from "../placement.js";
6
+ import { closeSpot, nestedInsert, spotAfter } from "../text/spot.js";
7
+ /** The merged model source. Refuses (never guesses) when the delta or the model cannot be read. */
8
+ export function spliceModel(req) {
9
+ const { additions, deltaText, featureId } = req;
10
+ const { model, borrowed } = additions;
11
+ const scan = scanModel(deltaText);
12
+ if (scan === null) {
13
+ throw new LandscapeSpliceError("delta.likec4 has no model block — nothing to splice the additions from");
14
+ }
15
+ const byId = new Map(scan.elements.map((e) => [e.id, e]));
16
+ const pool = new Map();
17
+ for (const s of scan.rels) {
18
+ const k = scannedStatementKey(s, req.deltaKindTags ?? {});
19
+ pool.set(k, [...(pool.get(k) ?? []), s]);
20
+ }
21
+ // Read with the map's kinds: the model declares none, and a `container
22
+ // outbox` frame or an `a .delivers b` edge it cannot see is a parent with
23
+ // nowhere to nest into, or an anchor the next edge lands above.
24
+ let content = withModelBlock(model.text, borrowed);
25
+ let live = read(content, model.path, borrowed);
26
+ // The delta ranges already carried over, so a child whose parent is itself
27
+ // new is recognised as riding inside the parent's text — the same rule the
28
+ // landscape merge states, and the reason `node` inside a new `cache` is never
29
+ // spliced twice.
30
+ const spliced = [];
31
+ const rides = (start, end) => spliced.some((r) => start >= r.start && end <= r.end);
32
+ // Every insert must be one the next scan sees — the landscape merge's backstop.
33
+ const applyAt = (at, insert, what) => {
34
+ const before = live;
35
+ content = content.slice(0, at) + insert + content.slice(at);
36
+ live = read(content, model.path, borrowed);
37
+ assertSpliceVisible(before, live, what);
38
+ };
39
+ // Ancestors first, exactly as the landscape merge orders them: a spliced
40
+ // parent covers its children before they are seen.
41
+ const depth = (id) => id.split(".").length;
42
+ const ordered = [...additions.els].sort((a, b) => depth(a.id) - depth(b.id) || (byId.get(a.id)?.start ?? 0) - (byId.get(b.id)?.start ?? 0));
43
+ for (const e of ordered) {
44
+ const src = byId.get(e.id);
45
+ if (src === undefined) {
46
+ throw new LandscapeSpliceError(`cannot locate '${e.id}' in delta.likec4 — the model merge splices authored source, and this declaration was not found`);
47
+ }
48
+ if (rides(src.start, src.end))
49
+ continue;
50
+ const [at, insert] = elementInsert({
51
+ content,
52
+ live,
53
+ block: (indent) => spliceSource(deltaText, src, { featureId, indent }),
54
+ parent: parentIdOf(e),
55
+ });
56
+ applyAt(at, insert, e.id);
57
+ spliced.push({ start: src.start, end: src.end });
58
+ }
59
+ for (const r of additions.rels) {
60
+ const s = pool.get(relStatementKey(r))?.shift();
61
+ if (s === undefined) {
62
+ throw new LandscapeSpliceError(`cannot locate the '${r.source} -> ${r.target}' relationship in delta.likec4 — the model merge splices authored source, and no matching declaration was found`);
63
+ }
64
+ if (rides(s.start, s.end))
65
+ continue;
66
+ const { close } = live.blocks[HOME_BLOCK];
67
+ const base = blockIndent(content, close);
68
+ // Top-level in the model block: an edge written inside an `extend` block is
69
+ // that block's, and anchoring after it would splice into someone's body.
70
+ // And in the HOME block: the anchor's own close is what `spotAfter` clamps
71
+ // to, and an edge last in a later block would otherwise pull this one there.
72
+ const top = live.rels.filter((x) => x.block === HOME_BLOCK && !live.elements.some((el) => x.start > el.start && x.start < el.end));
73
+ const anchor = top.at(-1);
74
+ const spot = anchor === undefined ? closeSpot(content, close) : spotAfter(content, close, anchor.end);
75
+ const block = spliceSource(deltaText, s, { featureId, indent: `${base} ` });
76
+ applyAt(spot.at, spot.bare ? `\n${block}\n` : `${block}\n`, `${r.source} -> ${r.target}`);
77
+ }
78
+ // The delta's newlines are not necessarily this model's, and a merge that left
79
+ // both conventions in one file is noise in every editor and every diff — the
80
+ // same correction the landscape merge makes, from the same helper
81
+ // (verification 2026-09-04, W-CRLF).
82
+ return matchLineEndings(model.text, content);
83
+ }
84
+ /** The parent an addition nests under. Routing only ever sends nested ids here. */
85
+ function parentIdOf(e) {
86
+ return e.id.slice(0, e.id.lastIndexOf("."));
87
+ }
88
+ /**
89
+ * Where one element's block goes, as `(offset, text)`.
90
+ *
91
+ * Two arms, and the second is the one that makes a freshly adopted service
92
+ * work: a model that has never named this container's parent has no `extend`
93
+ * block for it, so the merge writes one rather than refusing. A parent the
94
+ * merged project will not resolve is caught by the caller's parse net, which is
95
+ * the only reader that can see the map and the model together.
96
+ */
97
+ function elementInsert(req) {
98
+ const { content, live, block, parent } = req;
99
+ const declared = live.elements.find((x) => x.id === parent);
100
+ if (declared !== undefined) {
101
+ const nested = nestedInsert(content, declared, block(`${declared.indent} `));
102
+ return [nested.at, nested.insert];
103
+ }
104
+ const { close } = live.blocks[HOME_BLOCK];
105
+ const base = blockIndent(content, close);
106
+ const body = `${base} extend ${parent} {\n${block(`${base} `)}\n${base} }`;
107
+ const spot = closeSpot(content, close);
108
+ return [spot.at, spot.bare ? `\n${body}\n` : `${body}\n`];
109
+ }
110
+ /**
111
+ * The model, with a `model { }` block appended when the file has none.
112
+ *
113
+ * `../../service-model/shape.ts` answers `extending` for an empty file, a
114
+ * views-only file and a tags-only `specification { }` — three shapes it calls
115
+ * legal on purpose — so routing hands those models a nested addition, and
116
+ * refusing there took a whole legal shape away from `loam archive` for a
117
+ * document the merge is perfectly able to author (review of E1: before the
118
+ * routing existed, the same delta merged onto the map). It is the call
119
+ * `elementInsert` already makes one level down — a model that has never named
120
+ * the parent gains the `extend` block rather than refusing — and the caller's
121
+ * parse net proves the result either way.
122
+ */
123
+ function withModelBlock(text, borrowed) {
124
+ if (scanModel(text, borrowed) !== null)
125
+ return text;
126
+ const pad = text === "" || text.endsWith("\n") ? "" : "\n";
127
+ return `${text}${pad}model {\n}\n`;
128
+ }
129
+ /**
130
+ * The model's `model { }` block, re-scanned after every splice so each addition
131
+ * lands in the text the previous one left — the landscape merge's rule, for the
132
+ * same reason: placement composes per statement, not per archive.
133
+ *
134
+ * `withModelBlock` guarantees the FIRST read finds one, so a null here means a
135
+ * splice destroyed the block it was writing into: mechanical, so it refuses at
136
+ * plan time with nothing written, exactly as the parse nets do.
137
+ */
138
+ function read(content, path, borrowed) {
139
+ const scan = scanModel(content, borrowed);
140
+ if (scan === null) {
141
+ throw new LandscapeSpliceError(`merging this feature's additions left ${path} without a model block — nothing was written; re-run after reporting it`);
142
+ }
143
+ return scan;
144
+ }
145
+ /** The indentation of the line the model block's closing brace sits on, or "" when it shares one. */
146
+ function blockIndent(text, close) {
147
+ const lineStart = text.lastIndexOf("\n", close - 1) + 1;
148
+ const before = text.slice(lineStart, close);
149
+ return /^[ \t]*$/.test(before) ? before : "";
150
+ }
151
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../../../../src/core/c4/splice/model/merge.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The other half of the archive's C4 merge: what a feature adds INSIDE a\n * service, spliced into the service's own extending `model.likec4`.\n *\n * `../landscape-merge.ts` routes the additions (`../identity/owner.ts` states\n * the rule) and this carries them over, by the same discipline: authored source,\n * byte for byte,\n * with the feature's own tag stripped and the indentation rebased — never a\n * re-serialization of the parsed model, which keeps only the fields loam models.\n *\n * PLACEMENT IS SIMPLER HERE, and deliberately so. The map groups additions by\n * service because every service writes into it and concurrent archives must\n * merge in git; a service model has ONE service in it, so there is no\n * neighborhood to join. An element lands inside the `extend <fqn> { … }` block\n * that owns its parent — or inside its parent's own block when the model\n * already declares that container — and a model with no `extend` block for the\n * fqn gains one at the end of its `model { }` block, as a model with no `model\n * { }` block at all gains that. A relationship lands after the last top-level\n * relationship of that block, or last in it. A model written in SEVERAL\n * `model { }` blocks is read whole — a parent's `extend` frame is found in\n * whichever block holds it — and \"its block\" for everything else is\n * `HOME_BLOCK`, the first, for the reasons `../placement.ts` gives the map.\n *\n * WHAT THIS DOES NOT DO IS PROVE THE RESULT. The landscape merge parses its own\n * output because a landscape is a self-contained document; an extending model\n * is not — it is read beside the `architecture/` project, and staging that set\n * means touching the docs repo. So the parse net lives with the caller\n * (`commands/archive/plan/model/extending.ts`), which is also the side that\n * holds the merged MAP the model must be proven against.\n */\nimport type { Elem } from \"../../likec4.js\";\nimport { scanModel, type ScanKinds, type ScannedModel, type ScannedRel } from \"../../source-scan.js\";\nimport { matchLineEndings, spliceSource } from \"../authored-source.js\";\nimport { assertSpliceVisible, LandscapeSpliceError, type KindTags, type ModelAdditions } from \"../contract.js\";\nimport { relStatementKey, scannedStatementKey } from \"../identity/edges.js\";\nimport { HOME_BLOCK } from \"../placement.js\";\nimport { closeSpot, nestedInsert, spotAfter } from \"../text/spot.js\";\n\nexport interface ModelMergeRequest {\n /** One model's share of the merge, as `planLandscapeMerge` routed it. */\n additions: ModelAdditions;\n /** delta.likec4 as authored — the bytes the additions are spliced from. */\n deltaText: string;\n featureId: string;\n /** The delta's relationship kinds' tags — the landscape merge's own reason (`../identity/edges.ts`). */\n deltaKindTags?: KindTags;\n}\n\n/** The merged model source. Refuses (never guesses) when the delta or the model cannot be read. */\nexport function spliceModel(req: ModelMergeRequest): string {\n const { additions, deltaText, featureId } = req;\n const { model, borrowed } = additions;\n const scan = scanModel(deltaText);\n if (scan === null) {\n throw new LandscapeSpliceError(\"delta.likec4 has no model block — nothing to splice the additions from\");\n }\n const byId = new Map(scan.elements.map((e) => [e.id, e]));\n const pool = new Map<string, ScannedRel[]>();\n for (const s of scan.rels) {\n const k = scannedStatementKey(s, req.deltaKindTags ?? {});\n pool.set(k, [...(pool.get(k) ?? []), s]);\n }\n\n // Read with the map's kinds: the model declares none, and a `container\n // outbox` frame or an `a .delivers b` edge it cannot see is a parent with\n // nowhere to nest into, or an anchor the next edge lands above.\n let content = withModelBlock(model.text, borrowed);\n let live = read(content, model.path, borrowed);\n // The delta ranges already carried over, so a child whose parent is itself\n // new is recognised as riding inside the parent's text — the same rule the\n // landscape merge states, and the reason `node` inside a new `cache` is never\n // spliced twice.\n const spliced: Array<{ start: number; end: number }> = [];\n const rides = (start: number, end: number): boolean =>\n spliced.some((r) => start >= r.start && end <= r.end);\n // Every insert must be one the next scan sees — the landscape merge's backstop.\n const applyAt = (at: number, insert: string, what: string): void => {\n const before = live;\n content = content.slice(0, at) + insert + content.slice(at);\n live = read(content, model.path, borrowed);\n assertSpliceVisible(before, live, what);\n };\n\n // Ancestors first, exactly as the landscape merge orders them: a spliced\n // parent covers its children before they are seen.\n const depth = (id: string): number => id.split(\".\").length;\n const ordered = [...additions.els].sort(\n (a, b) => depth(a.id) - depth(b.id) || (byId.get(a.id)?.start ?? 0) - (byId.get(b.id)?.start ?? 0),\n );\n for (const e of ordered) {\n const src = byId.get(e.id);\n if (src === undefined) {\n throw new LandscapeSpliceError(\n `cannot locate '${e.id}' in delta.likec4 — the model merge splices authored source, and this declaration was not found`,\n );\n }\n if (rides(src.start, src.end)) continue;\n const [at, insert] = elementInsert({\n content,\n live,\n block: (indent) => spliceSource(deltaText, src, { featureId, indent }),\n parent: parentIdOf(e),\n });\n applyAt(at, insert, e.id);\n spliced.push({ start: src.start, end: src.end });\n }\n\n for (const r of additions.rels) {\n const s = pool.get(relStatementKey(r))?.shift();\n if (s === undefined) {\n throw new LandscapeSpliceError(\n `cannot locate the '${r.source} -> ${r.target}' relationship in delta.likec4 — the model merge splices authored source, and no matching declaration was found`,\n );\n }\n if (rides(s.start, s.end)) continue;\n const { close } = live.blocks[HOME_BLOCK]!;\n const base = blockIndent(content, close);\n // Top-level in the model block: an edge written inside an `extend` block is\n // that block's, and anchoring after it would splice into someone's body.\n // And in the HOME block: the anchor's own close is what `spotAfter` clamps\n // to, and an edge last in a later block would otherwise pull this one there.\n const top = live.rels.filter(\n (x) => x.block === HOME_BLOCK && !live.elements.some((el) => x.start > el.start && x.start < el.end),\n );\n const anchor = top.at(-1);\n const spot = anchor === undefined ? closeSpot(content, close) : spotAfter(content, close, anchor.end);\n const block = spliceSource(deltaText, s, { featureId, indent: `${base} ` });\n applyAt(spot.at, spot.bare ? `\\n${block}\\n` : `${block}\\n`, `${r.source} -> ${r.target}`);\n }\n // The delta's newlines are not necessarily this model's, and a merge that left\n // both conventions in one file is noise in every editor and every diff — the\n // same correction the landscape merge makes, from the same helper\n // (verification 2026-09-04, W-CRLF).\n return matchLineEndings(model.text, content);\n}\n\n/** The parent an addition nests under. Routing only ever sends nested ids here. */\nfunction parentIdOf(e: Elem): string {\n return e.id.slice(0, e.id.lastIndexOf(\".\"));\n}\n\ninterface ElementInsert {\n content: string;\n live: ScannedModel;\n /** The authored block at a given indent — computed late, because the indent depends on where it lands. */\n block: (indent: string) => string;\n parent: string;\n}\n\n/**\n * Where one element's block goes, as `(offset, text)`.\n *\n * Two arms, and the second is the one that makes a freshly adopted service\n * work: a model that has never named this container's parent has no `extend`\n * block for it, so the merge writes one rather than refusing. A parent the\n * merged project will not resolve is caught by the caller's parse net, which is\n * the only reader that can see the map and the model together.\n */\nfunction elementInsert(req: ElementInsert): [number, string] {\n const { content, live, block, parent } = req;\n const declared = live.elements.find((x) => x.id === parent);\n if (declared !== undefined) {\n const nested = nestedInsert(content, declared, block(`${declared.indent} `));\n return [nested.at, nested.insert];\n }\n const { close } = live.blocks[HOME_BLOCK]!;\n const base = blockIndent(content, close);\n const body = `${base} extend ${parent} {\\n${block(`${base} `)}\\n${base} }`;\n const spot = closeSpot(content, close);\n return [spot.at, spot.bare ? `\\n${body}\\n` : `${body}\\n`];\n}\n\n/**\n * The model, with a `model { }` block appended when the file has none.\n *\n * `../../service-model/shape.ts` answers `extending` for an empty file, a\n * views-only file and a tags-only `specification { }` — three shapes it calls\n * legal on purpose — so routing hands those models a nested addition, and\n * refusing there took a whole legal shape away from `loam archive` for a\n * document the merge is perfectly able to author (review of E1: before the\n * routing existed, the same delta merged onto the map). It is the call\n * `elementInsert` already makes one level down — a model that has never named\n * the parent gains the `extend` block rather than refusing — and the caller's\n * parse net proves the result either way.\n */\nfunction withModelBlock(text: string, borrowed: ScanKinds): string {\n if (scanModel(text, borrowed) !== null) return text;\n const pad = text === \"\" || text.endsWith(\"\\n\") ? \"\" : \"\\n\";\n return `${text}${pad}model {\\n}\\n`;\n}\n\n/**\n * The model's `model { }` block, re-scanned after every splice so each addition\n * lands in the text the previous one left — the landscape merge's rule, for the\n * same reason: placement composes per statement, not per archive.\n *\n * `withModelBlock` guarantees the FIRST read finds one, so a null here means a\n * splice destroyed the block it was writing into: mechanical, so it refuses at\n * plan time with nothing written, exactly as the parse nets do.\n */\nfunction read(content: string, path: string, borrowed: ScanKinds): ScannedModel {\n const scan = scanModel(content, borrowed);\n if (scan === null) {\n throw new LandscapeSpliceError(\n `merging this feature's additions left ${path} without a model block — nothing was written; re-run after reporting it`,\n );\n }\n return scan;\n}\n\n/** The indentation of the line the model block's closing brace sits on, or \"\" when it shares one. */\nfunction blockIndent(text: string, close: number): string {\n const lineStart = text.lastIndexOf(\"\\n\", close - 1) + 1;\n const before = text.slice(lineStart, close);\n return /^[ \\t]*$/.test(before) ? before : \"\";\n}\n"]}
@@ -1,9 +1,89 @@
1
1
  import {} from "../likec4.js";
2
2
  import { elementService, serviceOf } from "../resolve/service.js";
3
3
  import { relSortKey } from "./identity/edges.js";
4
+ import { aboveComments, closeSpot, lineStartAt, spotAfter } from "./text/spot.js";
5
+ /* ------------------------------------------------------------------ */
6
+ /* Landscape placement — where a top-level addition lands */
7
+ /* ------------------------------------------------------------------ */
8
+ /**
9
+ * The placement scheme, in full. It never moves an authored byte — placement
10
+ * only chooses where NEW spliced blocks go — and it is deterministic in a
11
+ * stronger sense: archiving feature A then feature B (touching different
12
+ * services) yields the SAME final bytes as B then A, which is what lets two
13
+ * concurrent archive PRs merge in git instead of colliding on one shared
14
+ * append point.
15
+ *
16
+ * - An ELEMENT whose service already has top-level elements in the model
17
+ * (the elementService join — binding first, title as the fallback) lands
18
+ * immediately after the last of them: it joins its service's neighborhood.
19
+ * Two features touching the SAME service therefore land adjacently, and
20
+ * their concurrent PRs still conflict — expected, and documented
21
+ * (SCHEMA.md sends that conflict to the PR flow).
22
+ * - An element opening a NEW service lands in the trailing region before the
23
+ * model's closing brace: skip the trailing relationship run, then walk left
24
+ * per same-service RUN, past every run whose leading id is
25
+ * lexicographically greater — an insertion sort of neighborhood heads
26
+ * against whatever is already there, which is what makes the region's
27
+ * final order independent of archive order (see the note on elementSpot:
28
+ * per-statement comparison was order-dependent).
29
+ * - A RELATIONSHIP lands after the last top-level relationship touching its
30
+ * SOURCE's service (either endpoint counts), then past the anchor's own
31
+ * CLUSTER members with a smaller sort key — two edges anchored to the same
32
+ * statement must order by key, not by which archived first. With no such
33
+ * neighborhood it falls to the trailing region, cluster-head-key-sorted
34
+ * the same insertion-sort way, after the trailing elements.
35
+ * - The relationship walk sorts only within the region's ASCENDING TAIL — the
36
+ * run loam's own insertions keep sorted — and stops where the existing order
37
+ * descends (`relSpot` has the case and the order-independence argument). A
38
+ * hand-written region is sorted by nobody, so walking into it made the spot
39
+ * depend on how unrelated edges happened to be drawn. The element walk is
40
+ * left unbounded: the map's top-level elements are few, a new service among
41
+ * them misfiles nothing, and its bytes are pinned as they always were.
42
+ * - A walk that stops BEFORE a statement, or at the closing brace, lands above
43
+ * the comment written directly over it (`aboveComments` in `./text/spot.ts`):
44
+ * a comment is about what follows it, and an addition between the two
45
+ * misfiles under it.
46
+ *
47
+ * A landscape may hold SEVERAL top-level `model { }` blocks, and LikeC4 reads
48
+ * them as one model. Placement keeps every rule above and adds one: an
49
+ * ANCHORED addition lands in its anchor's block (after the neighbor, clamped
50
+ * to that block's closing brace), and an UNANCHORED one — the trailing-region
51
+ * walks — lands in `HOME_BLOCK`, never crossing a block boundary. A same-service
52
+ * run and a relationship cluster are contiguous statements of ONE block: the
53
+ * views or the specification between two blocks are not a neighborhood.
54
+ *
55
+ * LikeC4 reference resolution is not order-dependent, so a relationship
56
+ * placed before an element it names still parses; the in-memory parse net in
57
+ * landscape-merge.ts's planLandscapeMerge stays as the backstop regardless.
58
+ */
59
+ /**
60
+ * The block an addition with no anchor lands in: the document's FIRST
61
+ * `model { }` block.
62
+ *
63
+ * First, because it is the block every unanchored addition already landed in
64
+ * before the scan could see a second one — the scan stopped at the first
65
+ * match — so a single-block map places byte-identically, and a map that grew
66
+ * a second block keeps receiving new services where its older ones went. It
67
+ * is also invariant under every addition this merge can make (an archive never
68
+ * creates or reorders a block), which is what order-independence needs of it:
69
+ * a block chosen by size or content would move as the archives landed, and the
70
+ * same two features would compose to different bytes by archive order. The
71
+ * service-model splice (`./model/merge.ts`) uses the same block for the same
72
+ * reasons.
73
+ */
74
+ export const HOME_BLOCK = 0;
75
+ /** The statements of one block, in document order — what a trailing walk may step over. */
76
+ function inBlock(stmts, block) {
77
+ return stmts.filter((s) => s.block === block);
78
+ }
4
79
  /** The model's top-level statements in document order, joined to the parsed elements for services. */
5
80
  export function topStatements(scan, els) {
6
- const topEls = scan.elements.filter((e) => !e.id.includes("."));
81
+ // An `extend <fqn>` frame is never a top-level declaration of THIS document —
82
+ // it reopens one another document owns — so it anchors nothing and displaces
83
+ // nothing. Undotted fqns are the reason the tag is checked rather than the
84
+ // dot: `extend paymentService { }` would otherwise read as a declaration of
85
+ // `paymentService` here.
86
+ const topEls = scan.elements.filter((e) => e.extend !== true && !e.id.includes("."));
7
87
  const bound = new Map(els.map((e) => [e.id, elementService(e)]));
8
88
  const stmts = topEls.map((e) => ({
9
89
  kind: "element",
@@ -12,11 +92,20 @@ export function topStatements(scan, els) {
12
92
  services: [bound.get(e.id) ?? e.id],
13
93
  start: e.start,
14
94
  end: e.end,
95
+ block: e.block,
15
96
  }));
97
+ // Every top-level FRAME a statement can sit inside: the elements, and the
98
+ // `extend` frames, which hold edges as well as children.
99
+ const frames = scan.elements.filter((e) => e.extend === true || !e.id.includes("."));
16
100
  for (const r of scan.rels) {
17
101
  // A rel declared inside an element's body is not a top-level statement —
18
- // anchoring after it would splice into the parent's block.
19
- if (topEls.some((e) => r.start > e.start && r.start < e.end))
102
+ // anchoring after it would splice into the parent's block. Inside an
103
+ // `extend` frame it is worse than misplaced: the frame is a SCOPE, so an
104
+ // edge spliced in after it re-resolves there, and the delta's `zulu ->
105
+ // beta` landed inside `extend alpha { beta = … }` as an edge into
106
+ // `alpha.beta` — a merge that parses, written at exit 0 (probed
107
+ // 2026-10-20). Only the extend frames' edges are new to this filter.
108
+ if (frames.some((e) => r.start > e.start && r.start < e.end))
20
109
  continue;
21
110
  stmts.push({
22
111
  kind: "rel",
@@ -30,6 +119,7 @@ export function topStatements(scan, els) {
30
119
  services: [serviceOf(els, r.source), serviceOf(els, r.target)],
31
120
  start: r.start,
32
121
  end: r.end,
122
+ block: r.block,
33
123
  });
34
124
  }
35
125
  return stmts.sort((a, b) => a.start - b.start);
@@ -49,14 +139,16 @@ export function topStatements(scan, els) {
49
139
  * exact regime the scheme guarantees.
50
140
  */
51
141
  export function elementSpot(region, id, service) {
52
- const { text, stmts, close } = region;
142
+ const { text, blocks } = region;
53
143
  let anchor;
54
- for (const s of stmts) {
144
+ for (const s of region.stmts) {
55
145
  if (s.kind === "element" && s.services.includes(service))
56
146
  anchor = s;
57
147
  }
58
148
  if (anchor !== undefined)
59
- return spotAfter(text, close, anchor.end);
149
+ return spotAfter(text, blocks[anchor.block].close, anchor.end);
150
+ const stmts = inBlock(region.stmts, HOME_BLOCK);
151
+ const close = blocks[HOME_BLOCK].close;
60
152
  let i = stmts.length - 1;
61
153
  let before;
62
154
  while (i >= 0 && stmts[i].kind === "rel") {
@@ -94,6 +186,12 @@ function relClusterHeads(stmts) {
94
186
  let services = null;
95
187
  for (let i = 0; i < stmts.length; i += 1) {
96
188
  const s = stmts[i];
189
+ // A block boundary ends a cluster exactly as an element does: the first
190
+ // edge of the next block is not contiguous with the last of this one.
191
+ if (i > 0 && stmts[i - 1].block !== s.block) {
192
+ head = -1;
193
+ services = null;
194
+ }
97
195
  if (s.kind !== "rel") {
98
196
  head = -1;
99
197
  services = null;
@@ -111,8 +209,49 @@ function relClusterHeads(stmts) {
111
209
  }
112
210
  return heads;
113
211
  }
212
+ /**
213
+ * Where a relationship lands: after its source's neighborhood, or — with none —
214
+ * in the trailing region, insertion-sorted among the cluster heads.
215
+ *
216
+ * The trailing walk sorts only within the region's ASCENDING TAIL: it steps left
217
+ * past a cluster whose head sorts above the new key only while that head also
218
+ * sorts at or below the head of the cluster after it. The insertions loam makes
219
+ * keep that tail sorted, so on a region loam wrote the walk is the plain
220
+ * insertion sort it always was; a hand-written region is sorted by nobody, and
221
+ * walking into it made the landing spot a function of unrelated edges — an edge
222
+ * drawn `svc -> kafka` let a new edge walk past it, the same edge turned round
223
+ * (`kafka -[delivers]-> svc`, a head that sorts lower) stopped the walk, and the
224
+ * addition landed sixty lines away under a comment about something else
225
+ * (2026-10). Order-independence survives the bound: the statements before the
226
+ * tail never change, because an addition sorting below the tail's first head
227
+ * becomes its new first head, and that still sorts below the statement the tail
228
+ * broke from — so every archive inserts into the same sorted run, whatever
229
+ * order they land in.
230
+ */
114
231
  export function relSpot(region, sourceService, key) {
115
- const { text, stmts, close } = region;
232
+ const anchored = anchoredRelSpot(region, sourceService, key);
233
+ if (anchored !== null)
234
+ return anchored;
235
+ const { text, blocks } = region;
236
+ const stmts = inBlock(region.stmts, HOME_BLOCK);
237
+ const close = blocks[HOME_BLOCK].close;
238
+ const heads = relClusterHeads(stmts);
239
+ let i = stmts.length - 1;
240
+ let before;
241
+ while (i >= 0 && stmts[i].kind === "rel") {
242
+ const j = heads[i];
243
+ if (!(stmts[j].key > key))
244
+ break;
245
+ if (before !== undefined && stmts[j].key > before.key)
246
+ break;
247
+ before = stmts[j];
248
+ i = j - 1;
249
+ }
250
+ return before !== undefined ? beforeSpot(text, before) : closeSpot(text, close);
251
+ }
252
+ /** After the last relationship touching the source's service, in that relationship's block — null when none does. */
253
+ function anchoredRelSpot(region, sourceService, key) {
254
+ const { text, stmts, blocks } = region;
116
255
  const heads = relClusterHeads(stmts);
117
256
  let anchorAt = -1;
118
257
  for (let i = 0; i < stmts.length; i += 1) {
@@ -133,62 +272,27 @@ export function relSpot(region, sourceService, key) {
133
272
  break;
134
273
  last = s;
135
274
  }
136
- return spotAfter(text, close, last.end);
137
- }
138
- let i = stmts.length - 1;
139
- let before;
140
- while (i >= 0 && stmts[i].kind === "rel") {
141
- const j = heads[i];
142
- if (!(stmts[j].key > key))
143
- break;
144
- before = stmts[j];
145
- i = j - 1;
275
+ return spotAfter(text, blocks[last.block].close, last.end);
146
276
  }
147
- return before !== undefined ? beforeSpot(text, before) : closeSpot(text, close);
277
+ return null;
148
278
  }
149
279
  /**
150
- * Insertion before an existing statement: at the start of its line when only
151
- * whitespace precedes it there, at the statement itself — bare, displacing it
152
- * onto a fresh line — when other text shares the line (a statement written on
153
- * the `model {` line, say). The unguarded line start spliced the block BEFORE
154
- * the model keyword, and the parse net refused a perfectly legal landscape.
280
+ * Insertion before an existing statement: above the comment written directly
281
+ * over it when only whitespace precedes it on its line, at the statement itself
282
+ * — bare, displacing it onto a fresh line — when other text shares the line (a
283
+ * statement written on the `model {` line, say). The unguarded line start
284
+ * spliced the block BEFORE the model keyword, and the parse net refused a
285
+ * perfectly legal landscape.
286
+ *
287
+ * Above the comment, because a comment written over a statement is about that
288
+ * statement, or heads the section it opens: inserted at the statement's own
289
+ * line, an addition landed between a six-line explanation and the edge it
290
+ * explains (2026-10). `aboveComments` says which lines count.
155
291
  */
156
292
  function beforeSpot(text, before) {
157
293
  const ls = lineStartAt(text, before.start);
158
294
  if (/^[ \t]*$/.test(text.slice(ls, before.start)))
159
- return { at: ls, bare: false };
295
+ return { at: aboveComments(text, ls), bare: false };
160
296
  return { at: before.start, bare: true };
161
297
  }
162
- /** The line following the statement that ends at `end` — clamped to the closing brace's own spot. */
163
- function spotAfter(text, close, end) {
164
- const nl = text.indexOf("\n", end);
165
- const at = nl === -1 ? text.length : nl + 1;
166
- return at > close ? closeSpot(text, close) : { at, bare: false };
167
- }
168
- /** The last resort: directly before the model's closing brace. */
169
- function closeSpot(text, close) {
170
- const ls = lineStartAt(text, close);
171
- if (/^[ \t]*$/.test(text.slice(ls, close)))
172
- return { at: ls, bare: false };
173
- return { at: close, bare: true };
174
- }
175
- function lineStartAt(text, at) {
176
- return text.lastIndexOf("\n", at - 1) + 1;
177
- }
178
- /**
179
- * Where a child block enters an existing living parent: before the closing
180
- * brace of the parent's body, on its own line at the parent's inner indent —
181
- * and a parent that never had a body gains one around the child.
182
- */
183
- export function nestedInsert(text, parent, block) {
184
- if (parent.bodyOpen === -1) {
185
- return { at: parent.end, insert: ` {\n${block}\n${parent.indent}}` };
186
- }
187
- const lineStart = text.lastIndexOf("\n", parent.bodyClose - 1) + 1;
188
- if (/^[ \t]*$/.test(text.slice(lineStart, parent.bodyClose))) {
189
- return { at: lineStart, insert: `${block}\n` };
190
- }
191
- // `{ ... }` on one line — break the brace onto its own line to make room.
192
- return { at: parent.bodyClose, insert: `\n${block}\n${parent.indent}` };
193
- }
194
298
  //# sourceMappingURL=placement.js.map